eval.h revision 12391:ceeca8b41e4b
1/*
2    pybind11/exec.h: Support for evaluating Python expressions and statements
3    from strings and files
4
5    Copyright (c) 2016 Klemens Morgenstern <klemens.morgenstern@ed-chemnitz.de> and
6                       Wenzel Jakob <wenzel.jakob@epfl.ch>
7
8    All rights reserved. Use of this source code is governed by a
9    BSD-style license that can be found in the LICENSE file.
10*/
11
12#pragma once
13
14#include "pybind11.h"
15
16NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
17
18enum eval_mode {
19    /// Evaluate a string containing an isolated expression
20    eval_expr,
21
22    /// Evaluate a string containing a single statement. Returns \c none
23    eval_single_statement,
24
25    /// Evaluate a string containing a sequence of statement. Returns \c none
26    eval_statements
27};
28
29template <eval_mode mode = eval_expr>
30object eval(str expr, object global = globals(), object local = object()) {
31    if (!local)
32        local = global;
33
34    /* PyRun_String does not accept a PyObject / encoding specifier,
35       this seems to be the only alternative */
36    std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr;
37
38    int start;
39    switch (mode) {
40        case eval_expr:             start = Py_eval_input;   break;
41        case eval_single_statement: start = Py_single_input; break;
42        case eval_statements:       start = Py_file_input;   break;
43        default: pybind11_fail("invalid evaluation mode");
44    }
45
46    PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());
47    if (!result)
48        throw error_already_set();
49    return reinterpret_steal<object>(result);
50}
51
52template <eval_mode mode = eval_expr, size_t N>
53object eval(const char (&s)[N], object global = globals(), object local = object()) {
54    /* Support raw string literals by removing common leading whitespace */
55    auto expr = (s[0] == '\n') ? str(module::import("textwrap").attr("dedent")(s))
56                               : str(s);
57    return eval<mode>(expr, global, local);
58}
59
60inline void exec(str expr, object global = globals(), object local = object()) {
61    eval<eval_statements>(expr, global, local);
62}
63
64template <size_t N>
65void exec(const char (&s)[N], object global = globals(), object local = object()) {
66    eval<eval_statements>(s, global, local);
67}
68
69template <eval_mode mode = eval_statements>
70object eval_file(str fname, object global = globals(), object local = object()) {
71    if (!local)
72        local = global;
73
74    int start;
75    switch (mode) {
76        case eval_expr:             start = Py_eval_input;   break;
77        case eval_single_statement: start = Py_single_input; break;
78        case eval_statements:       start = Py_file_input;   break;
79        default: pybind11_fail("invalid evaluation mode");
80    }
81
82    int closeFile = 1;
83    std::string fname_str = (std::string) fname;
84#if PY_VERSION_HEX >= 0x03040000
85    FILE *f = _Py_fopen_obj(fname.ptr(), "r");
86#elif PY_VERSION_HEX >= 0x03000000
87    FILE *f = _Py_fopen(fname.ptr(), "r");
88#else
89    /* No unicode support in open() :( */
90    auto fobj = reinterpret_steal<object>(PyFile_FromString(
91        const_cast<char *>(fname_str.c_str()),
92        const_cast<char*>("r")));
93    FILE *f = nullptr;
94    if (fobj)
95        f = PyFile_AsFile(fobj.ptr());
96    closeFile = 0;
97#endif
98    if (!f) {
99        PyErr_Clear();
100        pybind11_fail("File \"" + fname_str + "\" could not be opened!");
101    }
102
103#if PY_VERSION_HEX < 0x03000000 && defined(PYPY_VERSION)
104    PyObject *result = PyRun_File(f, fname_str.c_str(), start, global.ptr(),
105                                  local.ptr());
106    (void) closeFile;
107#else
108    PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(),
109                                    local.ptr(), closeFile);
110#endif
111
112    if (!result)
113        throw error_already_set();
114    return reinterpret_steal<object>(result);
115}
116
117NAMESPACE_END(PYBIND11_NAMESPACE)
118