#include <ParametersPlugin_PyInterp.h>
#include <string>
+#include <stdexcept>
ParametersPlugin_PyInterp::ParametersPlugin_PyInterp()
: PyInterp_Interp()
std::list<std::string> ParametersPlugin_PyInterp::compile(const std::string& theExpression)
{
- PyGILState_STATE aGilState = PyGILState_Ensure();
- std::list<std::string> res = this->_compile(theExpression);
- PyGILState_Release(aGilState);
- return res;
-}
-
-void ParametersPlugin_PyInterp::extendLocalContext(const std::list<std::string>& theParameters)
-{
- PyGILState_STATE aGilState = PyGILState_Ensure();
- this->_extendLocalContext(theParameters);
- PyGILState_Release(aGilState);
-}
-
-double ParametersPlugin_PyInterp::evaluate(const std::string& theExpression,
- std::string& theError)
-{
- PyGILState_STATE aGilState = PyGILState_Ensure();
- double res = this->_evaluate(theExpression, theError);
- PyGILState_Release(aGilState);
- return res;
-}
-
-
-std::list<std::string> ParametersPlugin_PyInterp::_compile(const std::string& theExpression)
-{
-
+ PyLockWrapper lck; // Acquire GIL until the end of the method
std::list<std::string> aResult;
PyObject *aCodeopModule = PyImport_AddModule("codeop");
if(!aCodeopModule) { // Fatal error. No way to go on.
}
PyCodeObject* aCodeObj = (PyCodeObject*) aCodePyObj;
+ std::string aCodeName(PyString_AsString(aCodeObj->co_code));
// co_names should be tuple, but can be changed in modern versions of python (>2.7.3)
if(!PyTuple_Check(aCodeObj->co_names))
return aResult;
return aResult;
}
-void ParametersPlugin_PyInterp::_extendLocalContext(const std::list<std::string>& theParameters)
+void ParametersPlugin_PyInterp::extendLocalContext(const std::list<std::string>& theParameters)
{
+ PyLockWrapper lck; // Acquire GIL until the end of the method
if (theParameters.empty())
return;
std::list<std::string>::const_iterator it = theParameters.begin();
}
}
+void ParametersPlugin_PyInterp::clearLocalContext()
+{
+ PyLockWrapper lck;
+ PyDict_Clear(_local_context);
+}
+
-double ParametersPlugin_PyInterp::_evaluate(const std::string& theExpression, std::string& theError)
+double ParametersPlugin_PyInterp::evaluate(const std::string& theExpression, std::string& theError)
{
+ PyLockWrapper lck; // Acquire GIL until the end of the method
PyCodeObject* anExprCode = (PyCodeObject *) Py_CompileString(theExpression.c_str(),
"<string>", Py_eval_input);
if(!anExprCode) {
Py_XDECREF(anExprCode);
Py_XDECREF(anEvalResult);
Py_XDECREF(anEvalStrObj);
- return std::stod(anEvalStr);
+ double result = 0.;
+ try {
+ result = std::stod(anEvalStr);
+ } catch (const std::invalid_argument&) {
+ theError = "Unable to eval " + anEvalStr;
+ }
+
+ return result;
}
std::string ParametersPlugin_PyInterp::errorMessage()
}
return aPyError;
}
+
+bool ParametersPlugin_PyInterp::initContext()
+{
+ PyObject *m = PyImport_AddModule("__main__"); // interpreter main module (module context)
+ if(!m){
+ PyErr_Print();
+ return false;
+ }
+ _global_context = PyModule_GetDict(m); // get interpreter global variable context
+ Py_INCREF(_global_context);
+ _local_context = PyDict_New();
+ Py_INCREF(_local_context);
+
+ return PyRun_SimpleString("from math import *") == 0;
+}
+
+void ParametersPlugin_PyInterp::closeContext()
+{
+ Py_XDECREF(_local_context);
+ PyInterp_Interp::closeContext();
+}