Salome HOME
PR: merge branch CCAR_br1
[modules/kernel.git] / src / SALOMEGUI / QAD_PyInterp.cxx
1 using namespace std;
2 using namespace std;
3 //=============================================================================
4 //  File      : QAD_PyInterp.cxx
5 //  Created   : Thu Jun 14 14:03:58 2001
6 //  Author    : Nicolas REJNERI
7 //  Project   : SALOME
8 //  Module    : SALOMEGUI
9 //  Copyright : Open CASCADE
10 //  $Header$
11 //=============================================================================
12
13 //    TODO: 
14 //    control & limit history length 
15
16 #include "QAD_PyInterp.h"
17 #include "utilities.h"
18
19 /*!
20  * constructor : multi Python interpreter, one per SALOME study.
21  * calls initialize method defined in base class, which calls virtual methods
22  * initstate & initcontext redefined here.
23  */
24 QAD_PyInterp::QAD_PyInterp(): PyInterp_base()
25 {
26   initialize();
27 }
28
29 QAD_PyInterp::~QAD_PyInterp()
30 {
31 }
32  
33 /*!
34  * EDF-CCAR
35  * When SALOME uses multi Python interpreter feature,
36  * Every study has its own interpreter and thread state (_tstate = Py_NewInterpreter())
37  * This is fine because every study has its own modules (sys.modules) stdout and stderr
38  * BUT some Python modules must be imported only once. In multi interpreter context Python
39  * modules (*.py) are imported several times.
40  * The pyqt module must be imported only once because it registers classes in a C module.
41  * It's quite the same with omniorb modules (internals and generated with omniidl)
42  * This problem is handled with "shared modules" defined in salome_shared_modules.py
43  * These "shared modules" are imported only once and only copied in all the other interpreters
44  * BUT it's not the only problem. Every interpreter has its own __builtin__ module. That's fine
45  * but if we have copied some modules and imported others problems may arise with operations that
46  * are not allowed in restricted execution environment. So we must impose that all interpreters
47  * have identical __builtin__ module.
48  * That's all, for the moment ...
49  */
50
51 void QAD_PyInterp::initState()
52 {
53   MESSAGE("QAD_PyInterp::initState");
54   salomeAcquireLock();           //acquire python global lock (one for all interpreters)
55   _tstate = Py_NewInterpreter(); //create an interpreter and save current state
56   SCRUTE(_tstate);
57   SCRUTE(PyInterp_base::_argc);
58   SCRUTE(PyInterp_base::_argv[0]);
59   PySys_SetArgv(PyInterp_base::_argc,PyInterp_base::_argv);    // initialize sys.argv
60
61   if(builtinmodule == NULL)return;
62   /*
63    * If builtinmodule has been initialized all the sub interpreters
64    * will have the same __builtin__ module
65    */
66   PyObject *m=PyImport_GetModuleDict();
67   PyDict_SetItemString(m, "__builtin__", builtinmodule);
68   SCRUTE(builtinmodule->ob_refcnt);                            // builtinmodule reference counter
69   _tstate->interp->builtins = PyModule_GetDict(builtinmodule);
70   Py_INCREF(_tstate->interp->builtins);
71 }
72
73 void QAD_PyInterp::initContext()
74 {
75   MESSAGE("QAD_PyInterp::initContext");
76   PyObject *m;
77   m=PyImport_AddModule("__main__");  // interpreter main module (module context)
78   if(m == NULL)
79     {
80       MESSAGE("problem...");
81       PyErr_Print();
82       ASSERT(0);
83       salomeReleaseLock(); 
84       return;
85     }  
86   _g = PyModule_GetDict(m);          // get interpreter dictionnary context
87   SCRUTE(_g);
88
89   if(builtinmodule)
90     {
91       PyDict_SetItemString(_g, "__builtins__", builtinmodule); // assign singleton __builtin__ module
92     }
93 // Debut modif CCAR
94   /*
95    * Import special module to change the import mechanism
96    */
97   m =PyImport_ImportModule("import_hook");
98   if(m == NULL){
99       MESSAGE("initContext: problem with import_hook import");
100       PyErr_Print();
101       PyErr_Clear();
102       ASSERT(0);
103   }
104   /*
105    * Call init_shared_modules to initialize the shared import mechanism for modules 
106    * that must not be imported twice
107    */
108   if(m != NULL){
109       m= PyObject_CallMethod(m,
110                          "init_shared_modules","O",salome_shared_modules_module);
111       if (m == NULL){
112           MESSAGE("initContext: problem with init_shared_modules call");
113           PyErr_Print();
114           PyErr_Clear();
115           ASSERT(0);
116       }
117   }
118 // Fin   modif CCAR
119
120 }