1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : PyInterp_Interp.cxx
24 // Author : Christian CAREMOLI, Paul RASCLE, EDF
27 #include "PyInterp_Interp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
30 #include <cStringIO.h>
31 #include <structmember.h>
39 #define TOP_HISTORY_PY "--- top of history ---"
40 #define BEGIN_HISTORY_PY "--- begin of history ---"
44 \brief Python GIL wrapper.
48 \brief Constructor. Automatically acquires GIL.
50 PyLockWrapper::PyLockWrapper()
52 _gil_state = PyGILState_Ensure();
56 \brief Destructor. Automatically releases GIL.
58 PyLockWrapper::~PyLockWrapper()
60 // if (myThreadState->interp == PyInterp_Interp::_interp)
61 // PyGILState_Release(_savestate);
63 // PyEval_ReleaseThread(myThreadState);
65 /* The destructor can never be called concurrently by two threads since it is called
66 * when the GIL is held - the below test should never run concurrently in two threads.
68 PyGILState_Release(_gil_state);
72 The following functions are used to hook the Python
77 PyStdOut_dealloc(PyStdOut *self)
83 PyStdOut_write(PyStdOut *self, PyObject *args)
87 if (!PyArg_ParseTuple(args, "t#:write",&c, &l))
96 self->_cb(self->_data,c);
103 PyStdOut_flush(PyStdOut *self)
109 static PyMethodDef PyStdOut_methods[] = {
110 {"write", (PyCFunction)PyStdOut_write, METH_VARARGS, PyDoc_STR("write(string) -> None")},
111 {"flush", (PyCFunction)PyStdOut_flush, METH_NOARGS, PyDoc_STR("flush() -> None")},
112 {NULL, NULL} /* sentinel */
115 static PyMemberDef PyStdOut_memberlist[] = {
116 {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0,
117 (char*)"flag indicating that a space needs to be printed; used by print"},
118 {NULL} /* Sentinel */
121 static PyTypeObject PyStdOut_Type = {
122 /* The ob_type field must be initialized in the module init function
123 * to be portable to Windows without using C++. */
124 PyObject_HEAD_INIT(NULL)
127 sizeof(PyStdOut), /*tp_basicsize*/
130 (destructor)PyStdOut_dealloc, /*tp_dealloc*/
137 0, /*tp_as_sequence*/
142 PyObject_GenericGetAttr, /*tp_getattro*/
143 /* softspace is writable: we must supply tp_setattro */
144 PyObject_GenericSetAttr, /* tp_setattro */
146 Py_TPFLAGS_DEFAULT, /*tp_flags*/
150 0, /*tp_richcompare*/
151 0, /*tp_weaklistoffset*/
154 PyStdOut_methods, /*tp_methods*/
155 PyStdOut_memberlist, /*tp_members*/
169 #define PyStdOut_Check(v) ((v)->ob_type == &PyStdOut_Type)
171 static PyStdOut* newPyStdOut( bool iscerr )
174 self = PyObject_New(PyStdOut, &PyStdOut_Type);
179 self->_iscerr = iscerr;
184 \class PyInterp_Interp
185 \brief Generic embedded Python interpreter.
188 int PyInterp_Interp::_argc = 1;
189 char* PyInterp_Interp::_argv[] = {(char*)""};
190 //PyObject* PyInterp_Interp::builtinmodule = NULL;
191 //PyThreadState* PyInterp_Interp::_gtstate = NULL;
192 //PyInterpreterState* PyInterp_Interp::_interp = NULL;
195 \brief Basic constructor.
197 After construction the interpreter instance successor classes
198 must call virtual method initalize().
200 PyInterp_Interp::PyInterp_Interp():
201 _vout(0), _verr(0), _context(0)
210 PyInterp_Interp::~PyInterp_Interp()
215 \brief Initialize embedded interpreter.
217 This method shoud be called after construction of the interpreter.
218 The method initialize() calls virtuals methods
219 - initPython() to initialize global Python interpreter
220 - initState() to initialize embedded interpreter state
221 - initContext() to initialize interpreter internal context
222 - initRun() to prepare interpreter for running commands
223 which should be implemented in the successor classes, according to the
224 embedded Python interpreter policy (mono or multi interpreter, etc).
226 void PyInterp_Interp::initialize()
228 _history.clear(); // start a new list of user's commands
229 _ith = _history.begin();
231 initPython(); // This also inits the multi-threading for Python (but w/o acquiring GIL)
233 //initState(); // [ABN] OBSOLETE
235 // ---- The rest of the initialisation process is done hodling the GIL
240 // used to interpret & compile commands - this is really imported here
241 // and only added again (with PyImport_AddModule) later on
242 PyObjWrapper m(PyImport_ImportModule("codeop"));
245 PyEval_ReleaseLock();
249 // Create python objects to capture stdout and stderr
250 _vout=(PyObject*)newPyStdOut( false ); // stdout
251 _verr=(PyObject*)newPyStdOut( true ); // stderr
253 // All the initRun outputs are redirected to the standard output (console)
257 void PyInterp_Interp::destroy()
264 \brief Initialize Python interpreter.
266 In case if Python is not initialized, it sets program name, initializes the single true Python
267 interpreter, sets program arguments, and initializes threads.
268 Otherwise, does nothing. This is important for light SALOME configuration,
269 as in full SALOME this is done at SalomeApp level.
270 \sa SalomeApp_PyInterp class and main() in SALOME_Session_Server
272 void PyInterp_Interp::initPython()
274 if (!Py_IsInitialized()){
275 // Python is not initialized
276 Py_SetProgramName(_argv[0]);
277 Py_Initialize(); // Initialize the interpreter
278 PySys_SetArgv(_argc, _argv);
280 PyEval_InitThreads(); // Create (and acquire) the Python global interpreter lock (GIL)
281 PyEval_ReleaseLock();
286 \brief Get embedded Python interpreter banner.
287 \return banner string
289 std::string PyInterp_Interp::getbanner() const
292 std::string aBanner("Python ");
293 aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
294 aBanner = aBanner + "\ntype help to get general information on environment\n";
299 \brief Initialize run command.
301 This method is used to prepare interpreter for running
304 \return \c true on success and \c false on error
306 bool PyInterp_Interp::initRun()
311 void PyInterp_Interp::closeContext()
316 \brief Compile Python command and evaluate it in the
317 python dictionary context if possible. This is not thread-safe.
318 This is the caller's responsability to make this thread-safe.
320 \param command Python command string
321 \param context Python context (dictionary)
322 \return -1 on fatal error, 1 if command is incomplete and 0
323 if command is executed successfully
325 static int run_command(const char *command, PyObject *context)
327 PyObject *m = PyImport_AddModule("codeop");
328 if(!m) { // Fatal error. No way to go on.
332 PyObjWrapper v(PyObject_CallMethod(m,(char*)"compile_command",(char*)"s",command));
334 // Error encountered. It should be SyntaxError,
335 //so we don't write out traceback
336 PyObjWrapper exception, value, tb;
337 PyErr_Fetch(&exception, &value, &tb);
338 PyErr_NormalizeException(&exception, &value, &tb);
339 PyErr_Display(exception, value, NULL);
342 else if (v == Py_None) {
343 // Incomplete text we return 1 : we need a complete text to execute
347 PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,context,context));
349 // Execution error. We return -1
353 // The command has been successfully executed. Return 0
358 void replaceAll(std::string& str, const std::string& from, const std::string& to) {
361 size_t start_pos = 0;
362 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
363 str.replace(start_pos, from.length(), to);
364 start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
368 \brief Compile Python command and evaluate it in the
369 python dictionary context if possible. Command might correspond to
370 the execution of a script with optional arguments.
371 In this case, command is:
372 execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
374 \param command Python command string
375 \param context Python context (dictionary)
376 \return -1 on fatal error, 1 if command is incomplete and 0
377 if command is executed successfully
379 static int compile_command(const char *command, PyObject *context)
381 // First guess if command is execution of a script with args, or a simple Python command
382 std::string singleCommand = command;
383 std::string commandArgs = "";
385 std::size_t pos = std::string(command).find("args:");
386 if (pos != std::string::npos) {
387 commandArgs = singleCommand.substr(pos+5);
388 commandArgs = commandArgs.substr(0, commandArgs.length()-3);
389 singleCommand = singleCommand.substr(0, pos-1)+"\")";
392 if (commandArgs.empty()) {
393 // process command: expression
394 // process command: execfile(r"/absolute/path/to/script.py") (no args)
395 return run_command(singleCommand.c_str(), context);
398 // process command: execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
399 std::string script = singleCommand.substr(11); // remove leading execfile(r"
400 script = script.substr(0, script.length()-2); // remove trailing ")
402 std::string preCommandBegin = "import sys; save_argv = sys.argv; sys.argv=[";
403 std::string preCommandEnd = "];";
404 replaceAll(commandArgs, ",", "\",\"");
405 commandArgs = "\""+commandArgs+"\"";
406 std::string completeCommand = preCommandBegin+"\""+script+"\","+commandArgs+preCommandEnd+singleCommand+";sys.argv=save_argv";
407 return run_command(completeCommand.c_str(), context);
412 \brief Run Python command - the command has to fit on a single line (no \n!).
413 Use ';' if you need multiple statements evaluated at once.
414 \param command Python command
415 \return command status
417 int PyInterp_Interp::run(const char *command)
420 return simpleRun(command);
424 * Called before a command is run (when calling run() method). Not thread-safe. Caller's responsability
425 * to acquire GIL if needed.
427 int PyInterp_Interp::beforeRun()
433 \brief Run Python command (used internally). Not thread-safe. GIL acquisition is caller's responsability.
434 \param command Python command
435 \param addToHistory if \c true (default), the command is added to the commands history
436 \return command status
438 int PyInterp_Interp::simpleRun(const char *command, const bool addToHistory)
440 if( addToHistory && strcmp(command,"") != 0 ) {
441 _history.push_back(command);
442 _ith = _history.end();
445 // Current stdout and stderr are saved
446 PyObject * oldOut = PySys_GetObject((char*)"stdout");
447 PyObject * oldErr = PySys_GetObject((char*)"stderr");
448 // Keep them alive (PySys_GetObject returned a *borrowed* ref!)
452 // Redirect outputs to SALOME Python console before treatment
453 PySys_SetObject((char*)"stderr",_verr);
454 PySys_SetObject((char*)"stdout",_vout);
456 int ier = compile_command(command,_context);
458 // Outputs are redirected to what they were before
459 PySys_SetObject((char*)"stdout",oldOut);
460 PySys_SetObject((char*)"stderr",oldErr);
466 \brief Get previous command in the commands history.
467 \return previous command
469 const char * PyInterp_Interp::getPrevious()
471 if(_ith != _history.begin()){
473 return (*_ith).c_str();
476 return BEGIN_HISTORY_PY;
480 \brief Get next command in the commands history.
483 const char * PyInterp_Interp::getNext()
485 if(_ith != _history.end()){
488 if (_ith == _history.end())
489 return TOP_HISTORY_PY;
491 return (*_ith).c_str();
495 \brief Set Python standard output device hook.
496 \param cb callback function
497 \param data callback function parameters
499 void PyInterp_Interp::setvoutcb(PyOutChanged* cb, void* data)
501 ((PyStdOut*)_vout)->_cb=cb;
502 ((PyStdOut*)_vout)->_data=data;
506 \brief Set Python standard error device hook.
507 \param cb callback function
508 \param data callback function parameters
510 void PyInterp_Interp::setverrcb(PyOutChanged* cb, void* data)
512 ((PyStdOut*)_verr)->_cb=cb;
513 ((PyStdOut*)_verr)->_data=data;