1 // SALOME SALOMEGUI : implementation of desktop and GUI kernel
3 // Copyright (C) 2003 CEA/DEN, EDF R&D
7 // File : PyInterp_base.cxx
8 // Author : Christian CAREMOLI, Paul RASCLE, EDF
16 #include "PyInterp_base.h" // this include must be first (see PyInterp_base.h)!
17 #include <cStringIO.h>
21 #include "utilities.h"
28 static int MYDEBUG = 0;
29 static int MYPYDEBUG = 0;
31 static int MYDEBUG = 0;
32 static int MYPYDEBUG = 0;
36 static QMutex myMutex(true);
39 PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState):
40 myThreadState(theThreadState),
41 mySaveThreadState(PyInterp_base::_gtstate)
44 mySaveThreadState = PyThreadState_Swap(myThreadState); // store previous current in save,
45 // set local in current
49 PyLockWrapper::~PyLockWrapper(){
50 PyThreadState_Swap(mySaveThreadState); // restore previous current (no need to get local,
51 PyEval_ReleaseLock(); // local thread state* already in _tstate
55 ThreadLock::ThreadLock(QMutex* theMutex, const char* theComment):
59 if(MYDEBUG && myComment != "") MESSAGE(" ThreadLock "<<this<<"::"<<myMutex<<" - "<<myComment<<" - "<<myMutex->locked());
64 ThreadLock::~ThreadLock(){
65 if(MYDEBUG && myComment != "") MESSAGE("~ThreadLock "<<this<<"::"<<myMutex<<" - "<<myComment);
71 return myMutex.locked();
75 ThreadLock GetPyThreadLock(const char* theComment){
76 return ThreadLock(&myMutex,theComment);
83 if(MYPYDEBUG) MESSAGE("~PyReleaseLock()");
89 PyLockWrapper PyInterp_base::GetLockWrapper(){
94 // main python interpreter
96 PyThreadState *PyInterp_base::_gtstate = 0; // force 0 before execution
97 int PyInterp_base::_argc = 1;
98 char* PyInterp_base::_argv[] = {""};
100 PyObject *PyInterp_base::builtinmodule = NULL;
101 PyObject *PyInterp_base::salome_shared_modules_module = NULL;
105 * basic constructor here : herited classes constructors must call initalize() method
108 PyInterp_base::PyInterp_base(): _tstate(0), _vout(0), _verr(0), _g(0), _atFirst(true)
110 if(MYPYDEBUG) MESSAGE("PyInterp_base::PyInterp_base() - this = "<<this);
113 PyInterp_base::~PyInterp_base()
115 if(MYPYDEBUG) MESSAGE("PyInterp_base::~PyInterp_base() - this = "<<this);
116 PyLockWrapper aLock(_tstate);
117 //Py_EndInterpreter(_tstate);
122 * Must be called by herited classes constructors. initialize() calls virtuals methods
123 * initstate & initcontext, not defined here in base class. initstate & initcontext methods
124 * must be implemented in herited classes, following the Python interpreter policy
125 * (mono or multi interpreter...).
127 void PyInterp_base::initialize()
129 _history.clear(); // start a new list of user's commands
130 _ith = _history.begin();
132 if(!_gtstate) init_python();
133 // Here the global lock is released
134 if(MYPYDEBUG) MESSAGE("PyInterp_base::initialize() - this = "<<this<<"; _gtstate = "<<_gtstate);
136 // The lock will be acquired in initState. Make provision to release it on exit
137 PyReleaseLock aReleaseLock;
142 // used to interpret & compile commands
143 PyObjWrapper m(PyImport_ImportModule("codeop"));
145 INFOS("PyInterp_base::initialize() - PyImport_ImportModule('codeop') failed");
151 // Create cStringIO to capture stdout and stderr
153 //PycStringIO = (PycStringIO_CAPI *)xxxPyCObject_Import("cStringIO", "cStringIO_CAPI");
154 _vout = PycStringIO->NewOutput(128);
155 _verr = PycStringIO->NewOutput(128);
157 // All the initRun outputs are redirected to the standard output (console)
161 void PyInterp_base::init_python()
164 * Initialize the main state (_gtstate) if not already done
165 * The lock is released on init_python output
166 * It is the caller responsability to acquire it if needed
169 PyReleaseLock aReleaseLock;
170 Py_Initialize(); // Initialize the interpreter
171 PyEval_InitThreads(); // Initialize and acquire the global interpreter lock
172 PySys_SetArgv(_argc,_argv); // initialize sys.argv
173 _gtstate = PyThreadState_Get();
175 * salome_shared_modules should be imported only once
177 salome_shared_modules_module = PyImport_ImportModule("salome_shared_modules");
178 if(!salome_shared_modules_module)
180 INFOS("PyInterp_base::initialize() - salome_shared_modules_module == NULL");
187 string PyInterp_base::getbanner()
189 string aBanner("Python ");
190 aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
191 aBanner = aBanner + "\ntype help to get general information on environment\n";
196 int PyInterp_base::initRun()
198 PySys_SetObject("stderr",_verr);
199 PySys_SetObject("stdout",_vout);
201 PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
202 PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
204 //PyObject *m = PyImport_GetModuleDict();
206 PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
207 PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
209 if(MYPYDEBUG) MESSAGE("PyInterp_base::initRun() - this = "<<this<<"; _verr = "<<_verr<<"; _vout = "<<_vout);
215 * This function compiles a string (command) and then evaluates it in the dictionnary
216 * context if possible.
219 * 1 : incomplete text
220 * 0 : complete text executed with success
222 int compile_command(const char *command,PyObject *context)
224 PyObject *m = PyImport_AddModule("codeop");
225 if(!m){ // Fatal error. No way to go on.
229 PyObjWrapper v(PyObject_CallMethod(m,"compile_command","s",command));
231 // Error encountered. It should be SyntaxError,
232 //so we don't write out traceback
233 PyObjWrapper exception, value, tb;
234 PyErr_Fetch(&exception, &value, &tb);
235 PyErr_NormalizeException(&exception, &value, &tb);
236 PyErr_Display(exception, value, NULL);
238 }else if (v == Py_None){
239 // Incomplete text we return 1 : we need a complete text to execute
242 // Complete and correct text. We evaluate it.
243 PyObjWrapper r(PyEval_EvalCode(v,context,context));
245 // Execution error. We return -1
249 // The command has been successfully executed. Return 0
255 int PyInterp_base::run(const char *command)
259 ret = simpleRun("from Help import *");
264 ret = simpleRun("import salome");
269 ret = simpleRun("salome.salome_init()");
276 return simpleRun(command);
280 int PyInterp_base::simpleRun(const char *command)
282 if( !_atFirst && strcmp(command,"") != 0 ) {
283 _history.push_back(command);
284 _ith = _history.end();
287 // We come from C++ to enter Python world
288 // We need to acquire the Python global lock
289 PyLockWrapper aLock(_tstate);
291 // Reset redirected outputs before treatment
292 PySys_SetObject("stderr",_verr);
293 PySys_SetObject("stdout",_vout);
295 PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
296 PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
298 int ier = compile_command(command,_g);
300 // Outputs are redirected on standards outputs (console)
301 PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
302 PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
307 const char * PyInterp_base::getPrevious()
309 if(_ith != _history.begin()){
311 return (*_ith).c_str();
314 return BEGIN_HISTORY_PY;
318 const char * PyInterp_base::getNext()
320 if(_ith != _history.end()){
323 if (_ith == _history.end())
324 return TOP_HISTORY_PY;
326 return (*_ith).c_str();
330 string PyInterp_base::getverr(){
331 PyLockWrapper aLock(_tstate);
332 PyObjWrapper v(PycStringIO->cgetvalue(_verr));
333 string aRet(PyString_AsString(v));
338 string PyInterp_base::getvout(){
339 PyLockWrapper aLock(_tstate);
340 PyObjWrapper v(PycStringIO->cgetvalue(_vout));
341 string aRet(PyString_AsString(v));