1 // Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : PyInterp_Interp.cxx
23 // Author : Christian CAREMOLI, Paul RASCLE, Adrien BRUNETON
25 #include "PyInterp_Interp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
26 #include "PyInterp_Utils.h"
29 //#include <cStringIO.h>
30 #include <structmember.h>
39 #include <QStringList>
41 #define TOP_HISTORY_PY "--- top of history ---"
42 #define BEGIN_HISTORY_PY "--- begin of history ---"
45 The following functions are used to hook the Python
50 PyStdOut_dealloc(PyStdOut *self)
56 PyStdOut_write(PyStdOut *self, PyObject *args)
59 if (!PyArg_ParseTuple(args, "s",&c))
68 self->_cb(self->_data,c);
75 PyStdOut_flush(PyStdOut * /*self*/, PyObject * /*args*/)
81 static PyMethodDef PyStdOut_methods[] = {
82 {"write", (PyCFunction)PyStdOut_write, METH_VARARGS, PyDoc_STR("write(string) -> None")},
83 {"flush", (PyCFunction)PyStdOut_flush, METH_NOARGS, PyDoc_STR("flush() -> None")},
84 {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
87 static PyMemberDef PyStdOut_memberlist[] = {
88 {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0,
89 (char*)"flag indicating that a space needs to be printed; used by print"},
90 {NULL, 0, 0, 0, NULL} /* Sentinel */
93 static PyTypeObject PyStdOut_Type = {
94 /* The ob_type field must be initialized in the module init function
95 * to be portable to Windows without using C++. */
96 PyVarObject_HEAD_INIT(NULL, 0)
99 sizeof(PyStdOut), /*tp_basicsize*/
102 (destructor)PyStdOut_dealloc, /*tp_dealloc*/
109 0, /*tp_as_sequence*/
114 PyObject_GenericGetAttr, /*tp_getattro*/
115 /* softspace is writable: we must supply tp_setattro */
116 PyObject_GenericSetAttr, /* tp_setattro */
118 Py_TPFLAGS_DEFAULT, /*tp_flags*/
122 0, /*tp_richcompare*/
123 0, /*tp_weaklistoffset*/
126 PyStdOut_methods, /*tp_methods*/
127 PyStdOut_memberlist, /*tp_members*/
145 0, /*tp_version_tag*/
147 #if PY_VERSION_HEX >= 0x03080000
149 #if PY_VERSION_HEX < 0x03090000
155 #define PyStdOut_Check(v) ((v)->ob_type == &PyStdOut_Type)
157 static PyStdOut* newPyStdOut( bool iscerr )
160 self = PyObject_New(PyStdOut, &PyStdOut_Type);
165 self->_iscerr = iscerr;
170 \class PyInterp_Interp
171 \brief Generic embedded Python interpreter.
174 int PyInterp_Interp::_argc = 1;
175 char* PyInterp_Interp::_argv[] = {(char*)""};
178 \brief Basic constructor.
180 After construction the interpreter instance successor classes
181 must call virtual method initalize().
183 PyInterp_Interp::PyInterp_Interp():
184 _vout(0), _verr(0), _global_context(0), _local_context(0), _initialized(false)
191 PyInterp_Interp::~PyInterp_Interp()
197 \brief Initialize embedded interpreter.
199 This method shoud be called after construction of the interpreter.
200 The method initialize() calls virtuals methods
201 - initPython() to initialize global Python interpreter
202 - initContext() to initialize interpreter internal context
203 - initRun() to prepare interpreter for running commands
204 which should be implemented in the successor classes, according to the
205 embedded Python interpreter policy (mono or multi interpreter, etc).
207 void PyInterp_Interp::initialize()
210 return; // prevent repeating intitialization
214 _history.clear(); // start a new list of user's commands
215 _ith = _history.begin();
217 initPython(); // This also inits the multi-threading for Python (but w/o acquiring GIL)
219 // ---- The rest of the initialisation process is done hodling the GIL
224 // used to interpret & compile commands - this is really imported here
225 // and only added again (with PyImport_AddModule) later on
226 PyObjWrapper m(PyImport_ImportModule("codeop"));
232 // Create python objects to capture stdout and stderr
233 _vout=(PyObject*)newPyStdOut( false ); // stdout
234 _verr=(PyObject*)newPyStdOut( true ); // stderr
236 // All the initRun outputs are redirected to the standard output (console)
240 void PyInterp_Interp::destroy()
247 \brief Initialize Python interpreter.
249 In case if Python is not initialized, it sets program name, initializes the single true Python
250 interpreter, sets program arguments, and initializes threads.
251 Otherwise, does nothing. This is important for light SALOME configuration,
252 as in full SALOME this is done at SalomeApp level.
253 \sa SalomeApp_PyInterp class and main() in SALOME_Session_Server
255 void PyInterp_Interp::initPython()
257 if (!Py_IsInitialized()){
258 // Python is not initialized
259 wchar_t **changed_argv = new wchar_t*[_argc]; // Setting arguments
260 for (int i = 0; i < _argc; i++)
262 changed_argv[i] = Py_DecodeLocale(_argv[i], NULL);
265 Py_SetProgramName(changed_argv[0]);
266 Py_Initialize(); // Initialize the interpreter
267 PySys_SetArgv(_argc, changed_argv);
269 PyEval_InitThreads(); // Create (and acquire) the Python global interpreter lock (GIL)
270 PyEval_SaveThread(); // release safely GIL
275 \brief Get embedded Python interpreter banner.
276 \return banner string
278 std::string PyInterp_Interp::getBanner() const
281 std::string aBanner("Python ");
282 aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
283 aBanner = aBanner + "\ntype help to get general information on environment\n";
288 \brief Initialize run command.
290 This method is used to prepare interpreter for running
293 \return \c true on success and \c false on error
295 bool PyInterp_Interp::initRun()
301 * Initialize context dictionaries. GIL is held already.
302 * The code executed in an embedded interpreter is expected to be run at the module
303 * level, in which case local and global context have to be the same dictionary.
304 * See: http://stackoverflow.com/questions/12265756/c-python-running-python-code-within-a-context
305 * for an explanation.
307 bool PyInterp_Interp::initContext()
309 PyObject *m = PyImport_AddModule("__main__"); // interpreter main module (module context)
314 _global_context = PyModule_GetDict(m); // get interpreter global variable context
315 Py_INCREF(_global_context);
316 _local_context = _global_context;
322 * Destroy context dictionaries. GIL is held already.
324 void PyInterp_Interp::closeContext()
326 Py_XDECREF(_global_context);
327 // both _global_context and _local_context may point to the same Python object
328 if ( _global_context != _local_context)
329 Py_XDECREF(_local_context);
333 \brief Compile Python command and evaluate it in the
334 python dictionary contexts if possible. This is not thread-safe.
335 This is the caller's responsability to make this thread-safe.
337 \param command Python command string
338 \return -1 on fatal error, 1 if command is incomplete and 0
339 if command is executed successfully
341 static int run_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
343 PyObject *m = PyImport_AddModule("codeop");
345 // Fatal error. No way to go on.
350 PyObjWrapper v(PyObject_CallMethod(m,(char*)"compile_command",(char*)"s",command));
352 // Error encountered. It should be SyntaxError,
353 //so we don't write out traceback
354 PyObjWrapper exception, value, tb;
355 PyErr_Fetch(&exception, &value, &tb);
356 PyErr_NormalizeException(&exception, &value, &tb);
357 PyErr_Display(exception, value, NULL);
360 else if (v == Py_None) {
361 // Incomplete text we return 1 : we need a complete text to execute
365 PyObjWrapper r(PyEval_EvalCode((PyObject *)(void *)v,global_ctxt, local_ctxt));
367 // Execution error. We return -1
371 // The command has been successfully executed. Return 0
376 void replaceAll(std::string& str, const std::string& from, const std::string& to) {
379 size_t start_pos = 0;
380 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
381 str.replace(start_pos, from.length(), to);
382 start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
386 std::vector<std::string>
387 __split(const std::string& str, char delimiter)
389 std::vector<std::string> internal;
390 std::stringstream ss(str); // Turn the string into a stream.
393 while (getline(ss, tok, delimiter)) {
394 internal.push_back(tok);
401 __join(const std::vector<std::string>& v, int begin=0, int end=-1)
404 end = (int)v.size(); //!< TODO: conversion from size_t to int
405 std::stringstream ss;
406 for (int i = begin; i < end; ++i) {
414 std::vector<std::string>
415 __getArgsList(std::string argsString)
417 // Special process if some items of 'args:' list are themselves lists
418 // Note that an item can be a list, but not a list of lists...
419 // So we can have something like this:
420 // myscript.py args:[\'file1\',\'file2\'],\'val1\',\"done\",[1,2,3],[True,False],\"ok\",kwarg1=\'kwarg1\',kwarg2=\'kwarg2\',\'fin\'
421 // With such a call, argsString variable contains the string representing ['file1','file2'],'val1','done',[1,2,3],[True,False],'ok',kwarg1='kwarg1',kwarg2='kwarg2','fin'
422 // We have to split argsString to obtain a 9 string elements list
423 std::vector<std::string> x = __split(argsString, ',');
424 bool containsList = (argsString.find('[') != std::string::npos);
426 std::vector<int> listBeginIndices, listEndIndices;
427 for (int pos = 0; pos < (int)x.size(); ++pos) {
428 if (x[pos][0] == '[')
429 listBeginIndices.push_back(pos);
430 else if (x[pos][x[pos].size()-1] == ']')
431 listEndIndices.push_back(pos);
433 std::vector<std::string> extractedArgs;
435 for (int pos = 0; pos < (int)listBeginIndices.size(); ++pos) {
436 int lbeg = listBeginIndices[pos];
437 int lend = listEndIndices[pos];
439 for (int k = start; k < lbeg; ++k)
440 extractedArgs.push_back(x[k]);
441 extractedArgs.push_back(__join(x, lbeg, lend+1));
444 if (start < (int)x.size())
445 for (int k = start; k < (int)x.size(); ++k)
446 extractedArgs.push_back(x[k]);
447 return extractedArgs;
455 \brief Compile Python command and evaluate it in the
456 python dictionary context if possible. Command might correspond to
457 the execution of a script with optional arguments.
458 In this case, command is:
459 exec(open(r"/absolute/path/to/script.py", "rb").read(), args=(arg1,...,argn))
460 and args parameter is optional one. This parameter is specified as a tuple of strings.
462 \param command Python command string
463 \param context Python context (dictionary)
464 \return -1 on fatal error, 1 if command is incomplete and 0
465 if command is executed successfully
467 static int compile_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
469 // First guess if command is execution of a script with args, or a simple Python command
470 QString singleCommand = command;
471 QString commandArgs = "";
473 QRegExp rx("exec\\s*\\(.*open\\s*\\(\\s*(.*)\\s*\\)\\s*\\.\\s*read\\s*\\(\\)(\\s*,\\s*args\\s*=\\s*\\(.*\\))\\s*\\)");
474 if (rx.indexIn(command) != -1) {
475 commandArgs = rx.cap(2).remove(0, rx.cap(2).indexOf("(")); // arguments of command
476 commandArgs.insert(commandArgs.indexOf('(')+1, rx.cap(1).split(",")[0].trimmed() + ","); // prepend arguments list by the script file itself
477 singleCommand = singleCommand.remove(rx.pos(2), rx.cap(2).size()); // command for execution without arguments
480 if (commandArgs.isEmpty()) {
481 return run_command(singleCommand.toStdString().c_str(), global_ctxt, local_ctxt);
484 ///////////////std::vector<std::string> argList = __getArgsList(commandArgs);
485 QString preCommandBegin = "import sys; save_argv = sys.argv; sys.argv=list(";
486 QString preCommandEnd = ");";
487 QString postCommand = ";sys.argv=save_argv";
488 QString completeCommand = preCommandBegin+commandArgs+preCommandEnd+singleCommand.trimmed()+postCommand;
489 return run_command(completeCommand.toStdString().c_str(), global_ctxt, local_ctxt);
494 \brief Run Python command - the command has to fit on a single line (no \n!).
495 Use ';' if you need multiple statements evaluated at once.
496 \param command Python command
497 \return command status
499 int PyInterp_Interp::run(const char *command)
502 int ret = simpleRun(command);
508 * Called before a command is run (when calling run() method). Not thread-safe. Caller's responsability
509 * to acquire GIL if needed.
511 int PyInterp_Interp::beforeRun()
517 * Called after a command is run (when calling run() method). Not thread-safe. Caller's responsability
518 * to acquire GIL if needed.
520 int PyInterp_Interp::afterRun()
526 \brief Run Python command (used internally). Not thread-safe. GIL acquisition is caller's responsability.
527 \param command Python command
528 \param addToHistory if \c true (default), the command is added to the commands history
529 \return command status
531 int PyInterp_Interp::simpleRun(const char *command, const bool addToHistory)
533 if( addToHistory && strcmp(command,"") != 0 ) {
534 _history.push_back(command);
535 _ith = _history.end();
538 // Current stdout and stderr are saved
539 PyObject * oldOut = PySys_GetObject((char*)"stdout");
540 PyObject * oldErr = PySys_GetObject((char*)"stderr");
541 // Keep them alive (PySys_GetObject returned a *borrowed* ref!)
545 // Redirect outputs to SALOME Python console before treatment
546 PySys_SetObject((char*)"stderr",_verr);
547 PySys_SetObject((char*)"stdout",_vout);
549 int ier = compile_command(command, _global_context, _local_context);
551 // Outputs are redirected to what they were before
552 PySys_SetObject((char*)"stdout",oldOut);
553 PySys_SetObject((char*)"stderr",oldErr);
559 \brief Get previous command in the commands history.
560 \return previous command
562 const char * PyInterp_Interp::getPrevious()
564 if(_ith != _history.begin()){
566 return (*_ith).c_str();
569 return BEGIN_HISTORY_PY;
573 \brief Get next command in the commands history.
576 const char * PyInterp_Interp::getNext()
578 if(_ith != _history.end()){
581 if (_ith == _history.end())
582 return TOP_HISTORY_PY;
584 return (*_ith).c_str();
588 \brief Set Python standard output device hook.
589 \param cb callback function
590 \param data callback function parameters
592 void PyInterp_Interp::setvoutcb(PyOutChanged* cb, void* data)
594 ((PyStdOut*)_vout)->_cb=cb;
595 ((PyStdOut*)_vout)->_data=data;
599 \brief Set Python standard error device hook.
600 \param cb callback function
601 \param data callback function parameters
603 void PyInterp_Interp::setverrcb(PyOutChanged* cb, void* data)
605 ((PyStdOut*)_verr)->_cb=cb;
606 ((PyStdOut*)_verr)->_data=data;
610 \bried Check if the interpreter is initialized
613 bool PyInterp_Interp::initialized() const