]> SALOME platform Git repositories - modules/gui.git/blob - src/PyConsole/PyConsole_Interp.cxx
Salome HOME
e915c185a3f84a3536e4cc4935945be162346dbb
[modules/gui.git] / src / PyConsole / PyConsole_Interp.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  SALOME SALOMEGUI : implementation of desktop and GUI kernel
23 //  File   : PyConsole_Interp.cxx
24 //  Author : Nicolas REJNERI
25 //  Module : SALOME
26 //
27 #include "PyConsole_Interp.h"
28
29 /*!
30   \class PyConsole_Interp
31   \brief Python interpreter to be embedded to the SALOME study's GUI.
32
33   Python interpreter is created one per SALOME study.
34
35   Call initialize method defined in the base class PyInterp_Interp,
36   to intialize interpreter after instance creation.
37
38   The method initialize() calls virtuals methods
39   - initPython()  to initialize global Python interpreter
40   - initState()   to initialize embedded interpreter state
41   - initContext() to initialize interpreter internal context
42   - initRun()     to prepare interpreter for running commands
43
44   /EDF-CCAR/
45   When SALOME uses multi Python interpreter feature, 
46   every study has its own interpreter and thread state (_tstate = Py_NewInterpreter()).
47   This is fine because every study has its own modules (sys.modules) stdout and stderr.
48
49   <b>But</b> some Python modules must be imported only once. In multi interpreter 
50   context Python modules (*.py) are imported several times.
51   For example, the PyQt module must be imported only once because 
52   it registers classes in a C module.
53
54   It's quite the same with omniorb modules (internals and generated with omniidl).
55
56   This problem is handled with "shared modules" defined in salome_shared_modules.py.
57   These "shared modules" are imported only once and only copied in all 
58   the other interpreters.
59
60   <b>But</b> it's not the only problem. Every interpreter has its own 
61   __builtin__ module. That's fine but if we have copied some modules 
62   and imported others problems may arise with operations that are not allowed
63   in restricted execution environment. So we must impose that all interpreters
64   have identical __builtin__ module.
65 */
66
67 /*!
68   \brief Constructor.
69
70   Creates new python interpreter.
71 */
72 PyConsole_Interp::PyConsole_Interp(): PyInterp_Interp()
73 {
74 }
75
76 /*!
77   \brief Destructor.
78
79   Does nothing for the moment.
80 */
81 PyConsole_Interp::~PyConsole_Interp()
82 {
83 }
84  
85 /*!
86   \brief Initialize internal Python interpreter state.
87   \return \c true on success
88 */
89 bool PyConsole_Interp::initState()
90 {
91   // The GIL is acquired and will be held on initState output
92   // It is the caller responsability to release the lock if needed
93   PyEval_AcquireLock();
94   _tstate = Py_NewInterpreter(); // create an interpreter and save current state
95   PySys_SetArgv(PyInterp_Interp::_argc,PyInterp_Interp::_argv); // initialize sys.argv
96   
97   if(!builtinmodule) // PAL18041: deepcopy function don't work in Salome
98   {
99     //builtinmodule is static member of PyInterp class
100     //If it is not NULL (initialized to the builtin module of the main interpreter
101     //all the sub interpreters will have the same builtin
102     //_interp is a static member and is the main interpreter
103     //The first time we initialized it to the builtin of main interpreter
104     builtinmodule=PyDict_GetItemString(_interp->modules, "__builtin__");
105   }
106
107   //If builtinmodule has been initialized all the sub interpreters
108   // will have the same __builtin__ module
109   if(builtinmodule){ 
110     PyObject *m = PyImport_GetModuleDict();
111     PyDict_SetItemString(m, "__builtin__", builtinmodule);
112     _tstate->interp->builtins = PyModule_GetDict(builtinmodule);
113     Py_INCREF(_tstate->interp->builtins);
114   }
115   PyEval_ReleaseThread(_tstate);
116   return true;
117 }
118
119 /*!
120   \brief Initialize python interpeter context.
121
122   The GIL is assumed to be held.
123   It is the caller responsability caller to acquire the GIL.
124   It will still be held on initContext() exit.
125
126   \return \c true on success
127 */
128 bool PyConsole_Interp::initContext()
129 {
130   PyObject *m = PyImport_AddModule("__main__");  // interpreter main module (module context)
131   if(!m){
132     PyErr_Print();
133     return false;
134   }  
135   _g = PyModule_GetDict(m);          // get interpreter dictionnary context
136
137   if(builtinmodule){
138     PyDict_SetItemString(_g, "__builtins__", builtinmodule); // assign singleton __builtin__ module
139   }
140   return true;
141 }