1 // Copyright (C) 2007-2016 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>
40 #define TOP_HISTORY_PY "--- top of history ---"
41 #define BEGIN_HISTORY_PY "--- begin of history ---"
44 The following functions are used to hook the Python
49 PyStdOut_dealloc(PyStdOut *self)
55 PyStdOut_write(PyStdOut *self, PyObject *args)
58 if (!PyArg_ParseTuple(args, "s",&c))
67 self->_cb(self->_data,c);
74 PyStdOut_flush(PyStdOut *self)
80 static PyMethodDef PyStdOut_methods[] = {
81 {"write", (PyCFunction)PyStdOut_write, METH_VARARGS, PyDoc_STR("write(string) -> None")},
82 {"flush", (PyCFunction)PyStdOut_flush, METH_NOARGS, PyDoc_STR("flush() -> None")},
83 {NULL, NULL} /* sentinel */
86 static PyMemberDef PyStdOut_memberlist[] = {
87 {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0,
88 (char*)"flag indicating that a space needs to be printed; used by print"},
92 static PyTypeObject PyStdOut_Type = {
93 /* The ob_type field must be initialized in the module init function
94 * to be portable to Windows without using C++. */
95 PyVarObject_HEAD_INIT(NULL, 0)
98 sizeof(PyStdOut), /*tp_basicsize*/
101 (destructor)PyStdOut_dealloc, /*tp_dealloc*/
108 0, /*tp_as_sequence*/
113 PyObject_GenericGetAttr, /*tp_getattro*/
114 /* softspace is writable: we must supply tp_setattro */
115 PyObject_GenericSetAttr, /* tp_setattro */
117 Py_TPFLAGS_DEFAULT, /*tp_flags*/
121 0, /*tp_richcompare*/
122 0, /*tp_weaklistoffset*/
125 PyStdOut_methods, /*tp_methods*/
126 PyStdOut_memberlist, /*tp_members*/
144 0, /*tp_version_tag*/
148 #define PyStdOut_Check(v) ((v)->ob_type == &PyStdOut_Type)
150 static PyStdOut* newPyStdOut( bool iscerr )
153 self = PyObject_New(PyStdOut, &PyStdOut_Type);
158 self->_iscerr = iscerr;
163 \class PyInterp_Interp
164 \brief Generic embedded Python interpreter.
167 int PyInterp_Interp::_argc = 1;
168 char* PyInterp_Interp::_argv[] = {(char*)""};
171 \brief Basic constructor.
173 After construction the interpreter instance successor classes
174 must call virtual method initalize().
176 PyInterp_Interp::PyInterp_Interp():
177 _vout(0), _verr(0), _global_context(0), _local_context(0), _initialized(false)
184 PyInterp_Interp::~PyInterp_Interp()
190 \brief Initialize embedded interpreter.
192 This method shoud be called after construction of the interpreter.
193 The method initialize() calls virtuals methods
194 - initPython() to initialize global Python interpreter
195 - initContext() to initialize interpreter internal context
196 - initRun() to prepare interpreter for running commands
197 which should be implemented in the successor classes, according to the
198 embedded Python interpreter policy (mono or multi interpreter, etc).
200 void PyInterp_Interp::initialize()
203 return; // prevent repeating intitialization
207 _history.clear(); // start a new list of user's commands
208 _ith = _history.begin();
210 initPython(); // This also inits the multi-threading for Python (but w/o acquiring GIL)
212 // ---- The rest of the initialisation process is done hodling the GIL
217 // used to interpret & compile commands - this is really imported here
218 // and only added again (with PyImport_AddModule) later on
219 PyObjWrapper m(PyImport_ImportModule("codeop"));
225 // Create python objects to capture stdout and stderr
226 _vout=(PyObject*)newPyStdOut( false ); // stdout
227 _verr=(PyObject*)newPyStdOut( true ); // stderr
229 // All the initRun outputs are redirected to the standard output (console)
233 void PyInterp_Interp::destroy()
240 \brief Initialize Python interpreter.
242 In case if Python is not initialized, it sets program name, initializes the single true Python
243 interpreter, sets program arguments, and initializes threads.
244 Otherwise, does nothing. This is important for light SALOME configuration,
245 as in full SALOME this is done at SalomeApp level.
246 \sa SalomeApp_PyInterp class and main() in SALOME_Session_Server
248 void PyInterp_Interp::initPython()
250 if (!Py_IsInitialized()){
251 // Python is not initialized
252 wchar_t **changed_argv = new wchar_t*[_argc]; // Setting arguments
253 for (int i = 0; i < _argc; i++)
255 changed_argv[i] = Py_DecodeLocale(_argv[i], NULL);
258 Py_SetProgramName(changed_argv[0]);
259 Py_Initialize(); // Initialize the interpreter
260 PySys_SetArgv(_argc, changed_argv);
262 PyEval_InitThreads(); // Create (and acquire) the Python global interpreter lock (GIL)
263 PyEval_SaveThread(); // release safely GIL
268 \brief Get embedded Python interpreter banner.
269 \return banner string
271 std::string PyInterp_Interp::getBanner() const
274 std::string aBanner("Python ");
275 aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
276 aBanner = aBanner + "\ntype help to get general information on environment\n";
281 \brief Initialize run command.
283 This method is used to prepare interpreter for running
286 \return \c true on success and \c false on error
288 bool PyInterp_Interp::initRun()
294 * Initialize context dictionaries. GIL is held already.
295 * The code executed in an embedded interpreter is expected to be run at the module
296 * level, in which case local and global context have to be the same dictionary.
297 * See: http://stackoverflow.com/questions/12265756/c-python-running-python-code-within-a-context
298 * for an explanation.
300 bool PyInterp_Interp::initContext()
302 PyObject *m = PyImport_AddModule("__main__"); // interpreter main module (module context)
307 _global_context = PyModule_GetDict(m); // get interpreter global variable context
308 Py_INCREF(_global_context);
309 _local_context = _global_context;
315 * Destroy context dictionaries. GIL is held already.
317 void PyInterp_Interp::closeContext()
319 Py_XDECREF(_global_context);
320 // both _global_context and _local_context may point to the same Python object
321 if ( _global_context != _local_context)
322 Py_XDECREF(_local_context);
326 \brief Compile Python command and evaluate it in the
327 python dictionary contexts if possible. This is not thread-safe.
328 This is the caller's responsability to make this thread-safe.
330 \param command Python command string
331 \return -1 on fatal error, 1 if command is incomplete and 0
332 if command is executed successfully
334 static int run_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
336 PyObject *m = PyImport_AddModule("codeop");
338 // Fatal error. No way to go on.
343 PyObjWrapper v(PyObject_CallMethod(m,(char*)"compile_command",(char*)"s",command));
345 // Error encountered. It should be SyntaxError,
346 //so we don't write out traceback
347 PyObjWrapper exception, value, tb;
348 PyErr_Fetch(&exception, &value, &tb);
349 PyErr_NormalizeException(&exception, &value, &tb);
350 PyErr_Display(exception, value, NULL);
353 else if (v == Py_None) {
354 // Incomplete text we return 1 : we need a complete text to execute
358 PyObjWrapper r(PyEval_EvalCode((PyObject *)(void *)v,global_ctxt, local_ctxt));
360 // Execution error. We return -1
364 // The command has been successfully executed. Return 0
369 void replaceAll(std::string& str, const std::string& from, const std::string& to) {
372 size_t start_pos = 0;
373 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
374 str.replace(start_pos, from.length(), to);
375 start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
379 std::vector<std::string>
380 __split(const std::string& str, char delimiter)
382 std::vector<std::string> internal;
383 std::stringstream ss(str); // Turn the string into a stream.
386 while (getline(ss, tok, delimiter)) {
387 internal.push_back(tok);
394 __join(const std::vector<std::string>& v, int begin=0, int end=-1)
398 std::stringstream ss;
399 for (int i = begin; i < end; ++i) {
407 std::vector<std::string>
408 __getArgsList(std::string argsString)
410 // Special process if some items of 'args:' list are themselves lists
411 // Note that an item can be a list, but not a list of lists...
412 // So we can have something like this:
413 // myscript.py args:[\'file1\',\'file2\'],\'val1\',\"done\",[1,2,3],[True,False],\"ok\",kwarg1=\'kwarg1\',kwarg2=\'kwarg2\',\'fin\'
414 // 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'
415 // We have to split argsString to obtain a 9 string elements list
416 std::vector<std::string> x = __split(argsString, ',');
417 bool containsList = (argsString.find('[') != std::string::npos);
419 std::vector<int> listBeginIndices, listEndIndices;
420 for (int pos = 0; pos < (int)x.size(); ++pos) {
421 if (x[pos][0] == '[')
422 listBeginIndices.push_back(pos);
423 else if (x[pos][x[pos].size()-1] == ']')
424 listEndIndices.push_back(pos);
426 std::vector<std::string> extractedArgs;
428 for (int pos = 0; pos < (int)listBeginIndices.size(); ++pos) {
429 int lbeg = listBeginIndices[pos];
430 int lend = listEndIndices[pos];
432 for (int k = start; k < lbeg; ++k)
433 extractedArgs.push_back(x[k]);
434 extractedArgs.push_back(__join(x, lbeg, lend+1));
437 if (start < (int)x.size())
438 for (int k = start; k < (int)x.size(); ++k)
439 extractedArgs.push_back(x[k]);
440 return extractedArgs;
448 \brief Compile Python command and evaluate it in the
449 python dictionary context if possible. Command might correspond to
450 the execution of a script with optional arguments.
451 In this case, command is:
452 execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
454 \param command Python command string
455 \param context Python context (dictionary)
456 \return -1 on fatal error, 1 if command is incomplete and 0
457 if command is executed successfully
459 static int compile_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
461 // First guess if command is execution of a script with args, or a simple Python command
462 std::string singleCommand = command;
463 std::string commandArgs = "";
465 QRegExp rx("execfile\\s*\\(.*(args:.*)\"\\s*\\)");
466 if (rx.indexIn(command) != -1) {
467 commandArgs = rx.cap(1).remove(0,5).toStdString(); // arguments of command
468 singleCommand = rx.cap().remove(rx.cap(1)).remove(" ").toStdString(); // command for execution without arguments
471 if (commandArgs.empty()) {
472 // process command: expression
473 // process command: execfile(r"/absolute/path/to/script.py") (no args)
474 return run_command(singleCommand.c_str(), global_ctxt, local_ctxt);
477 // process command: execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
478 std::string script = singleCommand.substr(11); // remove leading execfile(r"
479 script = script.substr(0, script.length()-2); // remove trailing ")
480 std::vector<std::string> argList = __getArgsList(commandArgs);
482 std::string preCommandBegin = "import sys; save_argv = sys.argv; sys.argv=[";
483 std::string preCommandEnd = "];";
484 std::string completeCommand = preCommandBegin+"\""+script+"\",";
485 for (std::vector<std::string>::iterator itr = argList.begin(); itr != argList.end(); ++itr) {
486 if (itr != argList.begin())
487 completeCommand += ",";
488 completeCommand = completeCommand + "\"" + *itr + "\"";
490 completeCommand = completeCommand+preCommandEnd+singleCommand+";sys.argv=save_argv";
491 return run_command(completeCommand.c_str(), global_ctxt, local_ctxt);
496 \brief Run Python command - the command has to fit on a single line (no \n!).
497 Use ';' if you need multiple statements evaluated at once.
498 \param command Python command
499 \return command status
501 int PyInterp_Interp::run(const char *command)
504 int ret = simpleRun(command);
510 * Called before a command is run (when calling run() method). Not thread-safe. Caller's responsability
511 * to acquire GIL if needed.
513 int PyInterp_Interp::beforeRun()
519 * Called after a command is run (when calling run() method). Not thread-safe. Caller's responsability
520 * to acquire GIL if needed.
522 int PyInterp_Interp::afterRun()
528 \brief Run Python command (used internally). Not thread-safe. GIL acquisition is caller's responsability.
529 \param command Python command
530 \param addToHistory if \c true (default), the command is added to the commands history
531 \return command status
533 int PyInterp_Interp::simpleRun(const char *command, const bool addToHistory)
535 if( addToHistory && strcmp(command,"") != 0 ) {
536 _history.push_back(command);
537 _ith = _history.end();
540 // Current stdout and stderr are saved
541 PyObject * oldOut = PySys_GetObject((char*)"stdout");
542 PyObject * oldErr = PySys_GetObject((char*)"stderr");
543 // Keep them alive (PySys_GetObject returned a *borrowed* ref!)
547 // Redirect outputs to SALOME Python console before treatment
548 PySys_SetObject((char*)"stderr",_verr);
549 PySys_SetObject((char*)"stdout",_vout);
551 int ier = compile_command(command, _global_context, _local_context);
553 // Outputs are redirected to what they were before
554 PySys_SetObject((char*)"stdout",oldOut);
555 PySys_SetObject((char*)"stderr",oldErr);
561 \brief Get previous command in the commands history.
562 \return previous command
564 const char * PyInterp_Interp::getPrevious()
566 if(_ith != _history.begin()){
568 return (*_ith).c_str();
571 return BEGIN_HISTORY_PY;
575 \brief Get next command in the commands history.
578 const char * PyInterp_Interp::getNext()
580 if(_ith != _history.end()){
583 if (_ith == _history.end())
584 return TOP_HISTORY_PY;
586 return (*_ith).c_str();
590 \brief Set Python standard output device hook.
591 \param cb callback function
592 \param data callback function parameters
594 void PyInterp_Interp::setvoutcb(PyOutChanged* cb, void* data)
596 ((PyStdOut*)_vout)->_cb=cb;
597 ((PyStdOut*)_vout)->_data=data;
601 \brief Set Python standard error device hook.
602 \param cb callback function
603 \param data callback function parameters
605 void PyInterp_Interp::setverrcb(PyOutChanged* cb, void* data)
607 ((PyStdOut*)_verr)->_cb=cb;
608 ((PyStdOut*)_verr)->_data=data;
612 \bried Check if the interpreter is initialized
615 bool PyInterp_Interp::initialized() const