1 // Copyright (C) 2007-2015 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>
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)
60 if (!PyArg_ParseTuple(args, "t#:write",&c, &l))
69 self->_cb(self->_data,c);
76 PyStdOut_flush(PyStdOut *self)
82 static PyMethodDef PyStdOut_methods[] = {
83 {"write", (PyCFunction)PyStdOut_write, METH_VARARGS, PyDoc_STR("write(string) -> None")},
84 {"flush", (PyCFunction)PyStdOut_flush, METH_NOARGS, PyDoc_STR("flush() -> None")},
85 {NULL, NULL} /* sentinel */
88 static PyMemberDef PyStdOut_memberlist[] = {
89 {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0,
90 (char*)"flag indicating that a space needs to be printed; used by print"},
94 static PyTypeObject PyStdOut_Type = {
95 /* The ob_type field must be initialized in the module init function
96 * to be portable to Windows without using C++. */
97 PyObject_HEAD_INIT(NULL)
100 sizeof(PyStdOut), /*tp_basicsize*/
103 (destructor)PyStdOut_dealloc, /*tp_dealloc*/
110 0, /*tp_as_sequence*/
115 PyObject_GenericGetAttr, /*tp_getattro*/
116 /* softspace is writable: we must supply tp_setattro */
117 PyObject_GenericSetAttr, /* tp_setattro */
119 Py_TPFLAGS_DEFAULT, /*tp_flags*/
123 0, /*tp_richcompare*/
124 0, /*tp_weaklistoffset*/
127 PyStdOut_methods, /*tp_methods*/
128 PyStdOut_memberlist, /*tp_members*/
142 #define PyStdOut_Check(v) ((v)->ob_type == &PyStdOut_Type)
144 static PyStdOut* newPyStdOut( bool iscerr )
147 self = PyObject_New(PyStdOut, &PyStdOut_Type);
152 self->_iscerr = iscerr;
157 \class PyInterp_Interp
158 \brief Generic embedded Python interpreter.
161 int PyInterp_Interp::_argc = 1;
162 char* PyInterp_Interp::_argv[] = {(char*)""};
165 \brief Basic constructor.
167 After construction the interpreter instance successor classes
168 must call virtual method initalize().
170 PyInterp_Interp::PyInterp_Interp():
171 _vout(0), _verr(0), _local_context(0), _global_context(0)
180 PyInterp_Interp::~PyInterp_Interp()
186 \brief Initialize embedded interpreter.
188 This method shoud be called after construction of the interpreter.
189 The method initialize() calls virtuals methods
190 - initPython() to initialize global Python interpreter
191 - initContext() to initialize interpreter internal context
192 - initRun() to prepare interpreter for running commands
193 which should be implemented in the successor classes, according to the
194 embedded Python interpreter policy (mono or multi interpreter, etc).
196 void PyInterp_Interp::initialize()
198 _history.clear(); // start a new list of user's commands
199 _ith = _history.begin();
201 initPython(); // This also inits the multi-threading for Python (but w/o acquiring GIL)
203 //initState(); // [ABN] OBSOLETE
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 Py_SetProgramName(_argv[0]);
246 Py_Initialize(); // Initialize the interpreter
247 PySys_SetArgv(_argc, _argv);
249 PyEval_InitThreads(); // Create (and acquire) the Python global interpreter lock (GIL)
250 PyEval_ReleaseLock();
255 \brief Get embedded Python interpreter banner.
256 \return banner string
258 std::string PyInterp_Interp::getbanner() const
261 std::string aBanner("Python ");
262 aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
263 aBanner = aBanner + "\ntype help to get general information on environment\n";
268 \brief Initialize run command.
270 This method is used to prepare interpreter for running
273 \return \c true on success and \c false on error
275 bool PyInterp_Interp::initRun()
281 * Initialize context dictionaries. GIL is held already.
282 * The code executed in an embedded interpreter is expected to be run at the module
283 * level, in which case local and global context have to be the same dictionary.
284 * See: http://stackoverflow.com/questions/12265756/c-python-running-python-code-within-a-context
285 * for an explanation.
287 bool PyInterp_Interp::initContext()
289 PyObject *m = PyImport_AddModule("__main__"); // interpreter main module (module context)
294 _global_context = PyModule_GetDict(m); // get interpreter global variable context
295 Py_INCREF(_global_context);
296 _local_context = _global_context;
298 int ret = PyRun_SimpleString("import salome_iapp;salome_iapp.IN_SALOME_GUI=True");
304 * Destroy context dictionaries. GIL is held already.
306 void PyInterp_Interp::closeContext()
308 Py_XDECREF(_global_context);
309 // both _global and _local point to the same Python object:
310 // Py_XDECREF(_local_context);
314 \brief Compile Python command and evaluate it in the
315 python dictionary contexts if possible. This is not thread-safe.
316 This is the caller's responsability to make this thread-safe.
318 \param command Python command string
319 \return -1 on fatal error, 1 if command is incomplete and 0
320 if command is executed successfully
322 static int run_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
324 PyObject *m = PyImport_AddModule("codeop");
325 if(!m) { // Fatal error. No way to go on.
330 // PyObjWrapper v(Py_CompileString(command, "<salome_input>", Py_file_input));
331 PyObjWrapper v(PyObject_CallMethod(m,(char*)"compile_command",(char*)"s",command));
333 // Error encountered. It should be SyntaxError,
334 //so we don't write out traceback
335 PyObjWrapper exception, value, tb;
336 PyErr_Fetch(&exception, &value, &tb);
337 PyErr_NormalizeException(&exception, &value, &tb);
338 PyErr_Display(exception, value, NULL);
341 else if (v == Py_None) {
342 // Incomplete text we return 1 : we need a complete text to execute
346 PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,global_ctxt, local_ctxt));
348 // Execution error. We return -1
352 // The command has been successfully executed. Return 0
357 void replaceAll(std::string& str, const std::string& from, const std::string& to) {
360 size_t start_pos = 0;
361 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
362 str.replace(start_pos, from.length(), to);
363 start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
367 std::vector<std::string>
368 __split(const std::string& str, char delimiter)
370 std::vector<std::string> internal;
371 std::stringstream ss(str); // Turn the string into a stream.
374 while (getline(ss, tok, delimiter)) {
375 internal.push_back(tok);
382 __join(const std::vector<std::string>& v, int begin=0, int end=-1)
386 std::stringstream ss;
387 for (size_t i = begin; i < end; ++i) {
395 std::vector<std::string>
396 __getArgsList(std::string argsString)
398 // Special process if some items of 'args:' list are themselves lists
399 // Note that an item can be a list, but not a list of lists...
400 // So we can have something like this:
401 // myscript.py args:[\'file1\',\'file2\'],\'val1\',\"done\",[1,2,3],[True,False],\"ok\",kwarg1=\'kwarg1\',kwarg2=\'kwarg2\',\'fin\'
402 // 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'
403 // We have to split argsString to obtain a 9 string elements list
404 std::vector<std::string> x = __split(argsString, ',');
405 bool containsList = (argsString.find('[') != std::string::npos);
407 std::vector<int> listBeginIndices, listEndIndices;
408 for (int pos = 0; pos < x.size(); ++pos) {
409 if (x[pos][0] == '[')
410 listBeginIndices.push_back(pos);
411 else if (x[pos][x[pos].size()-1] == ']')
412 listEndIndices.push_back(pos);
414 std::vector<std::string> extractedArgs;
416 for (int pos = 0; pos < listBeginIndices.size(); ++pos) {
417 int lbeg = listBeginIndices[pos];
418 int lend = listEndIndices[pos];
420 for (int k = start; k < lbeg; ++k)
421 extractedArgs.push_back(x[k]);
422 extractedArgs.push_back(__join(x, lbeg, lend+1));
425 if (start < x.size())
426 for (int k = start; k < x.size(); ++k)
427 extractedArgs.push_back(x[k]);
428 return extractedArgs;
436 \brief Compile Python command and evaluate it in the
437 python dictionary context if possible. Command might correspond to
438 the execution of a script with optional arguments.
439 In this case, command is:
440 execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
442 \param command Python command string
443 \param context Python context (dictionary)
444 \return -1 on fatal error, 1 if command is incomplete and 0
445 if command is executed successfully
447 static int compile_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
449 // First guess if command is execution of a script with args, or a simple Python command
450 std::string singleCommand = command;
451 std::string commandArgs = "";
453 while (singleCommand.at(singleCommand.size()-1) == '\n')
454 singleCommand.erase(singleCommand.size()-1);
455 std::size_t pos = singleCommand.find("args:");
456 if (pos != std::string::npos) {
457 commandArgs = singleCommand.substr(pos+5);
458 commandArgs = commandArgs.substr(0, commandArgs.length()-2);
459 singleCommand = singleCommand.substr(0, pos-1)+"\")";
462 if (commandArgs.empty()) {
463 // process command: expression
464 // process command: execfile(r"/absolute/path/to/script.py") (no args)
465 return run_command(singleCommand.c_str(), global_ctxt, local_ctxt);
468 // process command: execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
469 std::string script = singleCommand.substr(11); // remove leading execfile(r"
470 script = script.substr(0, script.length()-2); // remove trailing ")
471 std::vector<std::string> argList = __getArgsList(commandArgs);
473 std::string preCommandBegin = "import sys; save_argv = sys.argv; sys.argv=[";
474 std::string preCommandEnd = "];";
475 std::string completeCommand = preCommandBegin+"\""+script+"\",";
476 for (std::vector<std::string>::iterator itr = argList.begin(); itr != argList.end(); ++itr) {
477 if (itr != argList.begin())
478 completeCommand += ",";
479 completeCommand = completeCommand + "\"" + *itr + "\"";
481 completeCommand = completeCommand+preCommandEnd+singleCommand+";sys.argv=save_argv";
482 return run_command(completeCommand.c_str(), global_ctxt, local_ctxt);
487 \brief Run Python command - the command has to fit on a single line (no \n!).
488 Use ';' if you need multiple statements evaluated at once.
489 \param command Python command
490 \return command status
492 int PyInterp_Interp::run(const char *command)
495 int ret = simpleRun(command);
501 * Called before a command is run (when calling run() method). Not thread-safe. Caller's responsability
502 * to acquire GIL if needed.
504 int PyInterp_Interp::beforeRun()
510 * Called after a command is run (when calling run() method). Not thread-safe. Caller's responsability
511 * to acquire GIL if needed.
513 int PyInterp_Interp::afterRun()
519 \brief Run Python command (used internally). Not thread-safe. GIL acquisition is caller's responsability.
520 \param command Python command
521 \param addToHistory if \c true (default), the command is added to the commands history
522 \return command status
524 int PyInterp_Interp::simpleRun(const char *command, const bool addToHistory)
526 if( addToHistory && strcmp(command,"") != 0 ) {
527 _history.push_back(command);
528 _ith = _history.end();
531 // Current stdout and stderr are saved
532 PyObject * oldOut = PySys_GetObject((char*)"stdout");
533 PyObject * oldErr = PySys_GetObject((char*)"stderr");
534 // Keep them alive (PySys_GetObject returned a *borrowed* ref!)
538 // Redirect outputs to SALOME Python console before treatment
539 PySys_SetObject((char*)"stderr",_verr);
540 PySys_SetObject((char*)"stdout",_vout);
542 int ier = compile_command(command, _global_context, _local_context);
544 // Outputs are redirected to what they were before
545 PySys_SetObject((char*)"stdout",oldOut);
546 PySys_SetObject((char*)"stderr",oldErr);
552 \brief Get previous command in the commands history.
553 \return previous command
555 const char * PyInterp_Interp::getPrevious()
557 if(_ith != _history.begin()){
559 return (*_ith).c_str();
562 return BEGIN_HISTORY_PY;
566 \brief Get next command in the commands history.
569 const char * PyInterp_Interp::getNext()
571 if(_ith != _history.end()){
574 if (_ith == _history.end())
575 return TOP_HISTORY_PY;
577 return (*_ith).c_str();
581 \brief Set Python standard output device hook.
582 \param cb callback function
583 \param data callback function parameters
585 void PyInterp_Interp::setvoutcb(PyOutChanged* cb, void* data)
587 ((PyStdOut*)_vout)->_cb=cb;
588 ((PyStdOut*)_vout)->_data=data;
592 \brief Set Python standard error device hook.
593 \param cb callback function
594 \param data callback function parameters
596 void PyInterp_Interp::setverrcb(PyOutChanged* cb, void* data)
598 ((PyStdOut*)_verr)->_cb=cb;
599 ((PyStdOut*)_verr)->_data=data;