eval.h revision 11986:c12e4625ab56
113219Sodanrc@yahoo.com.br/* 213219Sodanrc@yahoo.com.br pybind11/exec.h: Support for evaluating Python expressions and statements 313219Sodanrc@yahoo.com.br from strings and files 413219Sodanrc@yahoo.com.br 513219Sodanrc@yahoo.com.br Copyright (c) 2016 Klemens Morgenstern <klemens.morgenstern@ed-chemnitz.de> and 613219Sodanrc@yahoo.com.br Wenzel Jakob <wenzel.jakob@epfl.ch> 713219Sodanrc@yahoo.com.br 813219Sodanrc@yahoo.com.br All rights reserved. Use of this source code is governed by a 913219Sodanrc@yahoo.com.br BSD-style license that can be found in the LICENSE file. 1013219Sodanrc@yahoo.com.br*/ 1113219Sodanrc@yahoo.com.br 1213219Sodanrc@yahoo.com.br#pragma once 1313219Sodanrc@yahoo.com.br 1413219Sodanrc@yahoo.com.br#pragma once 1513219Sodanrc@yahoo.com.br 1613219Sodanrc@yahoo.com.br#include "pybind11.h" 1713219Sodanrc@yahoo.com.br 1813219Sodanrc@yahoo.com.brNAMESPACE_BEGIN(pybind11) 1913219Sodanrc@yahoo.com.br 2013219Sodanrc@yahoo.com.brenum eval_mode { 2113219Sodanrc@yahoo.com.br /// Evaluate a string containing an isolated expression 2213219Sodanrc@yahoo.com.br eval_expr, 2313219Sodanrc@yahoo.com.br 2413219Sodanrc@yahoo.com.br /// Evaluate a string containing a single statement. Returns \c none 2513219Sodanrc@yahoo.com.br eval_single_statement, 2613219Sodanrc@yahoo.com.br 2713219Sodanrc@yahoo.com.br /// Evaluate a string containing a sequence of statement. Returns \c none 2813219Sodanrc@yahoo.com.br eval_statements 2913219Sodanrc@yahoo.com.br}; 3013219Sodanrc@yahoo.com.br 3113219Sodanrc@yahoo.com.brtemplate <eval_mode mode = eval_expr> 3213219Sodanrc@yahoo.com.brobject eval(str expr, object global = object(), object local = object()) { 3313219Sodanrc@yahoo.com.br if (!global) { 3413219Sodanrc@yahoo.com.br global = reinterpret_borrow<object>(PyEval_GetGlobals()); 3513219Sodanrc@yahoo.com.br if (!global) 3613219Sodanrc@yahoo.com.br global = dict(); 3713219Sodanrc@yahoo.com.br } 3813219Sodanrc@yahoo.com.br if (!local) 3913219Sodanrc@yahoo.com.br local = global; 4013219Sodanrc@yahoo.com.br 4113219Sodanrc@yahoo.com.br /* PyRun_String does not accept a PyObject / encoding specifier, 4213219Sodanrc@yahoo.com.br this seems to be the only alternative */ 4313219Sodanrc@yahoo.com.br std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr; 4413219Sodanrc@yahoo.com.br 4513219Sodanrc@yahoo.com.br int start; 4613219Sodanrc@yahoo.com.br switch (mode) { 4713219Sodanrc@yahoo.com.br case eval_expr: start = Py_eval_input; break; 4813219Sodanrc@yahoo.com.br case eval_single_statement: start = Py_single_input; break; 4913219Sodanrc@yahoo.com.br case eval_statements: start = Py_file_input; break; 5013219Sodanrc@yahoo.com.br default: pybind11_fail("invalid evaluation mode"); 5113219Sodanrc@yahoo.com.br } 5213219Sodanrc@yahoo.com.br 5313219Sodanrc@yahoo.com.br PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr()); 5413219Sodanrc@yahoo.com.br if (!result) 5513219Sodanrc@yahoo.com.br throw error_already_set(); 5613219Sodanrc@yahoo.com.br return reinterpret_steal<object>(result); 5713219Sodanrc@yahoo.com.br} 5813219Sodanrc@yahoo.com.br 5913219Sodanrc@yahoo.com.brtemplate <eval_mode mode = eval_statements> 6013219Sodanrc@yahoo.com.brobject eval_file(str fname, object global = object(), object local = object()) { 6113219Sodanrc@yahoo.com.br if (!global) { 6213219Sodanrc@yahoo.com.br global = reinterpret_borrow<object>(PyEval_GetGlobals()); 6313219Sodanrc@yahoo.com.br if (!global) 6413219Sodanrc@yahoo.com.br global = dict(); 6513219Sodanrc@yahoo.com.br } 6613219Sodanrc@yahoo.com.br if (!local) 6713219Sodanrc@yahoo.com.br local = global; 6813219Sodanrc@yahoo.com.br 6913219Sodanrc@yahoo.com.br int start; 7013219Sodanrc@yahoo.com.br switch (mode) { 7113219Sodanrc@yahoo.com.br case eval_expr: start = Py_eval_input; break; 7213219Sodanrc@yahoo.com.br case eval_single_statement: start = Py_single_input; break; 7313219Sodanrc@yahoo.com.br case eval_statements: start = Py_file_input; break; 7413219Sodanrc@yahoo.com.br default: pybind11_fail("invalid evaluation mode"); 7513219Sodanrc@yahoo.com.br } 7613219Sodanrc@yahoo.com.br 7713219Sodanrc@yahoo.com.br int closeFile = 1; 7813219Sodanrc@yahoo.com.br std::string fname_str = (std::string) fname; 7913219Sodanrc@yahoo.com.br#if PY_VERSION_HEX >= 0x03040000 8013219Sodanrc@yahoo.com.br FILE *f = _Py_fopen_obj(fname.ptr(), "r"); 8113219Sodanrc@yahoo.com.br#elif PY_VERSION_HEX >= 0x03000000 8213219Sodanrc@yahoo.com.br FILE *f = _Py_fopen(fname.ptr(), "r"); 8313219Sodanrc@yahoo.com.br#else 8413219Sodanrc@yahoo.com.br /* No unicode support in open() :( */ 8513219Sodanrc@yahoo.com.br auto fobj = reinterpret_steal<object>(PyFile_FromString( 8613219Sodanrc@yahoo.com.br const_cast<char *>(fname_str.c_str()), 8713219Sodanrc@yahoo.com.br const_cast<char*>("r"))); 8813219Sodanrc@yahoo.com.br FILE *f = nullptr; 8913219Sodanrc@yahoo.com.br if (fobj) 9013219Sodanrc@yahoo.com.br f = PyFile_AsFile(fobj.ptr()); 9113219Sodanrc@yahoo.com.br closeFile = 0; 9213219Sodanrc@yahoo.com.br#endif 9313219Sodanrc@yahoo.com.br if (!f) { 9413219Sodanrc@yahoo.com.br PyErr_Clear(); 9513219Sodanrc@yahoo.com.br pybind11_fail("File \"" + fname_str + "\" could not be opened!"); 9613219Sodanrc@yahoo.com.br } 9713219Sodanrc@yahoo.com.br 9813219Sodanrc@yahoo.com.br PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), 9913219Sodanrc@yahoo.com.br local.ptr(), closeFile); 10013219Sodanrc@yahoo.com.br if (!result) 10113219Sodanrc@yahoo.com.br throw error_already_set(); 10213219Sodanrc@yahoo.com.br return reinterpret_steal<object>(result); 10313219Sodanrc@yahoo.com.br} 10413219Sodanrc@yahoo.com.br 10513219Sodanrc@yahoo.com.brNAMESPACE_END(pybind11) 10613219Sodanrc@yahoo.com.br