eval.h 5.0 KB

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