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
23 // File : PyInterp_Interp.cxx
24 // Author : Christian CAREMOLI, Paul RASCLE, Adrien BRUNETON
27 #include "PyInterp_Interp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
28 #include "PyInterp_Utils.h"
31 #include <cStringIO.h>
32 #include <structmember.h>
43 #define TOP_HISTORY_PY "--- top of history ---"
44 #define BEGIN_HISTORY_PY "--- begin of history ---"
47 The following functions are used to hook the Python
52 PyStdOut_dealloc(PyStdOut *self)
58 PyStdOut_write(PyStdOut *self, PyObject *args)
62 if (!PyArg_ParseTuple(args, "t#:write",&c, &l))
71 self->_cb(self->_data,c);
78 PyStdOut_flush(PyStdOut *self)
84 static PyMethodDef PyStdOut_methods[] = {
85 {"write", (PyCFunction)PyStdOut_write, METH_VARARGS, PyDoc_STR("write(string) -> None")},
86 {"flush", (PyCFunction)PyStdOut_flush, METH_NOARGS, PyDoc_STR("flush() -> None")},
87 {NULL, NULL} /* sentinel */
90 static PyMemberDef PyStdOut_memberlist[] = {
91 {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0,
92 (char*)"flag indicating that a space needs to be printed; used by print"},
96 static PyTypeObject PyStdOut_Type = {
97 /* The ob_type field must be initialized in the module init function
98 * to be portable to Windows without using C++. */
99 PyObject_HEAD_INIT(NULL)
102 sizeof(PyStdOut), /*tp_basicsize*/
105 (destructor)PyStdOut_dealloc, /*tp_dealloc*/
112 0, /*tp_as_sequence*/
117 PyObject_GenericGetAttr, /*tp_getattro*/
118 /* softspace is writable: we must supply tp_setattro */
119 PyObject_GenericSetAttr, /* tp_setattro */
121 Py_TPFLAGS_DEFAULT, /*tp_flags*/
125 0, /*tp_richcompare*/
126 0, /*tp_weaklistoffset*/
129 PyStdOut_methods, /*tp_methods*/
130 PyStdOut_memberlist, /*tp_members*/
144 #define PyStdOut_Check(v) ((v)->ob_type == &PyStdOut_Type)
146 static PyStdOut* newPyStdOut( bool iscerr )
149 self = PyObject_New(PyStdOut, &PyStdOut_Type);
154 self->_iscerr = iscerr;
159 \class PyInterp_Interp
160 \brief Generic embedded Python interpreter.
163 int PyInterp_Interp::_argc = 1;
164 char* PyInterp_Interp::_argv[] = {(char*)""};
167 \brief Basic constructor.
169 After construction the interpreter instance successor classes
170 must call virtual method initalize().
172 PyInterp_Interp::PyInterp_Interp():
173 _vout(0), _verr(0), _local_context(0), _global_context(0)
182 PyInterp_Interp::~PyInterp_Interp()
188 \brief Initialize embedded interpreter.
190 This method shoud be called after construction of the interpreter.
191 The method initialize() calls virtuals methods
192 - initPython() to initialize global Python interpreter
193 - initContext() to initialize interpreter internal context
194 - initRun() to prepare interpreter for running commands
195 which should be implemented in the successor classes, according to the
196 embedded Python interpreter policy (mono or multi interpreter, etc).
198 void PyInterp_Interp::initialize()
200 _history.clear(); // start a new list of user's commands
201 _ith = _history.begin();
203 initPython(); // This also inits the multi-threading for Python (but w/o acquiring GIL)
205 //initState(); // [ABN] OBSOLETE
207 // ---- The rest of the initialisation process is done hodling the GIL
212 // used to interpret & compile commands - this is really imported here
213 // and only added again (with PyImport_AddModule) later on
214 PyObjWrapper m(PyImport_ImportModule("codeop"));
220 // Create python objects to capture stdout and stderr
221 _vout=(PyObject*)newPyStdOut( false ); // stdout
222 _verr=(PyObject*)newPyStdOut( true ); // stderr
224 // All the initRun outputs are redirected to the standard output (console)
228 void PyInterp_Interp::destroy()
235 \brief Initialize Python interpreter.
237 In case if Python is not initialized, it sets program name, initializes the single true Python
238 interpreter, sets program arguments, and initializes threads.
239 Otherwise, does nothing. This is important for light SALOME configuration,
240 as in full SALOME this is done at SalomeApp level.
241 \sa SalomeApp_PyInterp class and main() in SALOME_Session_Server
243 void PyInterp_Interp::initPython()
245 if (!Py_IsInitialized()){
246 // Python is not initialized
247 Py_SetProgramName(_argv[0]);
248 Py_Initialize(); // Initialize the interpreter
249 PySys_SetArgv(_argc, _argv);
251 PyEval_InitThreads(); // Create (and acquire) the Python global interpreter lock (GIL)
252 PyEval_ReleaseLock();
257 \brief Get embedded Python interpreter banner.
258 \return banner string
260 std::string PyInterp_Interp::getbanner() const
263 std::string aBanner("Python ");
264 aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
265 aBanner = aBanner + "\ntype help to get general information on environment\n";
270 \brief Initialize run command.
272 This method is used to prepare interpreter for running
275 \return \c true on success and \c false on error
277 bool PyInterp_Interp::initRun()
283 * Initialize context dictionaries. GIL is held already.
284 * The code executed in an embedded interpreter is expected to be run at the module
285 * level, in which case local and global context have to be the same dictionary.
286 * See: http://stackoverflow.com/questions/12265756/c-python-running-python-code-within-a-context
287 * for an explanation.
289 bool PyInterp_Interp::initContext()
291 PyObject *m = PyImport_AddModule("__main__"); // interpreter main module (module context)
296 _global_context = PyModule_GetDict(m); // get interpreter global variable context
297 Py_INCREF(_global_context);
298 _local_context = _global_context;
300 int ret = PyRun_SimpleString("import salome_iapp;salome_iapp.IN_SALOME_GUI=True");
306 * Destroy context dictionaries. GIL is held already.
308 void PyInterp_Interp::closeContext()
310 Py_XDECREF(_global_context);
311 // both _global and _local point to the same Python object:
312 // Py_XDECREF(_local_context);
316 \brief Compile Python command and evaluate it in the
317 python dictionary contexts if possible. This is not thread-safe.
318 This is the caller's responsability to make this thread-safe.
320 \param command Python command string
321 \return -1 on fatal error, 1 if command is incomplete and 0
322 if command is executed successfully
324 static int run_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
326 PyObject *m = PyImport_AddModule("codeop");
327 if(!m) { // Fatal error. No way to go on.
332 // PyObjWrapper v(Py_CompileString(command, "<salome_input>", Py_file_input));
333 PyObjWrapper v(PyObject_CallMethod(m,(char*)"compile_command",(char*)"s",command));
335 // Error encountered. It should be SyntaxError,
336 //so we don't write out traceback
337 PyObjWrapper exception, value, tb;
338 PyErr_Fetch(&exception, &value, &tb);
339 PyErr_NormalizeException(&exception, &value, &tb);
340 PyErr_Display(exception, value, NULL);
343 else if (v == Py_None) {
344 // Incomplete text we return 1 : we need a complete text to execute
348 PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,global_ctxt, local_ctxt));
350 // Execution error. We return -1
354 // The command has been successfully executed. Return 0
359 void replaceAll(std::string& str, const std::string& from, const std::string& to) {
362 size_t start_pos = 0;
363 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
364 str.replace(start_pos, from.length(), to);
365 start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
369 std::vector<std::string>
370 __split(const std::string& str, char delimiter)
372 std::vector<std::string> internal;
373 std::stringstream ss(str); // Turn the string into a stream.
376 while (getline(ss, tok, delimiter)) {
377 internal.push_back(tok);
384 __join(const std::vector<std::string>& v, int begin=0, int end=-1)
388 std::stringstream ss;
389 for (size_t i = begin; i < end; ++i) {
397 std::vector<std::string>
398 __getArgsList(std::string argsString)
400 // Special process if some items of 'args:' list are themselves lists
401 // Note that an item can be a list, but not a list of lists...
402 // So we can have something like this:
403 // myscript.py args:[\'file1\',\'file2\'],\'val1\',\"done\",[1,2,3],[True,False],\"ok\",kwarg1=\'kwarg1\',kwarg2=\'kwarg2\',\'fin\'
404 // 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'
405 // We have to split argsString to obtain a 9 string elements list
406 std::vector<std::string> x = __split(argsString, ',');
407 bool containsList = (argsString.find('[') != std::string::npos);
409 std::vector<int> listBeginIndices, listEndIndices;
410 for (int pos = 0; pos < x.size(); ++pos) {
411 if (x[pos][0] == '[')
412 listBeginIndices.push_back(pos);
413 else if (x[pos][x[pos].size()-1] == ']')
414 listEndIndices.push_back(pos);
416 std::vector<std::string> extractedArgs;
418 for (int pos = 0; pos < listBeginIndices.size(); ++pos) {
419 int lbeg = listBeginIndices[pos];
420 int lend = listEndIndices[pos];
422 for (int k = start; k < lbeg; ++k)
423 extractedArgs.push_back(x[k]);
424 extractedArgs.push_back(__join(x, lbeg, lend+1));
427 if (start < x.size())
428 for (int k = start; k < x.size(); ++k)
429 extractedArgs.push_back(x[k]);
430 return extractedArgs;
438 \brief Compile Python command and evaluate it in the
439 python dictionary context if possible. Command might correspond to
440 the execution of a script with optional arguments.
441 In this case, command is:
442 execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
444 \param command Python command string
445 \param context Python context (dictionary)
446 \return -1 on fatal error, 1 if command is incomplete and 0
447 if command is executed successfully
449 static int compile_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
451 // First guess if command is execution of a script with args, or a simple Python command
452 std::string singleCommand = command;
453 std::string commandArgs = "";
455 QRegExp rx("execfile\\s*\\(.*(args:.*)\"\\s*\\)");
456 if (rx.indexIn(command) != -1) {
457 commandArgs = rx.cap(1).remove(0,5).toStdString(); // arguments of command
458 singleCommand = rx.cap().remove(rx.cap(1)).remove(" ").toStdString(); // command for execution without arguments
461 if (commandArgs.empty()) {
462 // process command: expression
463 // process command: execfile(r"/absolute/path/to/script.py") (no args)
464 return run_command(singleCommand.c_str(), global_ctxt, local_ctxt);
467 // process command: execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
468 std::string script = singleCommand.substr(11); // remove leading execfile(r"
469 script = script.substr(0, script.length()-2); // remove trailing ")
470 std::vector<std::string> argList = __getArgsList(commandArgs);
472 std::string preCommandBegin = "import sys; save_argv = sys.argv; sys.argv=[";
473 std::string preCommandEnd = "];";
474 std::string completeCommand = preCommandBegin+"\""+script+"\",";
475 for (std::vector<std::string>::iterator itr = argList.begin(); itr != argList.end(); ++itr) {
476 if (itr != argList.begin())
477 completeCommand += ",";
478 completeCommand = completeCommand + "\"" + *itr + "\"";
480 completeCommand = completeCommand+preCommandEnd+singleCommand+";sys.argv=save_argv";
481 return run_command(completeCommand.c_str(), global_ctxt, local_ctxt);
486 \brief Run Python command - the command has to fit on a single line (no \n!).
487 Use ';' if you need multiple statements evaluated at once.
488 \param command Python command
489 \return command status
491 int PyInterp_Interp::run(const char *command)
494 int ret = simpleRun(command);
500 * Called before a command is run (when calling run() method). Not thread-safe. Caller's responsability
501 * to acquire GIL if needed.
503 int PyInterp_Interp::beforeRun()
509 * Called after a command is run (when calling run() method). Not thread-safe. Caller's responsability
510 * to acquire GIL if needed.
512 int PyInterp_Interp::afterRun()
518 \brief Run Python command (used internally). Not thread-safe. GIL acquisition is caller's responsability.
519 \param command Python command
520 \param addToHistory if \c true (default), the command is added to the commands history
521 \return command status
523 int PyInterp_Interp::simpleRun(const char *command, const bool addToHistory)
525 if( addToHistory && strcmp(command,"") != 0 ) {
526 _history.push_back(command);
527 _ith = _history.end();
530 // Current stdout and stderr are saved
531 PyObject * oldOut = PySys_GetObject((char*)"stdout");
532 PyObject * oldErr = PySys_GetObject((char*)"stderr");
533 // Keep them alive (PySys_GetObject returned a *borrowed* ref!)
537 // Redirect outputs to SALOME Python console before treatment
538 PySys_SetObject((char*)"stderr",_verr);
539 PySys_SetObject((char*)"stdout",_vout);
541 int ier = compile_command(command, _global_context, _local_context);
543 // Outputs are redirected to what they were before
544 PySys_SetObject((char*)"stdout",oldOut);
545 PySys_SetObject((char*)"stderr",oldErr);
551 \brief Get previous command in the commands history.
552 \return previous command
554 const char * PyInterp_Interp::getPrevious()
556 if(_ith != _history.begin()){
558 return (*_ith).c_str();
561 return BEGIN_HISTORY_PY;
565 \brief Get next command in the commands history.
568 const char * PyInterp_Interp::getNext()
570 if(_ith != _history.end()){
573 if (_ith == _history.end())
574 return TOP_HISTORY_PY;
576 return (*_ith).c_str();
580 \brief Set Python standard output device hook.
581 \param cb callback function
582 \param data callback function parameters
584 void PyInterp_Interp::setvoutcb(PyOutChanged* cb, void* data)
586 ((PyStdOut*)_vout)->_cb=cb;
587 ((PyStdOut*)_vout)->_data=data;
591 \brief Set Python standard error device hook.
592 \param cb callback function
593 \param data callback function parameters
595 void PyInterp_Interp::setverrcb(PyOutChanged* cb, void* data)
597 ((PyStdOut*)_verr)->_cb=cb;
598 ((PyStdOut*)_verr)->_data=data;