• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)17 PYBIND11_NAMESPACE_BEGIN(detail)
18 
19 inline void ensure_builtins_in_globals(object &global) {
20     #if PY_VERSION_HEX < 0x03080000
21         // Running exec and eval on Python 2 and 3 adds `builtins` module under
22         // `__builtins__` key to globals if not yet present.
23         // Python 3.8 made PyRun_String behave similarly. Let's also do that for
24         // older versions, for consistency.
25         if (!global.contains("__builtins__"))
26             global["__builtins__"] = module_::import(PYBIND11_BUILTINS_MODULE);
27     #else
28         (void) global;
29     #endif
30 }
31 
32 PYBIND11_NAMESPACE_END(detail)
33 
34 enum eval_mode {
35     /// Evaluate a string containing an isolated expression
36     eval_expr,
37 
38     /// Evaluate a string containing a single statement. Returns \c none
39     eval_single_statement,
40 
41     /// Evaluate a string containing a sequence of statement. Returns \c none
42     eval_statements
43 };
44 
45 template <eval_mode mode = eval_expr>
46 object eval(str expr, object global = globals(), object local = object()) {
47     if (!local)
48         local = global;
49 
50     detail::ensure_builtins_in_globals(global);
51 
52     /* PyRun_String does not accept a PyObject / encoding specifier,
53        this seems to be the only alternative */
54     std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr;
55 
56     int start;
57     switch (mode) {
58         case eval_expr:             start = Py_eval_input;   break;
59         case eval_single_statement: start = Py_single_input; break;
60         case eval_statements:       start = Py_file_input;   break;
61         default: pybind11_fail("invalid evaluation mode");
62     }
63 
64     PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());
65     if (!result)
66         throw error_already_set();
67     return reinterpret_steal<object>(result);
68 }
69 
70 template <eval_mode mode = eval_expr, size_t N>
71 object eval(const char (&s)[N], object global = globals(), object local = object()) {
72     /* Support raw string literals by removing common leading whitespace */
73     auto expr = (s[0] == '\n') ? str(module_::import("textwrap").attr("dedent")(s))
74                                : str(s);
75     return eval<mode>(expr, global, local);
76 }
77 
78 inline void exec(str expr, object global = globals(), object local = object()) {
79     eval<eval_statements>(expr, global, local);
80 }
81 
82 template <size_t N>
83 void exec(const char (&s)[N], object global = globals(), object local = object()) {
84     eval<eval_statements>(s, global, local);
85 }
86 
87 #if defined(PYPY_VERSION) && PY_VERSION_HEX >= 0x03000000
88 template <eval_mode mode = eval_statements>
eval_file(str,object,object)89 object eval_file(str, object, object) {
90     pybind11_fail("eval_file not supported in PyPy3. Use eval");
91 }
92 template <eval_mode mode = eval_statements>
eval_file(str,object)93 object eval_file(str, object) {
94     pybind11_fail("eval_file not supported in PyPy3. Use eval");
95 }
96 template <eval_mode mode = eval_statements>
eval_file(str)97 object eval_file(str) {
98     pybind11_fail("eval_file not supported in PyPy3. Use eval");
99 }
100 #else
101 template <eval_mode mode = eval_statements>
102 object eval_file(str fname, object global = globals(), object local = object()) {
103     if (!local)
104         local = global;
105 
106     detail::ensure_builtins_in_globals(global);
107 
108     int start;
109     switch (mode) {
110         case eval_expr:             start = Py_eval_input;   break;
111         case eval_single_statement: start = Py_single_input; break;
112         case eval_statements:       start = Py_file_input;   break;
113         default: pybind11_fail("invalid evaluation mode");
114     }
115 
116     int closeFile = 1;
117     std::string fname_str = (std::string) fname;
118 #if PY_VERSION_HEX >= 0x03040000
119     FILE *f = _Py_fopen_obj(fname.ptr(), "r");
120 #elif PY_VERSION_HEX >= 0x03000000
121     FILE *f = _Py_fopen(fname.ptr(), "r");
122 #else
123     /* No unicode support in open() :( */
124     auto fobj = reinterpret_steal<object>(PyFile_FromString(
125         const_cast<char *>(fname_str.c_str()),
126         const_cast<char*>("r")));
127     FILE *f = nullptr;
128     if (fobj)
129         f = PyFile_AsFile(fobj.ptr());
130     closeFile = 0;
131 #endif
132     if (!f) {
133         PyErr_Clear();
134         pybind11_fail("File \"" + fname_str + "\" could not be opened!");
135     }
136 
137 #if PY_VERSION_HEX < 0x03000000 && defined(PYPY_VERSION)
138     PyObject *result = PyRun_File(f, fname_str.c_str(), start, global.ptr(),
139                                   local.ptr());
140     (void) closeFile;
141 #else
142     PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(),
143                                     local.ptr(), closeFile);
144 #endif
145 
146     if (!result)
147         throw error_already_set();
148     return reinterpret_steal<object>(result);
149 }
150 #endif
151 
152 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
153