1 // Copyright (C) 2019-2023 CEA, EDF, OPEN CASCADE
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 email : webmaster.salome@opencascade.com
19 // Author : Anthony GEAY (EDF R&D)
21 #include "SALOME_CPythonHelper.hxx"
22 #include "PythonCppUtils.hxx"
24 SALOME_CPythonHelper *SALOME_CPythonHelper::_CPYTHONHELPER_INSTANCE = nullptr;
26 #if PY_VERSION_HEX < 0x03050000
28 Py_EncodeLocale(const wchar_t *arg, size_t *size)
30 return _Py_wchar2char(arg, size);
33 Py_DecodeLocale(const char *arg, size_t *size)
35 return _Py_char2wchar(arg, size);
39 SALOME_CPythonHelper *SALOME_CPythonHelper::Singleton()
41 if(!_CPYTHONHELPER_INSTANCE)
42 _CPYTHONHELPER_INSTANCE = new SALOME_CPythonHelper;
43 return _CPYTHONHELPER_INSTANCE;
46 void SALOME_CPythonHelper::KillSingleton()
48 delete _CPYTHONHELPER_INSTANCE;
49 _CPYTHONHELPER_INSTANCE = nullptr;
52 void SALOME_CPythonHelper::initializePython(int argc, char *argv[])
55 #if PY_VERSION_HEX < 0x03070000
58 wchar_t **changed_argv = new wchar_t*[argc]; // Setting arguments
59 for (int i = 0; i < argc; i++)
60 changed_argv[i] = Py_DecodeLocale(argv[i], NULL);
61 PySys_SetArgv(argc, changed_argv);
62 PyObject *mainmod(PyImport_AddModule("__main__"));
63 _globals=PyModule_GetDict(mainmod);
64 if(PyDict_GetItemString(_globals, "__builtins__") == NULL)
66 PyObject *bimod(PyImport_ImportModule("__builtin__"));
67 if (bimod == NULL || PyDict_SetItemString(_globals, "__builtins__", bimod) != 0)
68 Py_FatalError("can't add __builtins__ to __main__");
72 PyObject *tmp(PyList_New(0));
73 _pickler=PyImport_ImportModuleLevel(const_cast<char *>("pickle"),_globals,_locals,tmp,0);
74 _subprocess=PyImport_ImportModuleLevel(const_cast<char *>("subprocess"),_globals,_locals,tmp,0);
75 PyObject *socket(PyImport_ImportModuleLevel(const_cast<char *>("socket"),_globals,_locals,tmp,0));
76 PyDict_SetItemString(_globals,"sp",_subprocess);
77 PyDict_SetItemString(_globals,"socket",socket);
80 void SALOME_CPythonHelper::allowPythonCallsFromDifferentThread() const
82 #if PY_VERSION_HEX < 0x03070000
83 PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
85 PyEval_SaveThread(); /* Release the thread state */
88 void SALOME_CPythonHelper::registerToSalomePiDict(const std::string& processName, long pid) const
91 PyObject *mod(PyImport_ImportModule("addToKillList"));//new value
94 PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));//new value
96 { Py_XDECREF(mod); return ; }
97 PyObject *args(PyTuple_New(2));
98 PyTuple_SetItem(args,0,PyLong_FromLong(pid));
99 PyTuple_SetItem(args,1,PyUnicode_FromString(processName.c_str()));
100 PyObject *res(PyObject_CallObject(meth,args));
107 std::vector<long> SALOME_CPythonHelper::evalVL(const std::string& pyCode) const
110 PyObject* code(Py_CompileString(pyCode.c_str(),"evalVL.py", Py_eval_input));
111 PyObject *res(PyEval_EvalCode( code, _globals, _locals));
113 Py_ssize_t n(PyList_Size(res));
114 std::vector<long> ret(n);
115 for(auto i = 0; i<n; ++i)
117 PyObject *elt(PyList_GetItem(res,i));//borrowed
118 ret[i]=PyLong_AsLong(elt);
124 std::string SALOME_CPythonHelper::evalS(const std::string& pyCode) const
127 PyObject* code(Py_CompileString(pyCode.c_str(),"evalS.py", Py_eval_input));
128 PyObject *res(PyEval_EvalCode( code, _globals, _locals));
130 std::string ret(PyUnicode_AsUTF8(res));
136 SALOME_CPythonHelper::~SALOME_CPythonHelper()
138 // _globals is borrowed ref -> do nothing
140 /*if(_locals){ auto refcount_locals = Py_REFCNT(_locals); }*/
143 Py_XDECREF(_pickler);