File indexing completed on 2025-02-16 05:12:16
0001 /* 0002 pybind11/eval.h: Support for evaluating Python expressions and statements 0003 from strings and files 0004 0005 Copyright (c) 2016 Klemens Morgenstern <klemens.morgenstern@ed-chemnitz.de> and 0006 Wenzel Jakob <wenzel.jakob@epfl.ch> 0007 0008 All rights reserved. Use of this source code is governed by a 0009 BSD-style license that can be found in the LICENSE file. 0010 */ 0011 0012 #pragma once 0013 0014 #include <utility> 0015 0016 #include "pybind11.h" 0017 0018 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 0019 PYBIND11_NAMESPACE_BEGIN(detail) 0020 0021 inline void ensure_builtins_in_globals(object &global) { 0022 #if defined(PYPY_VERSION) || PY_VERSION_HEX < 0x03080000 0023 // Running exec and eval on Python 2 and 3 adds `builtins` module under 0024 // `__builtins__` key to globals if not yet present. 0025 // Python 3.8 made PyRun_String behave similarly. Let's also do that for 0026 // older versions, for consistency. This was missing from PyPy3.8 7.3.7. 0027 if (!global.contains("__builtins__")) 0028 global["__builtins__"] = module_::import(PYBIND11_BUILTINS_MODULE); 0029 #else 0030 (void) global; 0031 #endif 0032 } 0033 0034 PYBIND11_NAMESPACE_END(detail) 0035 0036 enum eval_mode { 0037 /// Evaluate a string containing an isolated expression 0038 eval_expr, 0039 0040 /// Evaluate a string containing a single statement. Returns \c none 0041 eval_single_statement, 0042 0043 /// Evaluate a string containing a sequence of statement. Returns \c none 0044 eval_statements 0045 }; 0046 0047 template <eval_mode mode = eval_expr> 0048 object eval(const str &expr, object global = globals(), object local = object()) { 0049 if (!local) 0050 local = global; 0051 0052 detail::ensure_builtins_in_globals(global); 0053 0054 /* PyRun_String does not accept a PyObject / encoding specifier, 0055 this seems to be the only alternative */ 0056 std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr; 0057 0058 int start = 0; 0059 switch (mode) { 0060 case eval_expr: start = Py_eval_input; break; 0061 case eval_single_statement: start = Py_single_input; break; 0062 case eval_statements: start = Py_file_input; break; 0063 default: pybind11_fail("invalid evaluation mode"); 0064 } 0065 0066 PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr()); 0067 if (!result) 0068 throw error_already_set(); 0069 return reinterpret_steal<object>(result); 0070 } 0071 0072 template <eval_mode mode = eval_expr, size_t N> 0073 object eval(const char (&s)[N], object global = globals(), object local = object()) { 0074 /* Support raw string literals by removing common leading whitespace */ 0075 auto expr = (s[0] == '\n') ? str(module_::import("textwrap").attr("dedent")(s)) 0076 : str(s); 0077 return eval<mode>(expr, global, local); 0078 } 0079 0080 inline void exec(const str &expr, object global = globals(), object local = object()) { 0081 eval<eval_statements>(expr, std::move(global), std::move(local)); 0082 } 0083 0084 template <size_t N> 0085 void exec(const char (&s)[N], object global = globals(), object local = object()) { 0086 eval<eval_statements>(s, global, local); 0087 } 0088 0089 #if defined(PYPY_VERSION) && PY_VERSION_HEX >= 0x03000000 0090 template <eval_mode mode = eval_statements> 0091 object eval_file(str, object, object) { 0092 pybind11_fail("eval_file not supported in PyPy3. Use eval"); 0093 } 0094 template <eval_mode mode = eval_statements> 0095 object eval_file(str, object) { 0096 pybind11_fail("eval_file not supported in PyPy3. Use eval"); 0097 } 0098 template <eval_mode mode = eval_statements> 0099 object eval_file(str) { 0100 pybind11_fail("eval_file not supported in PyPy3. Use eval"); 0101 } 0102 #else 0103 template <eval_mode mode = eval_statements> 0104 object eval_file(str fname, object global = globals(), object local = object()) { 0105 if (!local) 0106 local = global; 0107 0108 detail::ensure_builtins_in_globals(global); 0109 0110 int start = 0; 0111 switch (mode) { 0112 case eval_expr: start = Py_eval_input; break; 0113 case eval_single_statement: start = Py_single_input; break; 0114 case eval_statements: start = Py_file_input; break; 0115 default: pybind11_fail("invalid evaluation mode"); 0116 } 0117 0118 int closeFile = 1; 0119 std::string fname_str = (std::string) fname; 0120 #if PY_VERSION_HEX >= 0x03040000 0121 FILE *f = _Py_fopen_obj(fname.ptr(), "r"); 0122 #elif PY_VERSION_HEX >= 0x03000000 0123 FILE *f = _Py_fopen(fname.ptr(), "r"); 0124 #else 0125 /* No unicode support in open() :( */ 0126 auto fobj = reinterpret_steal<object>(PyFile_FromString( 0127 const_cast<char *>(fname_str.c_str()), 0128 const_cast<char*>("r"))); 0129 FILE *f = nullptr; 0130 if (fobj) 0131 f = PyFile_AsFile(fobj.ptr()); 0132 closeFile = 0; 0133 #endif 0134 if (!f) { 0135 PyErr_Clear(); 0136 pybind11_fail("File \"" + fname_str + "\" could not be opened!"); 0137 } 0138 0139 // In Python2, this should be encoded by getfilesystemencoding. 0140 // We don't boher setting it since Python2 is past EOL anyway. 0141 // See PR#3233 0142 #if PY_VERSION_HEX >= 0x03000000 0143 if (!global.contains("__file__")) { 0144 global["__file__"] = std::move(fname); 0145 } 0146 #endif 0147 0148 #if PY_VERSION_HEX < 0x03000000 && defined(PYPY_VERSION) 0149 PyObject *result = PyRun_File(f, fname_str.c_str(), start, global.ptr(), 0150 local.ptr()); 0151 (void) closeFile; 0152 #else 0153 PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), 0154 local.ptr(), closeFile); 0155 #endif 0156 0157 if (!result) 0158 throw error_already_set(); 0159 return reinterpret_steal<object>(result); 0160 } 0161 #endif 0162 0163 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)