2 #include "PyInterp_Interp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
6 #include <structmember.h>
14 #define TOP_HISTORY_PY "--- top of history ---"
15 #define BEGIN_HISTORY_PY "--- begin of history ---"
17 // a map to store python thread states that have been created for a given system thread (key=thread id,value=thread state)
18 std::map<long,PyThreadState*> currentThreadMap;
22 \brief Python GIL wrapper.
26 \brief Constructor. Automatically acquires GIL.
27 \param theThreadState python thread state
29 PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState):
30 myThreadState(theThreadState),
33 if (myThreadState->interp == PyInterp_Interp::_interp)
34 _savestate = PyGILState_Ensure();
36 PyEval_AcquireThread(myThreadState);
40 \brief Destructor. Automatically releases GIL.
42 PyLockWrapper::~PyLockWrapper()
44 if (myThreadState->interp == PyInterp_Interp::_interp)
45 PyGILState_Release(_savestate);
47 PyEval_ReleaseThread(myThreadState);
51 \brief Get Python GIL wrapper.
52 \return GIL lock wrapper (GIL is automatically acquired here)
54 PyLockWrapper PyInterp_Interp::GetLockWrapper()
56 if (_tstate->interp == PyInterp_Interp::_interp)
59 // If we are here, we have a secondary python interpreter. Try to get a thread state synchronized with the system thread
60 long currentThreadid=PyThread_get_thread_ident(); // the system thread id
61 PyThreadState* theThreadState;
62 if(currentThreadMap.count(currentThreadid) != 0)
64 //a thread state exists for this thread id
65 PyThreadState* oldThreadState=currentThreadMap[currentThreadid];
66 if(_tstate->interp ==oldThreadState->interp)
68 //The old thread state has the same python interpreter as this one : reuse the threadstate
69 theThreadState=oldThreadState;
73 //The old thread state has not the same python interpreter as this one : delete the old threadstate and create a new one
75 PyThreadState_Clear(oldThreadState);
76 PyThreadState_Delete(oldThreadState);
78 theThreadState=PyThreadState_New(_tstate->interp);
79 currentThreadMap[currentThreadid]=theThreadState;
84 // no old thread state for this thread id : create a new one
85 theThreadState=PyThreadState_New(_tstate->interp);
86 currentThreadMap[currentThreadid]=theThreadState;
88 return theThreadState;
92 The following functions are used to hook the Python
97 PyStdOut_dealloc(PyStdOut *self)
103 PyStdOut_write(PyStdOut *self, PyObject *args)
107 if (!PyArg_ParseTuple(args, "t#:write",&c, &l))
109 if(self->_cb==NULL) {
116 self->_cb(self->_data,c);
123 PyStdOut_flush(PyStdOut *self)
129 static PyMethodDef PyStdOut_methods[] = {
130 {"write", (PyCFunction)PyStdOut_write, METH_VARARGS, PyDoc_STR("write(string) -> None")},
131 {"flush", (PyCFunction)PyStdOut_flush, METH_NOARGS, PyDoc_STR("flush() -> None")},
132 {NULL, NULL} /* sentinel */
135 static PyMemberDef PyStdOut_memberlist[] = {
136 {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0,
137 (char*)"flag indicating that a space needs to be printed; used by print"},
138 {NULL} /* Sentinel */
141 static PyTypeObject PyStdOut_Type = {
142 /* The ob_type field must be initialized in the module init function
143 * to be portable to Windows without using C++. */
144 PyObject_HEAD_INIT(NULL)
147 sizeof(PyStdOut), /*tp_basicsize*/
150 (destructor)PyStdOut_dealloc, /*tp_dealloc*/
157 0, /*tp_as_sequence*/
162 PyObject_GenericGetAttr, /*tp_getattro*/
163 /* softspace is writable: we must supply tp_setattro */
164 PyObject_GenericSetAttr, /* tp_setattro */
166 Py_TPFLAGS_DEFAULT, /*tp_flags*/
170 0, /*tp_richcompare*/
171 0, /*tp_weaklistoffset*/
174 PyStdOut_methods, /*tp_methods*/
175 PyStdOut_memberlist, /*tp_members*/
189 #define PyStdOut_Check(v) ((v)->ob_type == &PyStdOut_Type)
191 static PyStdOut* newPyStdOut( bool iscerr )
194 self = PyObject_New(PyStdOut, &PyStdOut_Type);
199 self->_iscerr = iscerr;
204 \class PyInterp_Interp
205 \brief Generic embedded Python interpreter.
208 int PyInterp_Interp::_argc = 1;
209 char* PyInterp_Interp::_argv[] = {(char*)""};
210 PyObject* PyInterp_Interp::builtinmodule = NULL;
211 PyThreadState* PyInterp_Interp::_gtstate = NULL;
212 PyInterpreterState* PyInterp_Interp::_interp = NULL;
215 \brief Basic constructor.
217 After construction the interpreter instance successor classes
218 must call virtual method initalize().
220 PyInterp_Interp::PyInterp_Interp():
221 _tstate(0), _vout(0), _verr(0), _g(0)
228 PyInterp_Interp::~PyInterp_Interp()
233 \brief Initialize embedded interpreter.
235 This method shoud be called after construction of the interpreter.
236 The method initialize() calls virtuals methods
237 - initPython() to initialize global Python interpreter
238 - initState() to initialize embedded interpreter state
239 - initContext() to initialize interpreter internal context
240 - initRun() to prepare interpreter for running commands
241 which should be implemented in the successor classes, according to the
242 embedded Python interpreter policy (mono or multi interpreter, etc).
244 void PyInterp_Interp::initialize()
246 _history.clear(); // start a new list of user's commands
247 _ith = _history.begin();
250 // Here the global lock is released
254 PyEval_AcquireThread(_tstate);
258 // used to interpret & compile commands
259 PyObjWrapper m(PyImport_ImportModule("codeop"));
262 PyEval_ReleaseThread(_tstate);
266 // Create python objects to capture stdout and stderr
267 _vout=(PyObject*)newPyStdOut( false ); // stdout
268 _verr=(PyObject*)newPyStdOut( true ); // stderr
270 // All the initRun outputs are redirected to the standard output (console)
272 PyEval_ReleaseThread(_tstate);
276 \brief Initialize Python interpreter.
278 In case if Python is not initialized, it sets program name, initializes the interpreter, sets program arguments,
280 Otherwise, it just obtains the global interpreter and thread states. This is important for light SALOME configuration,
281 as in full SALOME this is done at SalomeApp level.
282 \sa SalomeApp_PyInterp class
284 void PyInterp_Interp::initPython()
286 if (!Py_IsInitialized()){
287 // Python is not initialized
288 Py_SetProgramName(_argv[0]);
289 Py_Initialize(); // Initialize the interpreter
290 PySys_SetArgv(_argc, _argv);
291 PyEval_InitThreads(); // Create (and acquire) the interpreter lock
294 if ( _interp == NULL )
295 _interp = PyThreadState_Get()->interp;
296 if (PyType_Ready(&PyStdOut_Type) < 0) {
299 if ( _gtstate == NULL )
300 _gtstate = PyEval_SaveThread(); // Release global thread state
304 \brief Get embedded Python interpreter banner.
305 \return banner string
307 std::string PyInterp_Interp::getbanner()
309 // Should we take the lock ?
310 // PyEval_RestoreThread(_tstate);
311 std::string aBanner("Python ");
312 aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
313 aBanner = aBanner + "\ntype help to get general information on environment\n";
314 //PyEval_SaveThread();
319 \brief Initialize run command.
321 This method is used to prepare interpreter for running
324 \return \c true on success and \c false on error
326 bool PyInterp_Interp::initRun()
329 // probably all below code isn't required
332 PySys_SetObject("stderr",_verr);
333 PySys_SetObject("stdout",_vout);
335 //PyObject *m = PyImport_GetModuleDict();
337 PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
338 PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
344 \brief Compile Python command and evaluate it in the
345 python dictionary context if possible.
347 \param command Python command string
348 \param context Python context (dictionary)
349 \return -1 on fatal error, 1 if command is incomplete and 0
350 if command is executed successfully
352 static int run_command(const char *command, PyObject *context)
354 PyObject *m = PyImport_AddModule("codeop");
355 if(!m) { // Fatal error. No way to go on.
359 PyObjWrapper v(PyObject_CallMethod(m,(char*)"compile_command",(char*)"s",command));
361 // Error encountered. It should be SyntaxError,
362 //so we don't write out traceback
363 PyObjWrapper exception, value, tb;
364 PyErr_Fetch(&exception, &value, &tb);
365 PyErr_NormalizeException(&exception, &value, &tb);
366 PyErr_Display(exception, value, NULL);
369 else if (v == Py_None) {
370 // Incomplete text we return 1 : we need a complete text to execute
374 // Complete and correct text. We evaluate it.
375 //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
376 // PyObjWrapper r(PyEval_EvalCode(v,context,context));
378 PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,context,context));
381 // Execution error. We return -1
385 // The command has been successfully executed. Return 0
390 void replaceAll(std::string& str, const std::string& from, const std::string& to) {
393 size_t start_pos = 0;
394 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
395 str.replace(start_pos, from.length(), to);
396 start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
400 \brief Compile Python command and evaluate it in the
401 python dictionary context if possible. Command might correspond to
402 the execution of a script with optional arguments.
403 In this case, command is:
404 execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
406 \param command Python command string
407 \param context Python context (dictionary)
408 \return -1 on fatal error, 1 if command is incomplete and 0
409 if command is executed successfully
411 static int compile_command(const char *command,PyObject *context)
413 // First guess if command is execution of a script with args, or a simple Python command
414 std::string singleCommand = command;
415 std::string commandArgs = "";
417 std::size_t pos = std::string(command).find("args:");
418 if (pos != std::string::npos) {
419 commandArgs = singleCommand.substr(pos+5);
420 commandArgs = commandArgs.substr(0, commandArgs.length()-3);
421 singleCommand = singleCommand.substr(0, pos-1)+"\")";
424 if (commandArgs.empty()) {
425 // process command: expression
426 // process command: execfile(r"/absolute/path/to/script.py") (no args)
427 return run_command(singleCommand.c_str(), context);
430 // process command: execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
431 std::string script = singleCommand.substr(11); // remove leading execfile(r"
432 script = script.substr(0, script.length()-2); // remove trailing ")
434 std::string preCommandBegin = "import sys; save_argv = sys.argv; sys.argv=[";
435 std::string preCommandEnd = "];";
436 replaceAll(commandArgs, ",", "\",\"");
437 commandArgs = "\""+commandArgs+"\"";
438 std::string completeCommand = preCommandBegin+"\""+script+"\","+commandArgs+preCommandEnd+singleCommand+";sys.argv=save_argv";
439 return run_command(completeCommand.c_str(), context);
444 \brief Run Python command.
445 \param command Python command
446 \return command status
448 int PyInterp_Interp::run(const char *command)
451 return simpleRun(command);
455 \brief Run Python command (used internally).
456 \param command Python command
457 \param addToHistory if \c true (default), the command is added to the commands history
458 \return command status
460 int PyInterp_Interp::simpleRun(const char *command, const bool addToHistory)
462 if( addToHistory && strcmp(command,"") != 0 ) {
463 _history.push_back(command);
464 _ith = _history.end();
467 // We come from C++ to enter Python world
468 // We need to acquire the Python global lock
469 //PyLockWrapper aLock(_tstate); // san - lock is centralized now
471 // Reset redirected outputs before treatment
472 PySys_SetObject((char*)"stderr",_verr);
473 PySys_SetObject((char*)"stdout",_vout);
475 int ier = compile_command(command,_g);
477 // Outputs are redirected on standards outputs (console)
478 PySys_SetObject((char*)"stdout",PySys_GetObject((char*)"__stdout__"));
479 PySys_SetObject((char*)"stderr",PySys_GetObject((char*)"__stderr__"));
485 \brief Get previous command in the commands history.
486 \return previous command
488 const char * PyInterp_Interp::getPrevious()
490 if(_ith != _history.begin()){
492 return (*_ith).c_str();
495 return BEGIN_HISTORY_PY;
499 \brief Get next command in the commands history.
502 const char * PyInterp_Interp::getNext()
504 if(_ith != _history.end()){
507 if (_ith == _history.end())
508 return TOP_HISTORY_PY;
510 return (*_ith).c_str();
514 \brief Set Python standard output device hook.
515 \param cb callback function
516 \param data callback function parameters
518 void PyInterp_Interp::setvoutcb(PyOutChanged* cb, void* data)
520 ((PyStdOut*)_vout)->_cb=cb;
521 ((PyStdOut*)_vout)->_data=data;
525 \brief Set Python standard error device hook.
526 \param cb callback function
527 \param data callback function parameters
529 void PyInterp_Interp::setverrcb(PyOutChanged* cb, void* data)
531 ((PyStdOut*)_verr)->_cb=cb;
532 ((PyStdOut*)_verr)->_data=data;