Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/pybind11/eval.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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 "pybind11.h"
0015 
0016 #include <utility>
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 adds `builtins` module under `__builtins__` key to
0024     // globals if not yet present.  Python 3.8 made PyRun_String behave
0025     // similarly. Let's also do that for older versions, for consistency. This
0026     // 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 
0053     detail::ensure_builtins_in_globals(global);
0054 
0055     /* PyRun_String does not accept a PyObject / encoding specifier,
0056        this seems to be the only alternative */
0057     std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr;
0058 
0059     int start = 0;
0060     switch (mode) {
0061         case eval_expr:
0062             start = Py_eval_input;
0063             break;
0064         case eval_single_statement:
0065             start = Py_single_input;
0066             break;
0067         case eval_statements:
0068             start = Py_file_input;
0069             break;
0070         default:
0071             pybind11_fail("invalid evaluation mode");
0072     }
0073 
0074     PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());
0075     if (!result) {
0076         throw error_already_set();
0077     }
0078     return reinterpret_steal<object>(result);
0079 }
0080 
0081 template <eval_mode mode = eval_expr, size_t N>
0082 object eval(const char (&s)[N], object global = globals(), object local = object()) {
0083     /* Support raw string literals by removing common leading whitespace */
0084     auto expr = (s[0] == '\n') ? str(module_::import("textwrap").attr("dedent")(s)) : str(s);
0085     return eval<mode>(expr, std::move(global), std::move(local));
0086 }
0087 
0088 inline void exec(const str &expr, object global = globals(), object local = object()) {
0089     eval<eval_statements>(expr, std::move(global), std::move(local));
0090 }
0091 
0092 template <size_t N>
0093 void exec(const char (&s)[N], object global = globals(), object local = object()) {
0094     eval<eval_statements>(s, std::move(global), std::move(local));
0095 }
0096 
0097 #if defined(PYPY_VERSION)
0098 template <eval_mode mode = eval_statements>
0099 object eval_file(str, object, object) {
0100     pybind11_fail("eval_file not supported in PyPy3. Use eval");
0101 }
0102 template <eval_mode mode = eval_statements>
0103 object eval_file(str, object) {
0104     pybind11_fail("eval_file not supported in PyPy3. Use eval");
0105 }
0106 template <eval_mode mode = eval_statements>
0107 object eval_file(str) {
0108     pybind11_fail("eval_file not supported in PyPy3. Use eval");
0109 }
0110 #else
0111 template <eval_mode mode = eval_statements>
0112 object eval_file(str fname, object global = globals(), object local = object()) {
0113     if (!local) {
0114         local = global;
0115     }
0116 
0117     detail::ensure_builtins_in_globals(global);
0118 
0119     int start = 0;
0120     switch (mode) {
0121         case eval_expr:
0122             start = Py_eval_input;
0123             break;
0124         case eval_single_statement:
0125             start = Py_single_input;
0126             break;
0127         case eval_statements:
0128             start = Py_file_input;
0129             break;
0130         default:
0131             pybind11_fail("invalid evaluation mode");
0132     }
0133 
0134     int closeFile = 1;
0135     std::string fname_str = (std::string) fname;
0136     FILE *f = _Py_fopen_obj(fname.ptr(), "r");
0137     if (!f) {
0138         PyErr_Clear();
0139         pybind11_fail("File \"" + fname_str + "\" could not be opened!");
0140     }
0141 
0142     if (!global.contains("__file__")) {
0143         global["__file__"] = std::move(fname);
0144     }
0145 
0146     PyObject *result
0147         = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), local.ptr(), closeFile);
0148 
0149     if (!result) {
0150         throw error_already_set();
0151     }
0152     return reinterpret_steal<object>(result);
0153 }
0154 #endif
0155 
0156 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)