2 * ParametersPlugin_PyInterp.cpp
4 * Created on: Apr 2, 2015
8 #include <ParametersPlugin_PyInterp.h>
13 ParametersPlugin_PyInterp::ParametersPlugin_PyInterp()
18 ParametersPlugin_PyInterp::~ParametersPlugin_PyInterp()
22 std::list<std::string> ParametersPlugin_PyInterp::compile(const std::string& theExpression)
24 PyLockWrapper lck; // Acquire GIL until the end of the method
25 std::list<std::string> aResult;
26 PyObject *aCodeopModule = PyImport_AddModule("codeop");
27 if(!aCodeopModule) { // Fatal error. No way to go on.
32 PyObject *aCodePyObj =
33 PyObject_CallMethod(aCodeopModule, "compile_command", "(s)", theExpression.c_str());
35 if(!aCodePyObj || aCodePyObj == Py_None || !PyCode_Check(aCodePyObj)) {
36 Py_XDECREF(aCodePyObj);
40 PyCodeObject* aCodeObj = (PyCodeObject*) aCodePyObj;
41 std::string aCodeName(PyString_AsString(aCodeObj->co_code));
42 // co_names should be tuple, but can be changed in modern versions of python (>2.7.3)
43 if(!PyTuple_Check(aCodeObj->co_names))
46 int params_size = PyTuple_Size(aCodeObj->co_names);
47 if (params_size > 0) {
48 for (int i = 0; i < params_size; i++) {
49 PyObject* aParamObj = PyTuple_GetItem(aCodeObj->co_names, i);
50 PyObject* aParamObjStr = PyObject_Str(aParamObj);
51 std::string aParamName(PyString_AsString(aParamObjStr));
52 aResult.push_back(aParamName);
53 Py_XDECREF(aParamObjStr);
60 void ParametersPlugin_PyInterp::extendLocalContext(const std::list<std::string>& theParameters)
62 PyLockWrapper lck; // Acquire GIL until the end of the method
63 if (theParameters.empty())
65 std::list<std::string>::const_iterator it = theParameters.begin();
66 for ( ; it != theParameters.cend(); it++) {
67 std::string aParamValue = *it;
68 simpleRun(aParamValue.c_str(), false);
73 double ParametersPlugin_PyInterp::evaluate(const std::string& theExpression, std::string& theError)
75 PyLockWrapper lck; // Acquire GIL until the end of the method
76 PyCodeObject* anExprCode = (PyCodeObject *) Py_CompileString(theExpression.c_str(),
77 "<string>", Py_eval_input);
79 theError = errorMessage();
80 Py_XDECREF(anExprCode);
84 PyObject* anEvalResult = PyEval_EvalCode(anExprCode, _global_context, _local_context);
86 theError = errorMessage();
87 Py_XDECREF(anExprCode);
88 Py_XDECREF(anEvalResult);
92 PyObject* anEvalStrObj = PyObject_Str(anEvalResult);
93 std::string anEvalStr(PyString_AsString(anEvalStrObj));
94 Py_XDECREF(anExprCode);
95 Py_XDECREF(anEvalResult);
96 Py_XDECREF(anEvalStrObj);
99 result = std::stod(anEvalStr);
100 } catch (const std::invalid_argument&) {
101 theError = "Unable to eval " + anEvalStr;
107 std::string ParametersPlugin_PyInterp::errorMessage()
109 std::string aPyError;
110 if (PyErr_Occurred()) {
111 PyObject *pstr, *ptype, *pvalue, *ptraceback;
112 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
113 PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
114 pstr = PyObject_Str(pvalue);
115 aPyError = std::string(PyString_AsString(pstr));
119 Py_XDECREF(ptraceback);
124 bool ParametersPlugin_PyInterp::initContext()
126 PyObject *m = PyImport_AddModule("__main__"); // interpreter main module (module context)
131 _global_context = PyModule_GetDict(m); // get interpreter global variable context
132 Py_INCREF(_global_context);
133 _local_context = _global_context;
135 return PyRun_SimpleString("from math import *") == 0;