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
18 #include <cStringIO.h>
22 #include "PyInterp_base.h"
23 #include "utilities.h"
30 static int MYDEBUG = 0;
31 static int MYPYDEBUG = 0;
33 static int MYDEBUG = 0;
34 static int MYPYDEBUG = 0;
38 static QMutex myMutex(false);
41 PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState):
42 myThreadState(theThreadState),
43 mySaveThreadState(PyInterp_base::_gtstate)
46 mySaveThreadState = PyThreadState_Swap(myThreadState);
50 PyLockWrapper::~PyLockWrapper(){
51 PyThreadState_Swap(mySaveThreadState);
56 ThreadLock::ThreadLock(QMutex* theMutex, const char* theComment):
60 if(MYDEBUG && myComment != "") MESSAGE(" ThreadLock "<<this<<"::"<<myMutex<<" - "<<myComment<<" - "<<myMutex->locked());
65 ThreadLock::~ThreadLock(){
66 if(MYDEBUG && myComment != "") MESSAGE("~ThreadLock "<<this<<"::"<<myMutex<<" - "<<myComment);
72 return myMutex.locked();
76 ThreadLock GetPyThreadLock(const char* theComment){
77 return ThreadLock(&myMutex,theComment);
84 if(MYPYDEBUG) MESSAGE("~PyReleaseLock()");
90 PyLockWrapper PyInterp_base::GetLockWrapper(){
95 // main python interpreter
97 PyThreadState *PyInterp_base::_gtstate = 0; // force 0 before execution
98 int PyInterp_base::_argc = 1;
99 char* PyInterp_base::_argv[] = {""};
101 PyObject *PyInterp_base::builtinmodule = NULL;
102 PyObject *PyInterp_base::salome_shared_modules_module = NULL;
106 * basic constructor here : herited classes constructors must call initalize() method
109 PyInterp_base::PyInterp_base(): _tstate(0), _vout(0), _verr(0), _g(0), _atFirst(true)
111 if(MYPYDEBUG) MESSAGE("PyInterp_base::PyInterp_base() - this = "<<this);
114 PyInterp_base::~PyInterp_base()
116 if(MYPYDEBUG) MESSAGE("PyInterp_base::~PyInterp_base() - this = "<<this);
117 PyLockWrapper aLock(_tstate);
118 //Py_EndInterpreter(_tstate);
123 * Must be called by herited classes constructors. initialize() calls virtuals methods
124 * initstate & initcontext, not defined here in base class. initstate & initcontext methods
125 * must be implemented in herited classes, following the Python interpreter policy
126 * (mono or multi interpreter...).
128 void PyInterp_base::initialize()
130 _history.clear(); // start a new list of user's commands
131 _ith = _history.begin();
134 PyReleaseLock aReleaseLock;
135 Py_Initialize(); // Initialize the interpreter
136 PyEval_InitThreads(); // Initialize and acquire the global interpreter lock
137 PySys_SetArgv(_argc,_argv); // initialize sys.argv
138 _gtstate = PyThreadState_Get();
141 * salome_shared_modules should be imported only once
143 salome_shared_modules_module = PyImport_ImportModule("salome_shared_modules");
144 if(!salome_shared_modules_module)
146 INFOS("PyInterp_base::initialize() - salome_shared_modules_module == NULL");
151 // Here the global lock is released
152 if(MYPYDEBUG) MESSAGE("PyInterp_base::initialize() - this = "<<this<<"; _gtstate = "<<_gtstate);
154 // The lock will be acquired in initState. Make provision to release it on exit
155 PyReleaseLock aReleaseLock;
160 // used to interpret & compile commands
161 PyObjWrapper m(PyImport_ImportModule("codeop"));
163 INFOS("PyInterp_base::initialize() - PyImport_ImportModule('codeop') failed");
169 // Create cStringIO to capture stdout and stderr
171 PycStringIO = (PycStringIO_CAPI *)xxxPyCObject_Import("cStringIO", "cStringIO_CAPI");
172 _vout = PycStringIO->NewOutput(128);
173 _verr = PycStringIO->NewOutput(128);
175 // All the initRun outputs are redirected to the standard output (console)
180 string PyInterp_base::getbanner()
182 string aBanner("Python ");
183 aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
184 aBanner = aBanner + "\ntype help to get general information on environment\n";
189 int PyInterp_base::initRun()
191 PySys_SetObject("stderr",_verr);
192 PySys_SetObject("stdout",_vout);
194 PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
195 PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
197 PyObject *m = PyImport_GetModuleDict();
199 PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
200 PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
202 if(MYPYDEBUG) MESSAGE("PyInterp_base::initRun() - this = "<<this<<"; _verr = "<<_verr<<"; _vout = "<<_vout);
208 * This function compiles a string (command) and then evaluates it in the dictionnary
209 * context if possible.
212 * 1 : incomplete text
213 * 0 : complete text executed with success
215 int compile_command(const char *command,PyObject *context)
217 PyObject *m = PyImport_AddModule("codeop");
218 if(!m){ // Fatal error. No way to go on.
222 PyObjWrapper v(PyObject_CallMethod(m,"compile_command","s",command));
224 // Error encountered. It should be SyntaxError,
225 //so we don't write out traceback
226 PyObjWrapper exception, value, tb;
227 PyErr_Fetch(&exception, &value, &tb);
228 PyErr_NormalizeException(&exception, &value, &tb);
229 PyErr_Display(exception, value, NULL);
231 }else if (v == Py_None){
232 // Incomplete text we return 1 : we need a complete text to execute
235 // Complete and correct text. We evaluate it.
236 PyObjWrapper r(PyEval_EvalCode(v,context,context));
238 // Execution error. We return -1
242 // The command has been successfully executed. Return 0
248 int PyInterp_base::run(const char *command)
253 ret = simpleRun("from Help import *");
255 ret = simpleRun("import salome");
258 return simpleRun(command);
262 int PyInterp_base::simpleRun(const char *command)
264 if(strcmp(command,"") != 0){
265 _history.push_back(command);
266 _ith = _history.end();
269 // We come from C++ to enter Python world
270 // We need to acquire the Python global lock
271 PyLockWrapper aLock(_tstate);
273 // Reset redirected outputs before treatment
274 PySys_SetObject("stderr",_verr);
275 PySys_SetObject("stdout",_vout);
277 PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
278 PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
280 int ier = compile_command(command,_g);
282 // Outputs are redirected on standards outputs (console)
283 PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
284 PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
289 const char * PyInterp_base::getPrevious()
291 if(_ith != _history.begin()){
293 return (*_ith).c_str();
296 return BEGIN_HISTORY_PY;
300 const char * PyInterp_base::getNext()
302 if(_ith != _history.end()){
305 if (_ith == _history.end())
306 return TOP_HISTORY_PY;
308 return (*_ith).c_str();
312 string PyInterp_base::getverr(){
313 PyLockWrapper aLock(_tstate);
314 PyObjWrapper v(PycStringIO->cgetvalue(_verr));
315 string aRet(PyString_AsString(v));
320 string PyInterp_base::getvout(){
321 PyLockWrapper aLock(_tstate);
322 PyObjWrapper v(PycStringIO->cgetvalue(_vout));
323 string aRet(PyString_AsString(v));