eval.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. pybind11/eval.h: Support for evaluating Python expressions and statements
  3. from strings and files
  4. Copyright (c) 2016 Klemens Morgenstern <klemens.morgenstern@ed-chemnitz.de> and
  5. Wenzel Jakob <wenzel.jakob@epfl.ch>
  6. All rights reserved. Use of this source code is governed by a
  7. BSD-style license that can be found in the LICENSE file.
  8. */
  9. #pragma once
  10. #include "pybind11.h"
  11. #include <utility>
  12. PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
  13. PYBIND11_NAMESPACE_BEGIN(detail)
  14. inline void ensure_builtins_in_globals(object &global) {
  15. #if defined(PYPY_VERSION) || PY_VERSION_HEX < 0x03080000
  16. // Running exec and eval adds `builtins` module under `__builtins__` key to
  17. // globals if not yet present. Python 3.8 made PyRun_String behave
  18. // similarly. Let's also do that for older versions, for consistency. This
  19. // was missing from PyPy3.8 7.3.7.
  20. if (!global.contains("__builtins__"))
  21. global["__builtins__"] = module_::import(PYBIND11_BUILTINS_MODULE);
  22. #else
  23. (void) global;
  24. #endif
  25. }
  26. PYBIND11_NAMESPACE_END(detail)
  27. enum eval_mode {
  28. /// Evaluate a string containing an isolated expression
  29. eval_expr,
  30. /// Evaluate a string containing a single statement. Returns \c none
  31. eval_single_statement,
  32. /// Evaluate a string containing a sequence of statement. Returns \c none
  33. eval_statements
  34. };
  35. template <eval_mode mode = eval_expr>
  36. object eval(const str &expr, object global = globals(), object local = object()) {
  37. if (!local) {
  38. local = global;
  39. }
  40. detail::ensure_builtins_in_globals(global);
  41. /* PyRun_String does not accept a PyObject / encoding specifier,
  42. this seems to be the only alternative */
  43. std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr;
  44. int start = 0;
  45. switch (mode) {
  46. case eval_expr:
  47. start = Py_eval_input;
  48. break;
  49. case eval_single_statement:
  50. start = Py_single_input;
  51. break;
  52. case eval_statements:
  53. start = Py_file_input;
  54. break;
  55. default:
  56. pybind11_fail("invalid evaluation mode");
  57. }
  58. PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());
  59. if (!result) {
  60. throw error_already_set();
  61. }
  62. return reinterpret_steal<object>(result);
  63. }
  64. template <eval_mode mode = eval_expr, size_t N>
  65. object eval(const char (&s)[N], object global = globals(), object local = object()) {
  66. /* Support raw string literals by removing common leading whitespace */
  67. auto expr = (s[0] == '\n') ? str(module_::import("textwrap").attr("dedent")(s)) : str(s);
  68. return eval<mode>(expr, std::move(global), std::move(local));
  69. }
  70. inline void exec(const str &expr, object global = globals(), object local = object()) {
  71. eval<eval_statements>(expr, std::move(global), std::move(local));
  72. }
  73. template <size_t N>
  74. void exec(const char (&s)[N], object global = globals(), object local = object()) {
  75. eval<eval_statements>(s, std::move(global), std::move(local));
  76. }
  77. #if defined(PYPY_VERSION)
  78. template <eval_mode mode = eval_statements>
  79. object eval_file(str, object, object) {
  80. pybind11_fail("eval_file not supported in PyPy3. Use eval");
  81. }
  82. template <eval_mode mode = eval_statements>
  83. object eval_file(str, object) {
  84. pybind11_fail("eval_file not supported in PyPy3. Use eval");
  85. }
  86. template <eval_mode mode = eval_statements>
  87. object eval_file(str) {
  88. pybind11_fail("eval_file not supported in PyPy3. Use eval");
  89. }
  90. #else
  91. template <eval_mode mode = eval_statements>
  92. object eval_file(str fname, object global = globals(), object local = object()) {
  93. if (!local) {
  94. local = global;
  95. }
  96. detail::ensure_builtins_in_globals(global);
  97. int start = 0;
  98. switch (mode) {
  99. case eval_expr:
  100. start = Py_eval_input;
  101. break;
  102. case eval_single_statement:
  103. start = Py_single_input;
  104. break;
  105. case eval_statements:
  106. start = Py_file_input;
  107. break;
  108. default:
  109. pybind11_fail("invalid evaluation mode");
  110. }
  111. int closeFile = 1;
  112. std::string fname_str = (std::string) fname;
  113. FILE *f = _Py_fopen_obj(fname.ptr(), "r");
  114. if (!f) {
  115. PyErr_Clear();
  116. pybind11_fail("File \"" + fname_str + "\" could not be opened!");
  117. }
  118. if (!global.contains("__file__")) {
  119. global["__file__"] = std::move(fname);
  120. }
  121. PyObject *result
  122. = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), local.ptr(), closeFile);
  123. if (!result) {
  124. throw error_already_set();
  125. }
  126. return reinterpret_steal<object>(result);
  127. }
  128. #endif
  129. PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)