blob: fa6b8af4791ee5245dacda19d5678991eb1442cc [file] [log] [blame]
Wenzel Jakob0d3fc352016-07-08 10:52:10 +02001/*
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
Wenzel Jakobdc13cf02016-07-08 11:07:02 +020014#include "pybind11.h"
Wenzel Jakob0d3fc352016-07-08 10:52:10 +020015
Yannick Jadoulf980d762020-07-09 00:14:41 +020016PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
Yannick Jadoul3a37d332020-10-27 19:58:27 +010017PYBIND11_NAMESPACE_BEGIN(detail)
18
19inline 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
32PYBIND11_NAMESPACE_END(detail)
Wenzel Jakob0d3fc352016-07-08 10:52:10 +020033
34enum 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
45template <eval_mode mode = eval_expr>
Dean Moldovan1d3c4bc2017-06-06 17:05:19 +020046object eval(str expr, object global = globals(), object local = object()) {
Wenzel Jakob0d3fc352016-07-08 10:52:10 +020047 if (!local)
48 local = global;
49
Yannick Jadoul3a37d332020-10-27 19:58:27 +010050 detail::ensure_builtins_in_globals(global);
51
Wenzel Jakob464c4352016-07-08 15:06:25 +020052 /* 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
Wenzel Jakob0d3fc352016-07-08 10:52:10 +020056 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
Dean Moldovanc7ac16b2016-10-28 03:08:15 +020064 PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());
Wenzel Jakob0d3fc352016-07-08 10:52:10 +020065 if (!result)
66 throw error_already_set();
Dean Moldovanc7ac16b2016-10-28 03:08:15 +020067 return reinterpret_steal<object>(result);
Wenzel Jakob0d3fc352016-07-08 10:52:10 +020068}
69
Dean Moldovan194d8b92017-03-29 00:27:56 +020070template <eval_mode mode = eval_expr, size_t N>
Dean Moldovan1d3c4bc2017-06-06 17:05:19 +020071object eval(const char (&s)[N], object global = globals(), object local = object()) {
Dean Moldovan194d8b92017-03-29 00:27:56 +020072 /* Support raw string literals by removing common leading whitespace */
Henry Schreiner6bcd2202020-10-03 13:38:03 -040073 auto expr = (s[0] == '\n') ? str(module_::import("textwrap").attr("dedent")(s))
Dean Moldovan194d8b92017-03-29 00:27:56 +020074 : str(s);
75 return eval<mode>(expr, global, local);
76}
77
Dean Moldovan1d3c4bc2017-06-06 17:05:19 +020078inline void exec(str expr, object global = globals(), object local = object()) {
Dean Moldovan076c7382017-04-30 01:53:06 +020079 eval<eval_statements>(expr, global, local);
80}
81
82template <size_t N>
Dean Moldovan1d3c4bc2017-06-06 17:05:19 +020083void exec(const char (&s)[N], object global = globals(), object local = object()) {
Dean Moldovan076c7382017-04-30 01:53:06 +020084 eval<eval_statements>(s, global, local);
85}
86
Yannick Jadoul14112072020-10-05 16:43:27 +020087#if defined(PYPY_VERSION) && PY_VERSION_HEX >= 0x03000000
Isuru Fernando0d70f0e2020-07-07 08:58:16 -050088template <eval_mode mode = eval_statements>
89object eval_file(str, object, object) {
90 pybind11_fail("eval_file not supported in PyPy3. Use eval");
91}
92template <eval_mode mode = eval_statements>
93object eval_file(str, object) {
94 pybind11_fail("eval_file not supported in PyPy3. Use eval");
95}
96template <eval_mode mode = eval_statements>
97object eval_file(str) {
98 pybind11_fail("eval_file not supported in PyPy3. Use eval");
99}
100#else
Wenzel Jakob0d3fc352016-07-08 10:52:10 +0200101template <eval_mode mode = eval_statements>
Dean Moldovan1d3c4bc2017-06-06 17:05:19 +0200102object eval_file(str fname, object global = globals(), object local = object()) {
Wenzel Jakob0d3fc352016-07-08 10:52:10 +0200103 if (!local)
104 local = global;
105
Yannick Jadoul3a37d332020-10-27 19:58:27 +0100106 detail::ensure_builtins_in_globals(global);
107
Wenzel Jakob0d3fc352016-07-08 10:52:10 +0200108 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
Wenzel Jakob464c4352016-07-08 15:06:25 +0200116 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() :( */
Dean Moldovanc7ac16b2016-10-28 03:08:15 +0200124 auto fobj = reinterpret_steal<object>(PyFile_FromString(
Wenzel Jakob678d59d2016-07-08 15:14:48 +0200125 const_cast<char *>(fname_str.c_str()),
Dean Moldovanc7ac16b2016-10-28 03:08:15 +0200126 const_cast<char*>("r")));
Wenzel Jakob464c4352016-07-08 15:06:25 +0200127 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 }
Wenzel Jakob0d3fc352016-07-08 10:52:10 +0200136
Wenzel Jakob1d1f81b2016-12-16 15:00:46 +0100137#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
Dean Moldovanc7ac16b2016-10-28 03:08:15 +0200142 PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(),
143 local.ptr(), closeFile);
Wenzel Jakob1d1f81b2016-12-16 15:00:46 +0100144#endif
145
Wenzel Jakob0d3fc352016-07-08 10:52:10 +0200146 if (!result)
147 throw error_already_set();
Dean Moldovanc7ac16b2016-10-28 03:08:15 +0200148 return reinterpret_steal<object>(result);
Wenzel Jakob0d3fc352016-07-08 10:52:10 +0200149}
Isuru Fernando0d70f0e2020-07-07 08:58:16 -0500150#endif
Wenzel Jakob0d3fc352016-07-08 10:52:10 +0200151
Yannick Jadoulf980d762020-07-09 00:14:41 +0200152PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)