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 <cStringIO.h>
20 #include "PyInterp_base.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(false);
39 PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState):
40 myThreadState(theThreadState),
41 mySaveThreadState(PyInterp_base::_gtstate)
44 mySaveThreadState = PyThreadState_Swap(myThreadState);
48 PyLockWrapper::~PyLockWrapper(){
49 PyThreadState_Swap(mySaveThreadState);
54 ThreadLock::ThreadLock(QMutex* theMutex, const char* theComment):
58 if(MYDEBUG && myComment != "") MESSAGE(" ThreadLock "<<this<<"::"<<myMutex<<" - "<<myComment<<" - "<<myMutex->locked());
63 ThreadLock::~ThreadLock(){
64 if(MYDEBUG && myComment != "") MESSAGE("~ThreadLock "<<this<<"::"<<myMutex<<" - "<<myComment);
70 return myMutex.locked();
74 ThreadLock GetPyThreadLock(const char* theComment){
75 return ThreadLock(&myMutex,theComment);
82 if(MYPYDEBUG) MESSAGE("~PyReleaseLock()");
88 PyLockWrapper PyInterp_base::GetLockWrapper(){
93 // main python interpreter
95 PyThreadState *PyInterp_base::_gtstate = 0; // force 0 before execution
96 int PyInterp_base::_argc = 1;
97 char* PyInterp_base::_argv[] = {""};
99 PyObject *PyInterp_base::builtinmodule = NULL;
100 PyObject *PyInterp_base::salome_shared_modules_module = NULL;
104 * basic constructor here : herited classes constructors must call initalize() method
107 PyInterp_base::PyInterp_base(): _tstate(0), _vout(0), _verr(0), _g(0), _atFirst(true)
109 if(MYPYDEBUG) MESSAGE("PyInterp_base::PyInterp_base() - this = "<<this);
112 PyInterp_base::~PyInterp_base()
114 if(MYPYDEBUG) MESSAGE("PyInterp_base::~PyInterp_base() - this = "<<this);
115 PyLockWrapper aLock(_tstate);
116 //Py_EndInterpreter(_tstate);
121 * Must be called by herited classes constructors. initialize() calls virtuals methods
122 * initstate & initcontext, not defined here in base class. initstate & initcontext methods
123 * must be implemented in herited classes, following the Python interpreter policy
124 * (mono or multi interpreter...).
126 void PyInterp_base::initialize()
128 _history.clear(); // start a new list of user's commands
129 _ith = _history.begin();
132 PyReleaseLock aReleaseLock;
133 Py_Initialize(); // Initialize the interpreter
134 PyEval_InitThreads(); // Initialize and acquire the global interpreter lock
135 PySys_SetArgv(_argc,_argv); // initialize sys.argv
136 _gtstate = PyThreadState_Get();
139 * salome_shared_modules should be imported only once
141 salome_shared_modules_module = PyImport_ImportModule("salome_shared_modules");
142 if(!salome_shared_modules_module)
144 INFOS("PyInterp_base::initialize() - salome_shared_modules_module == NULL");
149 // Here the global lock is released
150 if(MYPYDEBUG) MESSAGE("PyInterp_base::initialize() - this = "<<this<<"; _gtstate = "<<_gtstate);
152 // The lock will be acquired in initState. Make provision to release it on exit
153 PyReleaseLock aReleaseLock;
158 // used to interpret & compile commands
159 PyObjWrapper m(PyImport_ImportModule("codeop"));
161 INFOS("PyInterp_base::initialize() - PyImport_ImportModule('codeop') failed");
167 // Create cStringIO to capture stdout and stderr
169 PycStringIO = (PycStringIO_CAPI *)xxxPyCObject_Import("cStringIO", "cStringIO_CAPI");
170 _vout = PycStringIO->NewOutput(128);
171 _verr = PycStringIO->NewOutput(128);
173 // All the initRun outputs are redirected to the standard output (console)
178 string PyInterp_base::getbanner()
180 string aBanner("Python ");
181 aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
182 aBanner = aBanner + "\ntype help to get general information on environment\n";
187 int PyInterp_base::initRun()
189 PySys_SetObject("stderr",_verr);
190 PySys_SetObject("stdout",_vout);
192 PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
193 PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
195 PyObject *m = PyImport_GetModuleDict();
197 PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
198 PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
200 if(MYPYDEBUG) MESSAGE("PyInterp_base::initRun() - this = "<<this<<"; _verr = "<<_verr<<"; _vout = "<<_vout);
206 * This function compiles a string (command) and then evaluates it in the dictionnary
207 * context if possible.
210 * 1 : incomplete text
211 * 0 : complete text executed with success
213 int compile_command(const char *command,PyObject *context)
215 PyObject *m = PyImport_AddModule("codeop");
216 if(!m){ // Fatal error. No way to go on.
220 PyObjWrapper v(PyObject_CallMethod(m,"compile_command","s",command));
222 // Error encountered. It should be SyntaxError,
223 //so we don't write out traceback
224 PyObjWrapper exception, value, tb;
225 PyErr_Fetch(&exception, &value, &tb);
226 PyErr_NormalizeException(&exception, &value, &tb);
227 PyErr_Display(exception, value, NULL);
229 }else if (v == Py_None){
230 // Incomplete text we return 1 : we need a complete text to execute
233 // Complete and correct text. We evaluate it.
234 PyObjWrapper r(PyEval_EvalCode(v,context,context));
236 // Execution error. We return -1
240 // The command has been successfully executed. Return 0
246 int PyInterp_base::run(const char *command)
251 ret = simpleRun("from Help import *");
253 ret = simpleRun("import salome");
256 return simpleRun(command);
260 int PyInterp_base::simpleRun(const char *command)
262 if(strcmp(command,"") != 0){
263 _history.push_back(command);
264 _ith = _history.end();
267 // We come from C++ to enter Python world
268 // We need to acquire the Python global lock
269 PyLockWrapper aLock(_tstate);
271 // Reset redirected outputs before treatment
272 PySys_SetObject("stderr",_verr);
273 PySys_SetObject("stdout",_vout);
275 PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
276 PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
278 int ier = compile_command(command,_g);
280 // Outputs are redirected on standards outputs (console)
281 PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
282 PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
287 const char * PyInterp_base::getPrevious()
289 if(_ith != _history.begin()){
291 return (*_ith).c_str();
294 return BEGIN_HISTORY_PY;
298 const char * PyInterp_base::getNext()
300 if(_ith != _history.end()){
303 if (_ith == _history.end())
304 return TOP_HISTORY_PY;
306 return (*_ith).c_str();
310 string PyInterp_base::getverr(){
311 PyLockWrapper aLock(_tstate);
312 PyObjWrapper v(PycStringIO->cgetvalue(_verr));
313 string aRet(PyString_AsString(v));
318 string PyInterp_base::getvout(){
319 PyLockWrapper aLock(_tstate);
320 PyObjWrapper v(PycStringIO->cgetvalue(_vout));
321 string aRet(PyString_AsString(v));