cppyabm  1.0.17
An agent-based library to integrate C++ and Python
eval.h
Go to the documentation of this file.
1 /*
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 
14 #include "pybind11.h"
15 
18 
19 inline 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 
33 
34 enum eval_mode {
35  /// Evaluate a string containing an isolated expression
37 
38  /// Evaluate a string containing a single statement. Returns \c none
40 
41  /// Evaluate a string containing a sequence of statement. Returns \c none
43 };
44 
45 template <eval_mode mode = eval_expr>
46 object eval(str expr, object global = globals(), object local = object()) {
47  if (!local)
48  local = global;
49 
51 
52  /* 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 
56  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 
64  PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());
65  if (!result)
66  throw error_already_set();
67  return reinterpret_steal<object>(result);
68 }
69 
70 template <eval_mode mode = eval_expr, size_t N>
71 object eval(const char (&s)[N], object global = globals(), object local = object()) {
72  /* Support raw string literals by removing common leading whitespace */
73  auto expr = (s[0] == '\n') ? str(module_::import("textwrap").attr("dedent")(s))
74  : str(s);
75  return eval<mode>(expr, global, local);
76 }
77 
78 inline void exec(str expr, object global = globals(), object local = object()) {
79  eval<eval_statements>(expr, global, local);
80 }
81 
82 template <size_t N>
83 void exec(const char (&s)[N], object global = globals(), object local = object()) {
84  eval<eval_statements>(s, global, local);
85 }
86 
87 #if defined(PYPY_VERSION) && PY_VERSION_HEX >= 0x03000000
88 template <eval_mode mode = eval_statements>
89 object eval_file(str, object, object) {
90  pybind11_fail("eval_file not supported in PyPy3. Use eval");
91 }
92 template <eval_mode mode = eval_statements>
93 object eval_file(str, object) {
94  pybind11_fail("eval_file not supported in PyPy3. Use eval");
95 }
96 template <eval_mode mode = eval_statements>
97 object eval_file(str) {
98  pybind11_fail("eval_file not supported in PyPy3. Use eval");
99 }
100 #else
101 template <eval_mode mode = eval_statements>
102 object eval_file(str fname, object global = globals(), object local = object()) {
103  if (!local)
104  local = global;
105 
107 
108  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 
116  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() :( */
124  auto fobj = reinterpret_steal<object>(PyFile_FromString(
125  const_cast<char *>(fname_str.c_str()),
126  const_cast<char*>("r")));
127  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  }
136 
137 #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
142  PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(),
143  local.ptr(), closeFile);
144 #endif
145 
146  if (!result)
147  throw error_already_set();
148  return reinterpret_steal<object>(result);
149 }
150 #endif
151 
module_::import
static module_ import(const char *name)
Import and return a module or throws error_already_set.
Definition: pybind11.h:991
PYBIND11_BUILTINS_MODULE
#define PYBIND11_BUILTINS_MODULE
Definition: common.h:233
PYBIND11_NAMESPACE_BEGIN
#define PYBIND11_NAMESPACE_BEGIN(name)
Definition: common.h:16
PYBIND11_NAMESPACE_END
#define PYBIND11_NAMESPACE_END(name)
Definition: common.h:17
error_already_set
Definition: pytypes.h:326
PYBIND11_NAMESPACE
#define PYBIND11_NAMESPACE
Definition: common.h:26
eval_single_statement
@ eval_single_statement
Evaluate a string containing a single statement. Returns none.
Definition: eval.h:39
eval_statements
@ eval_statements
Evaluate a string containing a sequence of statement. Returns none.
Definition: eval.h:42
eval
object eval(str expr, object global=globals(), object local=object())
Definition: eval.h:46
buffer
Definition: pytypes.h:1403
exec
void exec(str expr, object global=globals(), object local=object())
Definition: eval.h:78
ensure_builtins_in_globals
void ensure_builtins_in_globals(object &global)
Definition: eval.h:19
eval_mode
eval_mode
Definition: eval.h:34
eval_expr
@ eval_expr
Evaluate a string containing an isolated expression.
Definition: eval.h:36
pybind11_fail
PyExc_RuntimeError PYBIND11_NOINLINE void pybind11_fail(const char *reason)
Used internally.
Definition: common.h:751
str
Definition: pytypes.h:946
pybind11.h
handle::ptr
PyObject * ptr() const
Return the underlying PyObject * pointer.
Definition: pytypes.h:184
eval_file
object eval_file(str fname, object global=globals(), object local=object())
Definition: eval.h:102
globals
dict globals()
Definition: pybind11.h:1072