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, Adrien BRUNETON
27 #include "PyInterp_Interp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
28 #include "PyInterp_Utils.h"
31 #include <cStringIO.h>
32 #include <structmember.h>
40 #define TOP_HISTORY_PY "--- top of history ---"
41 #define BEGIN_HISTORY_PY "--- begin of history ---"
44 The following functions are used to hook the Python
49 PyStdOut_dealloc(PyStdOut *self)
55 PyStdOut_write(PyStdOut *self, PyObject *args)
59 if (!PyArg_ParseTuple(args, "t#:write",&c, &l))
68 self->_cb(self->_data,c);
75 PyStdOut_flush(PyStdOut *self)
81 static PyMethodDef PyStdOut_methods[] = {
82 {"write", (PyCFunction)PyStdOut_write, METH_VARARGS, PyDoc_STR("write(string) -> None")},
83 {"flush", (PyCFunction)PyStdOut_flush, METH_NOARGS, PyDoc_STR("flush() -> None")},
84 {NULL, NULL} /* sentinel */
87 static PyMemberDef PyStdOut_memberlist[] = {
88 {(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0,
89 (char*)"flag indicating that a space needs to be printed; used by print"},
93 static PyTypeObject PyStdOut_Type = {
94 /* The ob_type field must be initialized in the module init function
95 * to be portable to Windows without using C++. */
96 PyObject_HEAD_INIT(NULL)
99 sizeof(PyStdOut), /*tp_basicsize*/
102 (destructor)PyStdOut_dealloc, /*tp_dealloc*/
109 0, /*tp_as_sequence*/
114 PyObject_GenericGetAttr, /*tp_getattro*/
115 /* softspace is writable: we must supply tp_setattro */
116 PyObject_GenericSetAttr, /* tp_setattro */
118 Py_TPFLAGS_DEFAULT, /*tp_flags*/
122 0, /*tp_richcompare*/
123 0, /*tp_weaklistoffset*/
126 PyStdOut_methods, /*tp_methods*/
127 PyStdOut_memberlist, /*tp_members*/
141 #define PyStdOut_Check(v) ((v)->ob_type == &PyStdOut_Type)
143 static PyStdOut* newPyStdOut( bool iscerr )
146 self = PyObject_New(PyStdOut, &PyStdOut_Type);
151 self->_iscerr = iscerr;
156 \class PyInterp_Interp
157 \brief Generic embedded Python interpreter.
160 int PyInterp_Interp::_argc = 1;
161 char* PyInterp_Interp::_argv[] = {(char*)""};
164 \brief Basic constructor.
166 After construction the interpreter instance successor classes
167 must call virtual method initalize().
169 PyInterp_Interp::PyInterp_Interp():
170 _vout(0), _verr(0), _local_context(0), _global_context(0)
179 PyInterp_Interp::~PyInterp_Interp()
185 \brief Initialize embedded interpreter.
187 This method shoud be called after construction of the interpreter.
188 The method initialize() calls virtuals methods
189 - initPython() to initialize global Python interpreter
190 - initContext() to initialize interpreter internal context
191 - initRun() to prepare interpreter for running commands
192 which should be implemented in the successor classes, according to the
193 embedded Python interpreter policy (mono or multi interpreter, etc).
195 void PyInterp_Interp::initialize()
197 _history.clear(); // start a new list of user's commands
198 _ith = _history.begin();
200 initPython(); // This also inits the multi-threading for Python (but w/o acquiring GIL)
202 //initState(); // [ABN] OBSOLETE
204 // ---- The rest of the initialisation process is done hodling the GIL
209 // used to interpret & compile commands - this is really imported here
210 // and only added again (with PyImport_AddModule) later on
211 PyObjWrapper m(PyImport_ImportModule("codeop"));
217 // Create python objects to capture stdout and stderr
218 _vout=(PyObject*)newPyStdOut( false ); // stdout
219 _verr=(PyObject*)newPyStdOut( true ); // stderr
221 // All the initRun outputs are redirected to the standard output (console)
225 void PyInterp_Interp::destroy()
232 \brief Initialize Python interpreter.
234 In case if Python is not initialized, it sets program name, initializes the single true Python
235 interpreter, sets program arguments, and initializes threads.
236 Otherwise, does nothing. This is important for light SALOME configuration,
237 as in full SALOME this is done at SalomeApp level.
238 \sa SalomeApp_PyInterp class and main() in SALOME_Session_Server
240 void PyInterp_Interp::initPython()
242 if (!Py_IsInitialized()){
243 // Python is not initialized
244 Py_SetProgramName(_argv[0]);
245 Py_Initialize(); // Initialize the interpreter
246 PySys_SetArgv(_argc, _argv);
248 PyEval_InitThreads(); // Create (and acquire) the Python global interpreter lock (GIL)
249 PyEval_ReleaseLock();
254 \brief Get embedded Python interpreter banner.
255 \return banner string
257 std::string PyInterp_Interp::getbanner() const
260 std::string aBanner("Python ");
261 aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
262 aBanner = aBanner + "\ntype help to get general information on environment\n";
267 \brief Initialize run command.
269 This method is used to prepare interpreter for running
272 \return \c true on success and \c false on error
274 bool PyInterp_Interp::initRun()
280 * Initialize context dictionaries. GIL is held already.
281 * The code executed in an embedded interpreter is expected to be run at the module
282 * level, in which case local and global context have to be the same dictionary.
283 * See: http://stackoverflow.com/questions/12265756/c-python-running-python-code-within-a-context
284 * for an explanation.
286 bool PyInterp_Interp::initContext()
288 PyObject *m = PyImport_AddModule("__main__"); // interpreter main module (module context)
293 _global_context = PyModule_GetDict(m); // get interpreter global variable context
294 Py_INCREF(_global_context);
295 _local_context = _global_context;
300 * Destroy context dictionaries. GIL is held already.
302 void PyInterp_Interp::closeContext()
304 Py_XDECREF(_global_context);
305 // both _global and _local point to the same Python object:
306 // Py_XDECREF(_local_context);
310 \brief Compile Python command and evaluate it in the
311 python dictionary contexts if possible. This is not thread-safe.
312 This is the caller's responsability to make this thread-safe.
314 \param command Python command string
315 \return -1 on fatal error, 1 if command is incomplete and 0
316 if command is executed successfully
318 static int run_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
320 PyObject *m = PyImport_AddModule("codeop");
321 if(!m) { // Fatal error. No way to go on.
326 // PyObjWrapper v(Py_CompileString(command, "<salome_input>", Py_file_input));
327 PyObjWrapper v(PyObject_CallMethod(m,(char*)"compile_command",(char*)"s",command));
329 // Error encountered. It should be SyntaxError,
330 //so we don't write out traceback
331 PyObjWrapper exception, value, tb;
332 PyErr_Fetch(&exception, &value, &tb);
333 PyErr_NormalizeException(&exception, &value, &tb);
334 PyErr_Display(exception, value, NULL);
337 else if (v == Py_None) {
338 // Incomplete text we return 1 : we need a complete text to execute
342 PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,global_ctxt, local_ctxt));
344 // Execution error. We return -1
348 // The command has been successfully executed. Return 0
353 void replaceAll(std::string& str, const std::string& from, const std::string& to) {
356 size_t start_pos = 0;
357 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
358 str.replace(start_pos, from.length(), to);
359 start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
363 \brief Compile Python command and evaluate it in the
364 python dictionary context if possible. Command might correspond to
365 the execution of a script with optional arguments.
366 In this case, command is:
367 execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
369 \param command Python command string
370 \param context Python context (dictionary)
371 \return -1 on fatal error, 1 if command is incomplete and 0
372 if command is executed successfully
374 static int compile_command(const char *command, PyObject * global_ctxt, PyObject * local_ctxt)
376 // First guess if command is execution of a script with args, or a simple Python command
377 std::string singleCommand = command;
378 std::string commandArgs = "";
380 std::size_t pos = std::string(command).find("args:");
381 if (pos != std::string::npos) {
382 commandArgs = singleCommand.substr(pos+5);
383 commandArgs = commandArgs.substr(0, commandArgs.length()-3);
384 singleCommand = singleCommand.substr(0, pos-1)+"\")";
387 if (commandArgs.empty()) {
388 // process command: expression
389 // process command: execfile(r"/absolute/path/to/script.py") (no args)
390 return run_command(singleCommand.c_str(), global_ctxt, local_ctxt);
393 // process command: execfile(r"/absolute/path/to/script.py [args:arg1,...,argn]")
394 std::string script = singleCommand.substr(11); // remove leading execfile(r"
395 script = script.substr(0, script.length()-2); // remove trailing ")
397 std::string preCommandBegin = "import sys; save_argv = sys.argv; sys.argv=[";
398 std::string preCommandEnd = "];";
399 replaceAll(commandArgs, ",", "\",\"");
400 commandArgs = "\""+commandArgs+"\"";
401 std::string completeCommand = preCommandBegin+"\""+script+"\","+commandArgs+preCommandEnd+singleCommand+";sys.argv=save_argv";
402 return run_command(completeCommand.c_str(), global_ctxt, local_ctxt);
407 \brief Run Python command - the command has to fit on a single line (no \n!).
408 Use ';' if you need multiple statements evaluated at once.
409 \param command Python command
410 \return command status
412 int PyInterp_Interp::run(const char *command)
415 return simpleRun(command);
419 * Called before a command is run (when calling run() method). Not thread-safe. Caller's responsability
420 * to acquire GIL if needed.
422 int PyInterp_Interp::beforeRun()
428 \brief Run Python command (used internally). Not thread-safe. GIL acquisition is caller's responsability.
429 \param command Python command
430 \param addToHistory if \c true (default), the command is added to the commands history
431 \return command status
433 int PyInterp_Interp::simpleRun(const char *command, const bool addToHistory)
435 if( addToHistory && strcmp(command,"") != 0 ) {
436 _history.push_back(command);
437 _ith = _history.end();
440 // Current stdout and stderr are saved
441 PyObject * oldOut = PySys_GetObject((char*)"stdout");
442 PyObject * oldErr = PySys_GetObject((char*)"stderr");
443 // Keep them alive (PySys_GetObject returned a *borrowed* ref!)
447 // Redirect outputs to SALOME Python console before treatment
448 PySys_SetObject((char*)"stderr",_verr);
449 PySys_SetObject((char*)"stdout",_vout);
451 int ier = compile_command(command, _global_context, _local_context);
453 // Outputs are redirected to what they were before
454 PySys_SetObject((char*)"stdout",oldOut);
455 PySys_SetObject((char*)"stderr",oldErr);
461 \brief Get previous command in the commands history.
462 \return previous command
464 const char * PyInterp_Interp::getPrevious()
466 if(_ith != _history.begin()){
468 return (*_ith).c_str();
471 return BEGIN_HISTORY_PY;
475 \brief Get next command in the commands history.
478 const char * PyInterp_Interp::getNext()
480 if(_ith != _history.end()){
483 if (_ith == _history.end())
484 return TOP_HISTORY_PY;
486 return (*_ith).c_str();
490 \brief Set Python standard output device hook.
491 \param cb callback function
492 \param data callback function parameters
494 void PyInterp_Interp::setvoutcb(PyOutChanged* cb, void* data)
496 ((PyStdOut*)_vout)->_cb=cb;
497 ((PyStdOut*)_vout)->_data=data;
501 \brief Set Python standard error device hook.
502 \param cb callback function
503 \param data callback function parameters
505 void PyInterp_Interp::setverrcb(PyOutChanged* cb, void* data)
507 ((PyStdOut*)_verr)->_cb=cb;
508 ((PyStdOut*)_verr)->_data=data;