1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include <InitializationPlugin_PyInterp.h>
27 InitializationPlugin_PyInterp::InitializationPlugin_PyInterp()
32 InitializationPlugin_PyInterp::~InitializationPlugin_PyInterp()
36 const char* aSearchCode =
38 "class FindName(ast.NodeVisitor):\n"
39 " def __init__(self, name):\n"
41 " def visit_Name(self, node):\n"
42 " if node.id == self.name:\n"
43 " positions.append((node.lineno, node.col_offset))\n"
44 "FindName(name).visit(ast.parse(expression))";
46 std::list<std::pair<int, int> >
47 InitializationPlugin_PyInterp::positions(const std::string& theExpression,
48 const std::string& theName)
50 PyLockWrapper lck; // Acquire GIL until the end of the method
52 std::list<std::pair<int, int> > aResult;
55 PyObject* aContext = PyDict_New();
56 PyObject* aBuiltinModule = PyImport_AddModule("__builtin__");
57 PyDict_SetItemString(aContext, "__builtins__", aBuiltinModule);
59 // extend aContext with variables
60 PyDict_SetItemString(aContext, "expression", PyString_FromString(theExpression.c_str()));
61 PyDict_SetItemString(aContext, "name", PyString_FromString(theName.c_str()));
62 PyDict_SetItemString(aContext, "positions", Py_BuildValue("[]"));
64 // run the search code
65 PyObject* aExecResult = PyRun_String(aSearchCode, Py_file_input, aContext, aContext);
66 Py_XDECREF(aExecResult);
68 // receive results from context
69 PyObject* aPositions = PyDict_GetItemString(aContext, "positions");
70 for (int anIndex = 0; anIndex < PyList_Size(aPositions); ++anIndex) {
71 PyObject* aPosition = PyList_GetItem(aPositions, anIndex);
72 PyObject* aLineNo = PyTuple_GetItem(aPosition, 0);
73 PyObject* aColOffset = PyTuple_GetItem(aPosition, 1);
76 std::pair<int, int>((int)PyInt_AsLong(aLineNo),
77 (int)PyInt_AsLong(aColOffset)));
80 // TODO(spo): after this refCount of the variable is not 0. Is there memory leak?
87 std::list<std::string> InitializationPlugin_PyInterp::compile(const std::string& theExpression)
89 PyLockWrapper lck; // Acquire GIL until the end of the method
90 std::list<std::string> aResult;
91 PyObject *aCodeopModule = PyImport_AddModule("codeop");
92 if(!aCodeopModule) { // Fatal error. No way to go on.
97 PyObject *aCodePyObj =
98 PyObject_CallMethod(aCodeopModule, (char*)"compile_command", (char*)"(s)",
99 theExpression.c_str());
101 if(!aCodePyObj || aCodePyObj == Py_None || !PyCode_Check(aCodePyObj)) {
102 Py_XDECREF(aCodePyObj);
106 PyCodeObject* aCodeObj = (PyCodeObject*) aCodePyObj;
107 std::string aCodeName(PyString_AsString(aCodeObj->co_code));
108 // co_names should be tuple, but can be changed in modern versions of python (>2.7.3)
109 if(!PyTuple_Check(aCodeObj->co_names))
112 size_t params_size = PyTuple_Size(aCodeObj->co_names);
113 if (params_size > 0) {
114 for (size_t i = 0; i < params_size; i++) {
115 PyObject* aParamObj = PyTuple_GetItem(aCodeObj->co_names, i);
116 PyObject* aParamObjStr = PyObject_Str(aParamObj);
117 std::string aParamName(PyString_AsString(aParamObjStr));
118 aResult.push_back(aParamName);
119 Py_XDECREF(aParamObjStr);
122 Py_XDECREF(aCodeObj);
126 void InitializationPlugin_PyInterp::extendLocalContext(const std::list<std::string>& theParameters)
128 PyLockWrapper lck; // Acquire GIL until the end of the method
129 if (theParameters.empty())
131 std::list<std::string>::const_iterator it = theParameters.begin();
132 for ( ; it != theParameters.cend(); it++) {
133 std::string aParamValue = *it;
134 simpleRun(aParamValue.c_str(), false);
138 void InitializationPlugin_PyInterp::clearLocalContext()
141 PyDict_Clear(_local_context);
144 double InitializationPlugin_PyInterp::evaluate(const std::string& theExpression,
145 std::string& theError)
147 PyLockWrapper lck; // Acquire GIL until the end of the method
148 PyCompilerFlags aFlags = {CO_FUTURE_DIVISION};
149 aFlags.cf_flags = CO_FUTURE_DIVISION;
150 PyCodeObject* anExprCode = (PyCodeObject *) Py_CompileStringFlags(theExpression.c_str(),
151 "<string>", Py_eval_input, &aFlags);
153 theError = errorMessage();
154 Py_XDECREF(anExprCode);
158 PyObject* anEvalResult = PyEval_EvalCode(anExprCode, _global_context, _local_context);
160 theError = errorMessage();
161 Py_XDECREF(anExprCode);
162 Py_XDECREF(anEvalResult);
166 PyObject* anEvalStrObj = PyObject_Str(anEvalResult);
167 std::string anEvalStr(PyString_AsString(anEvalStrObj));
168 Py_XDECREF(anExprCode);
169 Py_XDECREF(anEvalResult);
170 Py_XDECREF(anEvalStrObj);
173 // set locale due to the #2485
174 std::string aCurLocale = std::setlocale(LC_NUMERIC, 0);
175 std::setlocale(LC_NUMERIC, "C");
176 result = std::stod(anEvalStr);
177 std::setlocale(LC_NUMERIC, aCurLocale.c_str());
179 catch (const std::invalid_argument&) {
180 theError = "Unable to eval " + anEvalStr;
186 std::string InitializationPlugin_PyInterp::errorMessage()
188 std::string aPyError;
189 if (PyErr_Occurred()) {
190 PyObject *pstr, *ptype, *pvalue, *ptraceback;
191 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
192 PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
193 pstr = PyObject_Str(pvalue);
194 aPyError = std::string(PyString_AsString(pstr));
198 Py_XDECREF(ptraceback);
203 bool InitializationPlugin_PyInterp::initContext()
205 PyObject *m = PyImport_AddModule("__main__"); // interpreter main module (module context)
210 _global_context = PyModule_GetDict(m); // get interpreter global variable context
211 Py_INCREF(_global_context);
212 _local_context = PyDict_New();
213 Py_INCREF(_local_context);
215 return PyRun_SimpleString("from math import *") == 0;
218 void InitializationPlugin_PyInterp::closeContext()
220 Py_XDECREF(_local_context);
221 PyInterp_Interp::closeContext();