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