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 <Container_init_python.hxx>
18 #include <cStringIO.h>
22 #include <utilities.h>
29 //static int MYDEBUG = 1;
30 //static int MYPYDEBUG = 1;
32 //static int MYDEBUG = 0;
33 //static int MYPYDEBUG = 0;
37 static QMutex myMutex(true);
40 PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState):
41 myThreadState(theThreadState),
42 mySaveThreadState(KERNEL_PYTHON::_gtstate)
45 mySaveThreadState = PyThreadState_Swap(myThreadState); // store previous current in save,
46 // set local in current
47 // if(MYDEBUG) MESSAGE(" PyLockWrapper "<<this<<" aqcuired: new thread state "<<myThreadState<<" ; old thread state "<<mySaveThreadState);
51 PyLockWrapper::~PyLockWrapper(){
52 PyThreadState_Swap(mySaveThreadState); // restore previous current (no need to get local,
53 PyEval_ReleaseLock(); // local thread state* already in _tstate
54 // if(MYDEBUG) MESSAGE(" PyLockWrapper "<<this<<" released: new thread state "<<mySaveThreadState);
58 ThreadLock::ThreadLock(QMutex* theMutex, const char* theComment):
62 // if(MYDEBUG && myComment != "") MESSAGE(" ThreadLock "<<this<<"::"<<myMutex<<" - "<<myComment<<" - "<<myMutex->locked());
67 ThreadLock::~ThreadLock(){
68 // if(MYDEBUG && myComment != "") MESSAGE("~ThreadLock "<<this<<"::"<<myMutex<<" - "<<myComment);
74 return myMutex.locked();
78 ThreadLock GetPyThreadLock(const char* theComment){
79 return ThreadLock(&myMutex,theComment);
86 // if(MYPYDEBUG) MESSAGE("~PyReleaseLock()");
92 PyLockWrapper PyInterp_base::GetLockWrapper(){
97 // main python interpreter
99 //PyThreadState *PyInterp_base::_gtstate = 0; // force 0 before execution
100 int PyInterp_base::_argc = 1;
101 char* PyInterp_base::_argv[] = {""};
103 PyObject *PyInterp_base::builtinmodule = NULL;
107 * basic constructor here : herited classes constructors must call initalize() method
110 PyInterp_base::PyInterp_base(): _tstate(0), _vout(0), _verr(0), _g(0), _atFirst(true)
112 // if(MYPYDEBUG) MESSAGE("PyInterp_base::PyInterp_base() - this = "<<this);
115 PyInterp_base::~PyInterp_base()
117 // if(MYPYDEBUG) MESSAGE("PyInterp_base::~PyInterp_base() - this = "<<this);
118 PyLockWrapper aLock(_tstate);
119 //Py_EndInterpreter(_tstate);
124 * Must be called by herited classes constructors. initialize() calls virtuals methods
125 * initstate & initcontext, not defined here in base class. initstate & initcontext methods
126 * must be implemented in herited classes, following the Python interpreter policy
127 * (mono or multi interpreter...).
129 void PyInterp_base::initialize()
131 _history.clear(); // start a new list of user's commands
132 _ith = _history.begin();
135 // Here the global lock is released
136 // if(MYPYDEBUG) MESSAGE("PyInterp_base::initialize() - this = "<<this<<"; _gtstate = "<<_gtstate);
138 // The lock will be acquired in initState. Make provision to release it on exit
139 PyReleaseLock aReleaseLock;
144 // used to interpret & compile commands
145 PyObjWrapper m(PyImport_ImportModule("codeop"));
147 // INFOS("PyInterp_base::initialize() - PyImport_ImportModule('codeop') failed");
153 // Create cStringIO to capture stdout and stderr
155 //PycStringIO = (PycStringIO_CAPI *)xxxPyCObject_Import("cStringIO", "cStringIO_CAPI");
156 _vout = PycStringIO->NewOutput(128);
157 _verr = PycStringIO->NewOutput(128);
159 // All the initRun outputs are redirected to the standard output (console)
163 void PyInterp_base::init_python()
166 * Initialize the main state (_gtstate) if not already done
167 * The lock is released on init_python output
168 * It is the caller responsability to acquire it if needed
170 MESSAGE("PyInterp_base::init_python");
171 ASSERT(KERNEL_PYTHON::_gtstate); // initialisation in main
172 SCRUTE(KERNEL_PYTHON::_gtstate);
174 // PyReleaseLock aReleaseLock;
175 // Py_Initialize(); // Initialize the interpreter
176 // PyEval_InitThreads(); // Initialize and acquire the global interpreter lock
177 // PySys_SetArgv(_argc,_argv); // initialize sys.argv
178 // _gtstate = PyThreadState_Get();
182 string PyInterp_base::getbanner()
184 string aBanner("Python ");
185 aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
186 aBanner = aBanner + "\ntype help to get general information on environment\n";
191 int PyInterp_base::initRun()
193 PySys_SetObject("stderr",_verr);
194 PySys_SetObject("stdout",_vout);
196 PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
197 PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
199 //PyObject *m = PyImport_GetModuleDict();
201 PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
202 PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
204 // if(MYPYDEBUG) MESSAGE("PyInterp_base::initRun() - this = "<<this<<"; _verr = "<<_verr<<"; _vout = "<<_vout);
210 * This function compiles a string (command) and then evaluates it in the dictionnary
211 * context if possible.
214 * 1 : incomplete text
215 * 0 : complete text executed with success
217 int compile_command(const char *command,PyObject *context)
219 PyObject *m = PyImport_AddModule("codeop");
220 if(!m){ // Fatal error. No way to go on.
224 PyObjWrapper v(PyObject_CallMethod(m,"compile_command","s",command));
226 // Error encountered. It should be SyntaxError,
227 //so we don't write out traceback
228 PyObjWrapper exception, value, tb;
229 PyErr_Fetch(&exception, &value, &tb);
230 PyErr_NormalizeException(&exception, &value, &tb);
231 PyErr_Display(exception, value, NULL);
233 }else if (v == Py_None){
234 // Incomplete text we return 1 : we need a complete text to execute
237 // Complete and correct text. We evaluate it.
238 PyObjWrapper r(PyEval_EvalCode(v,context,context));
240 // Execution error. We return -1
244 // The command has been successfully executed. Return 0
250 int PyInterp_base::run(const char *command)
254 ret = simpleRun("from Help import *");
259 ret = simpleRun("import salome");
264 ret = simpleRun("salome.salome_init()");
271 return simpleRun(command);
275 int PyInterp_base::simpleRun(const char *command)
277 if( !_atFirst && strcmp(command,"") != 0 ) {
278 _history.push_back(command);
279 _ith = _history.end();
282 // We come from C++ to enter Python world
283 // We need to acquire the Python global lock
284 //PyLockWrapper aLock(_tstate); // san - lock is centralized now
286 // Reset redirected outputs before treatment
287 PySys_SetObject("stderr",_verr);
288 PySys_SetObject("stdout",_vout);
290 PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
291 PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
293 int ier = compile_command(command,_g);
295 // Outputs are redirected on standards outputs (console)
296 PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
297 PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
302 const char * PyInterp_base::getPrevious()
304 if(_ith != _history.begin()){
306 return (*_ith).c_str();
309 return BEGIN_HISTORY_PY;
313 const char * PyInterp_base::getNext()
315 if(_ith != _history.end()){
318 if (_ith == _history.end())
319 return TOP_HISTORY_PY;
321 return (*_ith).c_str();
325 string PyInterp_base::getverr(){
326 //PyLockWrapper aLock(_tstate);
327 PyObjWrapper v(PycStringIO->cgetvalue(_verr));
328 string aRet(PyString_AsString(v));
333 string PyInterp_base::getvout(){
334 //PyLockWrapper aLock(_tstate);
335 PyObjWrapper v(PycStringIO->cgetvalue(_vout));
336 string aRet(PyString_AsString(v));