X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FInitializationPlugin%2FInitializationPlugin_PyInterp.cpp;h=b7d591b29c184ac7dae0caed20b00afbcd46436d;hb=f9426a402de748e9d13085856a7cf72a3659135d;hp=e3cce6120e3186dee0f8d45d0dbcdd559efc0ba6;hpb=e7619fdb3df37b612acfd127e50e6c41dc7b9680;p=modules%2Fshaper.git diff --git a/src/InitializationPlugin/InitializationPlugin_PyInterp.cpp b/src/InitializationPlugin/InitializationPlugin_PyInterp.cpp index e3cce6120..b7d591b29 100644 --- a/src/InitializationPlugin/InitializationPlugin_PyInterp.cpp +++ b/src/InitializationPlugin/InitializationPlugin_PyInterp.cpp @@ -43,6 +43,16 @@ const char* aSearchCode = " positions.append((node.lineno, node.col_offset))\n" "FindName(name).visit(ast.parse(expression))"; +// make the expression be correct for the python interpreter even for the +// beta=alfa*2 expressions +static std::string adjustExpression(const std::string& theExpression) { + std::string anExpression = theExpression; + if (!anExpression.empty() && anExpression.back() == '=') { + anExpression = anExpression.substr(0, anExpression.length() - 1); + } + return anExpression; +} + std::list > InitializationPlugin_PyInterp::positions(const std::string& theExpression, const std::string& theName) @@ -56,9 +66,10 @@ InitializationPlugin_PyInterp::positions(const std::string& theExpression, PyObject* aBuiltinModule = PyImport_AddModule("__builtin__"); PyDict_SetItemString(aContext, "__builtins__", aBuiltinModule); + std::string anExpression = adjustExpression(theExpression); // extend aContext with variables - PyDict_SetItemString(aContext, "expression", PyString_FromString(theExpression.c_str())); - PyDict_SetItemString(aContext, "name", PyString_FromString(theName.c_str())); + PyDict_SetItemString(aContext, "expression", PyUnicode_FromString(anExpression.c_str())); + PyDict_SetItemString(aContext, "name", PyUnicode_FromString(theName.c_str())); PyDict_SetItemString(aContext, "positions", Py_BuildValue("[]")); // run the search code @@ -73,8 +84,8 @@ InitializationPlugin_PyInterp::positions(const std::string& theExpression, PyObject* aColOffset = PyTuple_GetItem(aPosition, 1); aResult.push_back( - std::pair((int)PyInt_AsLong(aLineNo), - (int)PyInt_AsLong(aColOffset))); + std::pair((int)PyLong_AsLong(aLineNo), + (int)PyLong_AsLong(aColOffset))); } // TODO(spo): after this refCount of the variable is not 0. Is there memory leak? @@ -93,10 +104,12 @@ std::list InitializationPlugin_PyInterp::compile(const std::string& PyErr_Print(); return aResult; } + // support "variable_name=" expression as "variable_name" + std::string anExpression = adjustExpression(theExpression); PyObject *aCodePyObj = PyObject_CallMethod(aCodeopModule, (char*)"compile_command", (char*)"(s)", - theExpression.c_str()); + anExpression.c_str()); if(!aCodePyObj || aCodePyObj == Py_None || !PyCode_Check(aCodePyObj)) { Py_XDECREF(aCodePyObj); @@ -104,17 +117,18 @@ std::list InitializationPlugin_PyInterp::compile(const std::string& } PyCodeObject* aCodeObj = (PyCodeObject*) aCodePyObj; - std::string aCodeName(PyString_AsString(aCodeObj->co_code)); + std::string aCodeName(PyBytes_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)) + if(!PyTuple_Check(aCodeObj->co_names)) { return aResult; + } size_t params_size = PyTuple_Size(aCodeObj->co_names); if (params_size > 0) { for (size_t i = 0; i < params_size; i++) { PyObject* aParamObj = PyTuple_GetItem(aCodeObj->co_names, i); PyObject* aParamObjStr = PyObject_Str(aParamObj); - std::string aParamName(PyString_AsString(aParamObjStr)); + std::string aParamName(PyUnicode_AsUTF8(aParamObjStr)); aResult.push_back(aParamName); Py_XDECREF(aParamObjStr); } @@ -144,10 +158,13 @@ void InitializationPlugin_PyInterp::clearLocalContext() double InitializationPlugin_PyInterp::evaluate(const std::string& theExpression, std::string& theError) { + // support "variable_name=" expression as "variable_name" + std::string anExpression = adjustExpression(theExpression); + PyLockWrapper lck; // Acquire GIL until the end of the method PyCompilerFlags aFlags = {CO_FUTURE_DIVISION}; aFlags.cf_flags = CO_FUTURE_DIVISION; - PyCodeObject* anExprCode = (PyCodeObject *) Py_CompileStringFlags(theExpression.c_str(), + PyCodeObject* anExprCode = (PyCodeObject *) Py_CompileStringFlags(anExpression.c_str(), "", Py_eval_input, &aFlags); if(!anExprCode) { theError = errorMessage(); @@ -155,7 +172,7 @@ double InitializationPlugin_PyInterp::evaluate(const std::string& theExpression, return 0.; } - PyObject* anEvalResult = PyEval_EvalCode(anExprCode, _global_context, _local_context); + PyObject* anEvalResult = PyEval_EvalCode((PyObject *)anExprCode, _global_context, _local_context); if(!anEvalResult) { theError = errorMessage(); Py_XDECREF(anExprCode); @@ -164,7 +181,7 @@ double InitializationPlugin_PyInterp::evaluate(const std::string& theExpression, } PyObject* anEvalStrObj = PyObject_Str(anEvalResult); - std::string anEvalStr(PyString_AsString(anEvalStrObj)); + std::string anEvalStr(PyUnicode_AsUTF8(anEvalStrObj)); Py_XDECREF(anExprCode); Py_XDECREF(anEvalResult); Py_XDECREF(anEvalStrObj); @@ -191,7 +208,7 @@ std::string InitializationPlugin_PyInterp::errorMessage() PyErr_Fetch(&ptype, &pvalue, &ptraceback); PyErr_NormalizeException(&ptype, &pvalue, &ptraceback); pstr = PyObject_Str(pvalue); - aPyError = std::string(PyString_AsString(pstr)); + aPyError = std::string(PyUnicode_AsUTF8(pstr)); Py_XDECREF(pstr); Py_XDECREF(ptype); Py_XDECREF(pvalue);