blob: ba82cf42ae3673a3de391eb55777ef413c43dc33 [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)
Wenzel Jakob0d3fc352016-07-08 10:52:10 +020017
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>
Dean Moldovan1d3c4bc2017-06-06 17:05:19 +020030object eval(str expr, object global = globals(), object local = object()) {
Wenzel Jakob0d3fc352016-07-08 10:52:10 +020031 if (!local)
32 local = global;
33
Wenzel Jakob464c4352016-07-08 15:06:25 +020034 /* 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
Wenzel Jakob0d3fc352016-07-08 10:52:10 +020038 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
Dean Moldovanc7ac16b2016-10-28 03:08:15 +020046 PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());
Wenzel Jakob0d3fc352016-07-08 10:52:10 +020047 if (!result)
48 throw error_already_set();
Dean Moldovanc7ac16b2016-10-28 03:08:15 +020049 return reinterpret_steal<object>(result);
Wenzel Jakob0d3fc352016-07-08 10:52:10 +020050}
51
Dean Moldovan194d8b92017-03-29 00:27:56 +020052template <eval_mode mode = eval_expr, size_t N>
Dean Moldovan1d3c4bc2017-06-06 17:05:19 +020053object eval(const char (&s)[N], object global = globals(), object local = object()) {
Dean Moldovan194d8b92017-03-29 00:27:56 +020054 /* 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
Dean Moldovan1d3c4bc2017-06-06 17:05:19 +020060inline void exec(str expr, object global = globals(), object local = object()) {
Dean Moldovan076c7382017-04-30 01:53:06 +020061 eval<eval_statements>(expr, global, local);
62}
63
64template <size_t N>
Dean Moldovan1d3c4bc2017-06-06 17:05:19 +020065void exec(const char (&s)[N], object global = globals(), object local = object()) {
Dean Moldovan076c7382017-04-30 01:53:06 +020066 eval<eval_statements>(s, global, local);
67}
68
Isuru Fernando0d70f0e2020-07-07 08:58:16 -050069#if defined(PYPY_VERSION) && PY_VERSION_HEX >= 0x3000000
70template <eval_mode mode = eval_statements>
71object eval_file(str, object, object) {
72 pybind11_fail("eval_file not supported in PyPy3. Use eval");
73}
74template <eval_mode mode = eval_statements>
75object eval_file(str, object) {
76 pybind11_fail("eval_file not supported in PyPy3. Use eval");
77}
78template <eval_mode mode = eval_statements>
79object eval_file(str) {
80 pybind11_fail("eval_file not supported in PyPy3. Use eval");
81}
82#else
Wenzel Jakob0d3fc352016-07-08 10:52:10 +020083template <eval_mode mode = eval_statements>
Dean Moldovan1d3c4bc2017-06-06 17:05:19 +020084object eval_file(str fname, object global = globals(), object local = object()) {
Wenzel Jakob0d3fc352016-07-08 10:52:10 +020085 if (!local)
86 local = global;
87
88 int start;
89 switch (mode) {
90 case eval_expr: start = Py_eval_input; break;
91 case eval_single_statement: start = Py_single_input; break;
92 case eval_statements: start = Py_file_input; break;
93 default: pybind11_fail("invalid evaluation mode");
94 }
95
Wenzel Jakob464c4352016-07-08 15:06:25 +020096 int closeFile = 1;
97 std::string fname_str = (std::string) fname;
98#if PY_VERSION_HEX >= 0x03040000
99 FILE *f = _Py_fopen_obj(fname.ptr(), "r");
100#elif PY_VERSION_HEX >= 0x03000000
101 FILE *f = _Py_fopen(fname.ptr(), "r");
102#else
103 /* No unicode support in open() :( */
Dean Moldovanc7ac16b2016-10-28 03:08:15 +0200104 auto fobj = reinterpret_steal<object>(PyFile_FromString(
Wenzel Jakob678d59d2016-07-08 15:14:48 +0200105 const_cast<char *>(fname_str.c_str()),
Dean Moldovanc7ac16b2016-10-28 03:08:15 +0200106 const_cast<char*>("r")));
Wenzel Jakob464c4352016-07-08 15:06:25 +0200107 FILE *f = nullptr;
108 if (fobj)
109 f = PyFile_AsFile(fobj.ptr());
110 closeFile = 0;
111#endif
112 if (!f) {
113 PyErr_Clear();
114 pybind11_fail("File \"" + fname_str + "\" could not be opened!");
115 }
Wenzel Jakob0d3fc352016-07-08 10:52:10 +0200116
Wenzel Jakob1d1f81b2016-12-16 15:00:46 +0100117#if PY_VERSION_HEX < 0x03000000 && defined(PYPY_VERSION)
118 PyObject *result = PyRun_File(f, fname_str.c_str(), start, global.ptr(),
119 local.ptr());
120 (void) closeFile;
121#else
Dean Moldovanc7ac16b2016-10-28 03:08:15 +0200122 PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(),
123 local.ptr(), closeFile);
Wenzel Jakob1d1f81b2016-12-16 15:00:46 +0100124#endif
125
Wenzel Jakob0d3fc352016-07-08 10:52:10 +0200126 if (!result)
127 throw error_already_set();
Dean Moldovanc7ac16b2016-10-28 03:08:15 +0200128 return reinterpret_steal<object>(result);
Wenzel Jakob0d3fc352016-07-08 10:52:10 +0200129}
Isuru Fernando0d70f0e2020-07-07 08:58:16 -0500130#endif
Wenzel Jakob0d3fc352016-07-08 10:52:10 +0200131
Yannick Jadoulf980d762020-07-09 00:14:41 +0200132PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)