1 /*
2 pybind11/exec.h: Support for evaluating Python expressions and statements
3 from strings and files
5 Copyright (c) 2016 Klemens Morgenstern <klemens.morgenstern@ed-chemnitz.de> and
6 Wenzel Jakob <wenzel.jakob@epfl.ch>
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 */
12 #pragma once
14 #include "pybind11.h"
16 NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
18 enum eval_mode {
19 /// Evaluate a string containing an isolated expression
20 eval_expr,
22 /// Evaluate a string containing a single statement. Returns \c none
23 eval_single_statement,
25 /// Evaluate a string containing a sequence of statement. Returns \c none
26 eval_statements
27 };
29 template <eval_mode mode = eval_expr>
30 object eval(str expr, object global = globals(), object local = object()) {
31 if (!local)
32 local = global;
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;
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 }
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 }
52 template <eval_mode mode = eval_expr, size_t N>
53 object 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 }
60 inline void exec(str expr, object global = globals(), object local = object()) {
61 eval<eval_statements>(expr, global, local);
62 }
64 template <size_t N>
65 void exec(const char (&s)[N], object global = globals(), object local = object()) {
66 eval<eval_statements>(s, global, local);
67 }
69 template <eval_mode mode = eval_statements>
70 object eval_file(str fname, object global = globals(), object local = object()) {
71 if (!local)
72 local = global;
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 }
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 }
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
112 if (!result)
113 throw error_already_set();
114 return reinterpret_steal<object>(result);
115 }
117 NAMESPACE_END(PYBIND11_NAMESPACE)