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), _local_context(0), _global_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
254 for (int i = 0; i < _argc; i++)
256 changed_argv[i] = Py_DecodeLocale(_argv[i], NULL);
259 Py_SetProgramName(changed_argv[0]);
260 Py_Initialize(); // Initialize the interpreter
261 PySys_SetArgv(_argc, changed_argv);
263 PyEval_InitThreads(); // Create (and acquire) the Python global interpreter lock (GIL)
264 PyEval_SaveThread(); // release safely GIL
269 \brief Get embedded Python interpreter banner.
270 \return banner string
272 std::string PyInterp_Interp::getBanner() const
275 std::string aBanner("Python ");
276 aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
277 aBanner = aBanner + "\ntype help to get general information on environment\n";
282 \brief Initialize run command.
284 This method is used to prepare interpreter for running
287 \return \c true on success and \c false on error
289 bool PyInterp_Interp::initRun()
295 * Initialize context dictionaries. GIL is held already.
296 * The code executed in an embedded interpreter is expected to be run at the module
297 * level, in which case local and global context have to be the same dictionary.
298 * See: http://stackoverflow.com/questions/12265756/c-python-running-python-code-within-a-context
299 * for an explanation.
301 bool PyInterp_Interp::initContext()
303 PyObject *m = PyImport_AddModule("__main__"); // interpreter main module (module context)
308 _global_context = PyModule_GetDict(m); // get interpreter global variable context
309 Py_INCREF(_global_context);
310 _local_context = _global_context;
316 * Destroy context dictionaries. GIL is held already.
318 void PyInterp_Interp::closeContext()
320 Py_XDECREF(_global_context);
321 // both _global_context and _local_context may point to the same Python object
322 if ( _global_context != _local_context)
323 Py_XDECREF(_local_context);
327 \brief Compile Python command and evaluate it in the
328 python dictionary contexts if possible. This is not thread-safe.
329 This is the caller's responsability to make this thread-safe.
331 \param command Python command string
332 \return -1 on fatal error, 1 if command is incomplete and 0
333 if command is executed successfully
335 static int run_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
337 PyObject *m = PyImport_AddModule("codeop");
339 // Fatal error. No way to go on.
344 PyObjWrapper v(PyObject_CallMethod(m,(char*)"compile_command",(char*)"s",command));
346 // Error encountered. It should be SyntaxError,
347 //so we don't write out traceback
348 PyObjWrapper exception, value, tb;
349 PyErr_Fetch(&exception, &value, &tb);
350 PyErr_NormalizeException(&exception, &value, &tb);
351 PyErr_Display(exception, value, NULL);
354 else if (v == Py_None) {
355 // Incomplete text we return 1 : we need a complete text to execute
359 PyObjWrapper r(PyEval_EvalCode((PyObject *)(void *)v,global_ctxt, local_ctxt));
361 // Execution error. We return -1
365 // The command has been successfully executed. Return 0
370 void replaceAll(std::string& str, const std::string& from, const std::string& to) {
373 size_t start_pos = 0;
374 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
375 str.replace(start_pos, from.length(), to);
376 start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
380 std::vector<std::string>
381 __split(const std::string& str, char delimiter)
383 std::vector<std::string> internal;
384 std::stringstream ss(str); // Turn the string into a stream.
387 while (getline(ss, tok, delimiter)) {
388 internal.push_back(tok);
395 __join(const std::vector<std::string>& v, int begin=0, int end=-1)
399 std::stringstream ss;
400 for (size_t i = begin; i < end; ++i) {
408 std::vector<std::string>
409 __getArgsList(std::string argsString)
411 // Special process if some items of 'args:' list are themselves lists
412 // Note that an item can be a list, but not a list of lists...
413 // So we can have something like this:
414 // myscript.py args:[\'file1\',\'file2\'],\'val1\',\"done\",[1,2,3],[True,False],\"ok\",kwarg1=\'kwarg1\',kwarg2=\'kwarg2\',\'fin\'
415 // 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'
416 // We have to split argsString to obtain a 9 string elements list
417 std::vector<std::string> x = __split(argsString, ',');
418 bool containsList = (argsString.find('[') != std::string::npos);
420 std::vector<int> listBeginIndices, listEndIndices;
421 for (int pos = 0; pos < x.size(); ++pos) {
422 if (x[pos][0] == '[')
423 listBeginIndices.push_back(pos);
424 else if (x[pos][x[pos].size()-1] == ']')
425 listEndIndices.push_back(pos);
427 std::vector<std::string> extractedArgs;
429 for (int pos = 0; pos < listBeginIndices.size(); ++pos) {
430 int lbeg = listBeginIndices[pos];
431 int lend = listEndIndices[pos];
433 for (int k = start; k < lbeg; ++k)
434 extractedArgs.push_back(x[k]);
435 extractedArgs.push_back(__join(x, lbeg, lend+1));
438 if (start < x.size())
439 for (int k = start; k < x.size(); ++k)
440 extractedArgs.push_back(x[k]);
441 return extractedArgs;
449 \brief Compile Python command and evaluate it in the
450 python dictionary context if possible. Command might correspond to
451 the execution of a script with optional arguments.
452 In this case, command is:
453 execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
455 \param command Python command string
456 \param context Python context (dictionary)
457 \return -1 on fatal error, 1 if command is incomplete and 0
458 if command is executed successfully
460 static int compile_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
462 // First guess if command is execution of a script with args, or a simple Python command
463 std::string singleCommand = command;
464 std::string commandArgs = "";
466 QRegExp rx("execfile\\s*\\(.*(args:.*)\"\\s*\\)");
467 if (rx.indexIn(command) != -1) {
468 commandArgs = rx.cap(1).remove(0,5).toStdString(); // arguments of command
469 singleCommand = rx.cap().remove(rx.cap(1)).remove(" ").toStdString(); // command for execution without arguments
472 if (commandArgs.empty()) {
473 // process command: expression
474 // process command: execfile(r"/absolute/path/to/script.py") (no args)
475 return run_command(singleCommand.c_str(), global_ctxt, local_ctxt);
478 // process command: execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
479 std::string script = singleCommand.substr(11); // remove leading execfile(r"
480 script = script.substr(0, script.length()-2); // remove trailing ")
481 std::vector<std::string> argList = __getArgsList(commandArgs);
483 std::string preCommandBegin = "import sys; save_argv = sys.argv; sys.argv=[";
484 std::string preCommandEnd = "];";
485 std::string completeCommand = preCommandBegin+"\""+script+"\",";
486 for (std::vector<std::string>::iterator itr = argList.begin(); itr != argList.end(); ++itr) {
487 if (itr != argList.begin())
488 completeCommand += ",";
489 completeCommand = completeCommand + "\"" + *itr + "\"";
491 completeCommand = completeCommand+preCommandEnd+singleCommand+";sys.argv=save_argv";
492 return run_command(completeCommand.c_str(), global_ctxt, local_ctxt);
497 \brief Run Python command - the command has to fit on a single line (no \n!).
498 Use ';' if you need multiple statements evaluated at once.
499 \param command Python command
500 \return command status
502 int PyInterp_Interp::run(const char *command)
505 int ret = simpleRun(command);
511 * Called before a command is run (when calling run() method). Not thread-safe. Caller's responsability
512 * to acquire GIL if needed.
514 int PyInterp_Interp::beforeRun()
520 * Called after a command is run (when calling run() method). Not thread-safe. Caller's responsability
521 * to acquire GIL if needed.
523 int PyInterp_Interp::afterRun()
529 \brief Run Python command (used internally). Not thread-safe. GIL acquisition is caller's responsability.
530 \param command Python command
531 \param addToHistory if \c true (default), the command is added to the commands history
532 \return command status
534 int PyInterp_Interp::simpleRun(const char *command, const bool addToHistory)
536 if( addToHistory && strcmp(command,"") != 0 ) {
537 _history.push_back(command);
538 _ith = _history.end();
541 // Current stdout and stderr are saved
542 PyObject * oldOut = PySys_GetObject((char*)"stdout");
543 PyObject * oldErr = PySys_GetObject((char*)"stderr");
544 // Keep them alive (PySys_GetObject returned a *borrowed* ref!)
548 // Redirect outputs to SALOME Python console before treatment
549 PySys_SetObject((char*)"stderr",_verr);
550 PySys_SetObject((char*)"stdout",_vout);
552 int ier = compile_command(command, _global_context, _local_context);
554 // Outputs are redirected to what they were before
555 PySys_SetObject((char*)"stdout",oldOut);
556 PySys_SetObject((char*)"stderr",oldErr);
562 \brief Get previous command in the commands history.
563 \return previous command
565 const char * PyInterp_Interp::getPrevious()
567 if(_ith != _history.begin()){
569 return (*_ith).c_str();
572 return BEGIN_HISTORY_PY;
576 \brief Get next command in the commands history.
579 const char * PyInterp_Interp::getNext()
581 if(_ith != _history.end()){
584 if (_ith == _history.end())
585 return TOP_HISTORY_PY;
587 return (*_ith).c_str();
591 \brief Set Python standard output device hook.
592 \param cb callback function
593 \param data callback function parameters
595 void PyInterp_Interp::setvoutcb(PyOutChanged* cb, void* data)
597 ((PyStdOut*)_vout)->_cb=cb;
598 ((PyStdOut*)_vout)->_data=data;
602 \brief Set Python standard error device hook.
603 \param cb callback function
604 \param data callback function parameters
606 void PyInterp_Interp::setverrcb(PyOutChanged* cb, void* data)
608 ((PyStdOut*)_verr)->_cb=cb;
609 ((PyStdOut*)_verr)->_data=data;
613 \bried Check if the interpreter is initialized
616 bool PyInterp_Interp::initialized() const