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)
59 if (!PyArg_ParseTuple(args, "t#:write",&c, &l))
68 self->_cb(self->_data,c);
75 PyStdOut_flush(PyStdOut *self)
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, 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"},
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*/
141 #define PyStdOut_Check(v) ((v)->ob_type == &PyStdOut_Type)
143 static PyStdOut* newPyStdOut( bool iscerr )
146 self = PyObject_New(PyStdOut, &PyStdOut_Type);
151 self->_iscerr = iscerr;
156 \class PyInterp_Interp
157 \brief Generic embedded Python interpreter.
160 int PyInterp_Interp::_argc = 1;
161 char* PyInterp_Interp::_argv[] = {(char*)""};
164 \brief Basic constructor.
166 After construction the interpreter instance successor classes
167 must call virtual method initalize().
169 PyInterp_Interp::PyInterp_Interp():
170 _vout(0), _verr(0), _local_context(0), _global_context(0), _initialized(false)
177 PyInterp_Interp::~PyInterp_Interp()
183 \brief Initialize embedded interpreter.
185 This method shoud be called after construction of the interpreter.
186 The method initialize() calls virtuals methods
187 - initPython() to initialize global Python interpreter
188 - initContext() to initialize interpreter internal context
189 - initRun() to prepare interpreter for running commands
190 which should be implemented in the successor classes, according to the
191 embedded Python interpreter policy (mono or multi interpreter, etc).
193 void PyInterp_Interp::initialize()
196 return; // prevent repeating intitialization
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 // ---- The rest of the initialisation process is done hodling the GIL
210 // used to interpret & compile commands - this is really imported here
211 // and only added again (with PyImport_AddModule) later on
212 PyObjWrapper m(PyImport_ImportModule("codeop"));
218 // Create python objects to capture stdout and stderr
219 _vout=(PyObject*)newPyStdOut( false ); // stdout
220 _verr=(PyObject*)newPyStdOut( true ); // stderr
222 // All the initRun outputs are redirected to the standard output (console)
226 void PyInterp_Interp::destroy()
233 \brief Initialize Python interpreter.
235 In case if Python is not initialized, it sets program name, initializes the single true Python
236 interpreter, sets program arguments, and initializes threads.
237 Otherwise, does nothing. This is important for light SALOME configuration,
238 as in full SALOME this is done at SalomeApp level.
239 \sa SalomeApp_PyInterp class and main() in SALOME_Session_Server
241 void PyInterp_Interp::initPython()
243 if (!Py_IsInitialized()){
244 // Python is not initialized
245 wchar_t **changed_argv = new wchar_t*[_argc]; // Setting arguments
247 for (int i = 0; i < _argc; i++)
249 changed_argv[i] = Py_DecodeLocale(_argv[i], NULL);
252 Py_SetProgramName(changed_argv[0]);
253 Py_Initialize(); // Initialize the interpreter
254 PySys_SetArgv(_argc, changed_argv);
256 PyEval_InitThreads(); // Create (and acquire) the Python global interpreter lock (GIL)
257 PyEval_ReleaseLock();
262 \brief Get embedded Python interpreter banner.
263 \return banner string
265 std::string PyInterp_Interp::getBanner() const
268 std::string aBanner("Python ");
269 aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
270 aBanner = aBanner + "\ntype help to get general information on environment\n";
275 \brief Initialize run command.
277 This method is used to prepare interpreter for running
280 \return \c true on success and \c false on error
282 bool PyInterp_Interp::initRun()
288 * Initialize context dictionaries. GIL is held already.
289 * The code executed in an embedded interpreter is expected to be run at the module
290 * level, in which case local and global context have to be the same dictionary.
291 * See: http://stackoverflow.com/questions/12265756/c-python-running-python-code-within-a-context
292 * for an explanation.
294 bool PyInterp_Interp::initContext()
296 PyObject *m = PyImport_AddModule("__main__"); // interpreter main module (module context)
301 _global_context = PyModule_GetDict(m); // get interpreter global variable context
302 Py_INCREF(_global_context);
303 _local_context = _global_context;
309 * Destroy context dictionaries. GIL is held already.
311 void PyInterp_Interp::closeContext()
313 Py_XDECREF(_global_context);
314 // both _global_context and _local_context may point to the same Python object
315 if ( _global_context != _local_context)
316 Py_XDECREF(_local_context);
320 \brief Compile Python command and evaluate it in the
321 python dictionary contexts if possible. This is not thread-safe.
322 This is the caller's responsability to make this thread-safe.
324 \param command Python command string
325 \return -1 on fatal error, 1 if command is incomplete and 0
326 if command is executed successfully
328 static int run_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
330 PyObject *m = PyImport_AddModule("codeop");
332 // Fatal error. No way to go on.
337 PyObjWrapper v(PyObject_CallMethod(m,(char*)"compile_command",(char*)"s",command));
339 // Error encountered. It should be SyntaxError,
340 //so we don't write out traceback
341 PyObjWrapper exception, value, tb;
342 PyErr_Fetch(&exception, &value, &tb);
343 PyErr_NormalizeException(&exception, &value, &tb);
344 PyErr_Display(exception, value, NULL);
347 else if (v == Py_None) {
348 // Incomplete text we return 1 : we need a complete text to execute
352 PyObjWrapper r(PyEval_EvalCode((PyObject *)(void *)v,global_ctxt, local_ctxt));
354 // Execution error. We return -1
358 // The command has been successfully executed. Return 0
363 void replaceAll(std::string& str, const std::string& from, const std::string& to) {
366 size_t start_pos = 0;
367 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
368 str.replace(start_pos, from.length(), to);
369 start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
373 std::vector<std::string>
374 __split(const std::string& str, char delimiter)
376 std::vector<std::string> internal;
377 std::stringstream ss(str); // Turn the string into a stream.
380 while (getline(ss, tok, delimiter)) {
381 internal.push_back(tok);
388 __join(const std::vector<std::string>& v, int begin=0, int end=-1)
392 std::stringstream ss;
393 for (size_t i = begin; i < end; ++i) {
401 std::vector<std::string>
402 __getArgsList(std::string argsString)
404 // Special process if some items of 'args:' list are themselves lists
405 // Note that an item can be a list, but not a list of lists...
406 // So we can have something like this:
407 // myscript.py args:[\'file1\',\'file2\'],\'val1\',\"done\",[1,2,3],[True,False],\"ok\",kwarg1=\'kwarg1\',kwarg2=\'kwarg2\',\'fin\'
408 // 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'
409 // We have to split argsString to obtain a 9 string elements list
410 std::vector<std::string> x = __split(argsString, ',');
411 bool containsList = (argsString.find('[') != std::string::npos);
413 std::vector<int> listBeginIndices, listEndIndices;
414 for (int pos = 0; pos < x.size(); ++pos) {
415 if (x[pos][0] == '[')
416 listBeginIndices.push_back(pos);
417 else if (x[pos][x[pos].size()-1] == ']')
418 listEndIndices.push_back(pos);
420 std::vector<std::string> extractedArgs;
422 for (int pos = 0; pos < listBeginIndices.size(); ++pos) {
423 int lbeg = listBeginIndices[pos];
424 int lend = listEndIndices[pos];
426 for (int k = start; k < lbeg; ++k)
427 extractedArgs.push_back(x[k]);
428 extractedArgs.push_back(__join(x, lbeg, lend+1));
431 if (start < x.size())
432 for (int k = start; k < x.size(); ++k)
433 extractedArgs.push_back(x[k]);
434 return extractedArgs;
442 \brief Compile Python command and evaluate it in the
443 python dictionary context if possible. Command might correspond to
444 the execution of a script with optional arguments.
445 In this case, command is:
446 execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
448 \param command Python command string
449 \param context Python context (dictionary)
450 \return -1 on fatal error, 1 if command is incomplete and 0
451 if command is executed successfully
453 static int compile_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
455 // First guess if command is execution of a script with args, or a simple Python command
456 std::string singleCommand = command;
457 std::string commandArgs = "";
459 QRegExp rx("execfile\\s*\\(.*(args:.*)\"\\s*\\)");
460 if (rx.indexIn(command) != -1) {
461 commandArgs = rx.cap(1).remove(0,5).toStdString(); // arguments of command
462 singleCommand = rx.cap().remove(rx.cap(1)).remove(" ").toStdString(); // command for execution without arguments
465 if (commandArgs.empty()) {
466 // process command: expression
467 // process command: execfile(r"/absolute/path/to/script.py") (no args)
468 return run_command(singleCommand.c_str(), global_ctxt, local_ctxt);
471 // process command: execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
472 std::string script = singleCommand.substr(11); // remove leading execfile(r"
473 script = script.substr(0, script.length()-2); // remove trailing ")
474 std::vector<std::string> argList = __getArgsList(commandArgs);
476 std::string preCommandBegin = "import sys; save_argv = sys.argv; sys.argv=[";
477 std::string preCommandEnd = "];";
478 std::string completeCommand = preCommandBegin+"\""+script+"\",";
479 for (std::vector<std::string>::iterator itr = argList.begin(); itr != argList.end(); ++itr) {
480 if (itr != argList.begin())
481 completeCommand += ",";
482 completeCommand = completeCommand + "\"" + *itr + "\"";
484 completeCommand = completeCommand+preCommandEnd+singleCommand+";sys.argv=save_argv";
485 return run_command(completeCommand.c_str(), global_ctxt, local_ctxt);
490 \brief Run Python command - the command has to fit on a single line (no \n!).
491 Use ';' if you need multiple statements evaluated at once.
492 \param command Python command
493 \return command status
495 int PyInterp_Interp::run(const char *command)
498 int ret = simpleRun(command);
504 * Called before a command is run (when calling run() method). Not thread-safe. Caller's responsability
505 * to acquire GIL if needed.
507 int PyInterp_Interp::beforeRun()
513 * Called after a command is run (when calling run() method). Not thread-safe. Caller's responsability
514 * to acquire GIL if needed.
516 int PyInterp_Interp::afterRun()
522 \brief Run Python command (used internally). Not thread-safe. GIL acquisition is caller's responsability.
523 \param command Python command
524 \param addToHistory if \c true (default), the command is added to the commands history
525 \return command status
527 int PyInterp_Interp::simpleRun(const char *command, const bool addToHistory)
529 if( addToHistory && strcmp(command,"") != 0 ) {
530 _history.push_back(command);
531 _ith = _history.end();
534 // Current stdout and stderr are saved
535 PyObject * oldOut = PySys_GetObject((char*)"stdout");
536 PyObject * oldErr = PySys_GetObject((char*)"stderr");
537 // Keep them alive (PySys_GetObject returned a *borrowed* ref!)
541 // Redirect outputs to SALOME Python console before treatment
542 PySys_SetObject((char*)"stderr",_verr);
543 PySys_SetObject((char*)"stdout",_vout);
545 int ier = compile_command(command, _global_context, _local_context);
547 // Outputs are redirected to what they were before
548 PySys_SetObject((char*)"stdout",oldOut);
549 PySys_SetObject((char*)"stderr",oldErr);
555 \brief Get previous command in the commands history.
556 \return previous command
558 const char * PyInterp_Interp::getPrevious()
560 if(_ith != _history.begin()){
562 return (*_ith).c_str();
565 return BEGIN_HISTORY_PY;
569 \brief Get next command in the commands history.
572 const char * PyInterp_Interp::getNext()
574 if(_ith != _history.end()){
577 if (_ith == _history.end())
578 return TOP_HISTORY_PY;
580 return (*_ith).c_str();
584 \brief Set Python standard output device hook.
585 \param cb callback function
586 \param data callback function parameters
588 void PyInterp_Interp::setvoutcb(PyOutChanged* cb, void* data)
590 ((PyStdOut*)_vout)->_cb=cb;
591 ((PyStdOut*)_vout)->_data=data;
595 \brief Set Python standard error device hook.
596 \param cb callback function
597 \param data callback function parameters
599 void PyInterp_Interp::setverrcb(PyOutChanged* cb, void* data)
601 ((PyStdOut*)_verr)->_cb=cb;
602 ((PyStdOut*)_verr)->_data=data;
606 \bried Check if the interpreter is initialized
609 bool PyInterp_Interp::initialized() const