eval.h revision 12391:ceeca8b41e4b
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 16NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 17 18enum eval_mode { 19 /// Evaluate a string containing an isolated expression 20 eval_expr, 21 22 /// Evaluate a string containing a single statement. Returns \c none 23 eval_single_statement, 24 25 /// Evaluate a string containing a sequence of statement. Returns \c none 26 eval_statements 27}; 28 29template <eval_mode mode = eval_expr> 30object eval(str expr, object global = globals(), object local = object()) { 31 if (!local) 32 local = global; 33 34 /* PyRun_String does not accept a PyObject / encoding specifier, 35 this seems to be the only alternative */ 36 std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr; 37 38 int start; 39 switch (mode) { 40 case eval_expr: start = Py_eval_input; break; 41 case eval_single_statement: start = Py_single_input; break; 42 case eval_statements: start = Py_file_input; break; 43 default: pybind11_fail("invalid evaluation mode"); 44 } 45 46 PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr()); 47 if (!result) 48 throw error_already_set(); 49 return reinterpret_steal<object>(result); 50} 51 52template <eval_mode mode = eval_expr, size_t N> 53object eval(const char (&s)[N], object global = globals(), object local = object()) { 54 /* Support raw string literals by removing common leading whitespace */ 55 auto expr = (s[0] == '\n') ? str(module::import("textwrap").attr("dedent")(s)) 56 : str(s); 57 return eval<mode>(expr, global, local); 58} 59 60inline void exec(str expr, object global = globals(), object local = object()) { 61 eval<eval_statements>(expr, global, local); 62} 63 64template <size_t N> 65void exec(const char (&s)[N], object global = globals(), object local = object()) { 66 eval<eval_statements>(s, global, local); 67} 68 69template <eval_mode mode = eval_statements> 70object eval_file(str fname, object global = globals(), object local = object()) { 71 if (!local) 72 local = global; 73 74 int start; 75 switch (mode) { 76 case eval_expr: start = Py_eval_input; break; 77 case eval_single_statement: start = Py_single_input; break; 78 case eval_statements: start = Py_file_input; break; 79 default: pybind11_fail("invalid evaluation mode"); 80 } 81 82 int closeFile = 1; 83 std::string fname_str = (std::string) fname; 84#if PY_VERSION_HEX >= 0x03040000 85 FILE *f = _Py_fopen_obj(fname.ptr(), "r"); 86#elif PY_VERSION_HEX >= 0x03000000 87 FILE *f = _Py_fopen(fname.ptr(), "r"); 88#else 89 /* No unicode support in open() :( */ 90 auto fobj = reinterpret_steal<object>(PyFile_FromString( 91 const_cast<char *>(fname_str.c_str()), 92 const_cast<char*>("r"))); 93 FILE *f = nullptr; 94 if (fobj) 95 f = PyFile_AsFile(fobj.ptr()); 96 closeFile = 0; 97#endif 98 if (!f) { 99 PyErr_Clear(); 100 pybind11_fail("File \"" + fname_str + "\" could not be opened!"); 101 } 102 103#if PY_VERSION_HEX < 0x03000000 && defined(PYPY_VERSION) 104 PyObject *result = PyRun_File(f, fname_str.c_str(), start, global.ptr(), 105 local.ptr()); 106 (void) closeFile; 107#else 108 PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), 109 local.ptr(), closeFile); 110#endif 111 112 if (!result) 113 throw error_already_set(); 114 return reinterpret_steal<object>(result); 115} 116 117NAMESPACE_END(PYBIND11_NAMESPACE) 118