You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
3.4 KiB

8 years ago
  1. /*
  2. pybind11/exec.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. #pragma once
  11. #include "pybind11.h"
  12. NAMESPACE_BEGIN(pybind11)
  13. enum eval_mode {
  14. /// Evaluate a string containing an isolated expression
  15. eval_expr,
  16. /// Evaluate a string containing a single statement. Returns \c none
  17. eval_single_statement,
  18. /// Evaluate a string containing a sequence of statement. Returns \c none
  19. eval_statements
  20. };
  21. template <eval_mode mode = eval_expr>
  22. object eval(str expr, object global = object(), object local = object()) {
  23. if (!global) {
  24. global = reinterpret_borrow<object>(PyEval_GetGlobals());
  25. if (!global)
  26. global = dict();
  27. }
  28. if (!local)
  29. local = global;
  30. /* PyRun_String does not accept a PyObject / encoding specifier,
  31. this seems to be the only alternative */
  32. std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr;
  33. int start;
  34. switch (mode) {
  35. case eval_expr: start = Py_eval_input; break;
  36. case eval_single_statement: start = Py_single_input; break;
  37. case eval_statements: start = Py_file_input; break;
  38. default: pybind11_fail("invalid evaluation mode");
  39. }
  40. PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());
  41. if (!result)
  42. throw error_already_set();
  43. return reinterpret_steal<object>(result);
  44. }
  45. template <eval_mode mode = eval_statements>
  46. object eval_file(str fname, object global = object(), object local = object()) {
  47. if (!global) {
  48. global = reinterpret_borrow<object>(PyEval_GetGlobals());
  49. if (!global)
  50. global = dict();
  51. }
  52. if (!local)
  53. local = global;
  54. int start;
  55. switch (mode) {
  56. case eval_expr: start = Py_eval_input; break;
  57. case eval_single_statement: start = Py_single_input; break;
  58. case eval_statements: start = Py_file_input; break;
  59. default: pybind11_fail("invalid evaluation mode");
  60. }
  61. int closeFile = 1;
  62. std::string fname_str = (std::string) fname;
  63. #if PY_VERSION_HEX >= 0x03040000
  64. FILE *f = _Py_fopen_obj(fname.ptr(), "r");
  65. #elif PY_VERSION_HEX >= 0x03000000
  66. FILE *f = _Py_fopen(fname.ptr(), "r");
  67. #else
  68. /* No unicode support in open() :( */
  69. auto fobj = reinterpret_steal<object>(PyFile_FromString(
  70. const_cast<char *>(fname_str.c_str()),
  71. const_cast<char*>("r")));
  72. FILE *f = nullptr;
  73. if (fobj)
  74. f = PyFile_AsFile(fobj.ptr());
  75. closeFile = 0;
  76. #endif
  77. if (!f) {
  78. PyErr_Clear();
  79. pybind11_fail("File \"" + fname_str + "\" could not be opened!");
  80. }
  81. #if PY_VERSION_HEX < 0x03000000 && defined(PYPY_VERSION)
  82. PyObject *result = PyRun_File(f, fname_str.c_str(), start, global.ptr(),
  83. local.ptr());
  84. (void) closeFile;
  85. #else
  86. PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(),
  87. local.ptr(), closeFile);
  88. #endif
  89. if (!result)
  90. throw error_already_set();
  91. return reinterpret_steal<object>(result);
  92. }
  93. NAMESPACE_END(pybind11)