eval.h 5.0 KB

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