Salome HOME
CCAR (EDF-RD): CCAR_br1
authorcaremoli <caremoli>
Thu, 5 Jun 2003 17:54:21 +0000 (17:54 +0000)
committercaremoli <caremoli>
Thu, 5 Jun 2003 17:54:21 +0000 (17:54 +0000)
- First modification : runSalome.py can be imported or exec'ed. I'm not sure
      it's really possible to use startSalome or startGUI from another Python module
      but it's a first step.
- Second modification : new import mechanism for shared python modules (CORBA, qt,..)
      This mechanism implemented in the new module import_hook replaces the
   standard import mechanism. New module kernel_shared_modules helps to define those modules
   that must be imported only once. Other modules can have their own <module>_shared_modules
- 3rd : some minor improvments in Python interpretor (more error trace) and link to new import
      mechanism.
- 4th : modification of check_sip and check_pyqt to recognize different versions 3.3, ..., 3.5

bin/runSalome.py
salome_adm/unix/config_files/check_pyqt.m4
salome_adm/unix/config_files/check_sip.m4
src/SALOMEGUI/PyInterp_base.cxx
src/SALOMEGUI/QAD_PyInterp.cxx
src/SALOME_SWIG/Makefile.in
src/SALOME_SWIG/salome_shared_modules.py

index 070be63dd77fa4877d0843c6cde5462101bd3ba7..cc3a72b16cf2ef65ba86d4a0296ed9d9f207e1bf 100755 (executable)
@@ -138,9 +138,9 @@ liste_modules[:0]=["KERNEL"]
 #print liste_modules
 #print modules_root_dir
 
+os.environ["SALOMEPATH"]=":".join(modules_root_dir.values())
 if "SUPERV" in liste_modules:with_container_superv=1
 
-import orbmodule
 
 # -----------------------------------------------------------------------------
 #
@@ -270,9 +270,12 @@ for module in liste_modules_reverse:
     add_python_path(os.path.join(module_root_dir,"bin","salome"))
     add_python_path(os.path.join(module_root_dir,"lib",python_version,"site-packages","salome"))
     add_python_path(os.path.join(module_root_dir,"lib","salome"))
+    add_python_path(os.path.join(module_root_dir,"lib",python_version,"site-packages","salome","shared_modules"))
 
 #print "PYTHONPATH=",sys.path
 
+import orbmodule
+
 #
 # -----------------------------------------------------------------------------
 #
@@ -432,41 +435,42 @@ def startSalome():
 # -----------------------------------------------------------------------------
 #
 
-clt=None
-try:
-   clt = startSalome()
-except:
+if __name__ == "__main__":
+   clt=None
+   try:
+      clt = startSalome()
+   except:
+      print
+      print
+      print "--- erreur au lancement Salome ---"
+   
+   #print process_id
+   
+   
+   filedict='/tmp/'+os.getenv('USER')+'_SALOME_pidict'
+   #filedict='/tmp/'+os.getlogin()+'_SALOME_pidict'
+   
+   fpid=open(filedict, 'w')
+   pickle.dump(process_id,fpid)
+   fpid.close()
+   
    print
+   print "Sauvegarde du dictionnaire des process dans ", filedict
+   print "Pour tuer les process SALOME, executer : python killSalome.py depuis"
+   print "une console, ou bien killSalome() depuis le present interpreteur,"
+   print "s'il n'est pas fermé."
    print
-   print "--- erreur au lancement Salome ---"
-
-#print process_id
-
-
-filedict='/tmp/'+os.getenv('USER')+'_SALOME_pidict'
-#filedict='/tmp/'+os.getlogin()+'_SALOME_pidict'
-
-fpid=open(filedict, 'w')
-pickle.dump(process_id,fpid)
-fpid.close()
-
-print
-print "Sauvegarde du dictionnaire des process dans ", filedict
-print "Pour tuer les process SALOME, executer : python killSalome.py depuis"
-print "une console, ou bien killSalome() depuis le present interpreteur,"
-print "s'il n'est pas fermé."
-print
-print "runSalome, avec l'option --killall, commence par tuer les process restants d'une execution précédente."
-print
-print "Pour lancer uniquement le GUI, executer startGUI() depuis le present interpreteur,"
-print "s'il n'est pas fermé."
-
-#
-#  Impression arborescence Naming Service
-#
-
-if clt != None:
-  print
-  print " --- registered objects tree in Naming Service ---"
-  clt.showNS()
-
+   print "runSalome, avec l'option --killall, commence par tuer les process restants d'une execution précédente."
+   print
+   print "Pour lancer uniquement le GUI, executer startGUI() depuis le present interpreteur,"
+   print "s'il n'est pas fermé."
+   
+   #
+   #  Impression arborescence Naming Service
+   #
+   
+   if clt != None:
+     print
+     print " --- registered objects tree in Naming Service ---"
+     clt.showNS()
+   
index ec915a4ad412e783ea4d7ec56066696225bd73f1..62b4668b693d83cb36940779dbc4de35c0269763 100644 (file)
@@ -14,25 +14,60 @@ else
   pyqt_ok=yes
 fi
 
-if test "x$pyqt_ok" = xno -o ! -d "$PYQTDIR" -o ! -d "$PYQTDIR"/sip ; then
+version=`python -c "import qt;print qt.PYQT_VERSION"`
+case "$version" in
+     3.2*)
+       pyqt_vers=old ;;
+     3.3*)
+       pyqt_vers=old ;;
+     3.4*)
+       pyqt_vers=new ;;
+     3.5*)
+       pyqt_vers=new ;;
+        *)
+       pyqt_vers=no ;;
+esac
+
+if test "x$pyqt_ok" = xno -o ! -d "$PYQTDIR" ; then
   AC_MSG_RESULT(no)
   AC_MSG_WARN(pyqt not found)
 else
-  AC_CHECK_FILES("$PYQTDIR"/qt.py "$PYQTDIR"/libqtcmodule.so,pyqt_ok=yes,pyqt_ok=no) 
-  if test "x$pyqt_ok" = xno ; then
-     AC_MSG_RESULT(no)
-     AC_MSG_WARN(pyqt not found)
-  else
-     PYQT_ROOT=$PYQTDIR
-     PYQT_INCLUDES="-I$PYQTDIR/sip"
-     PYQT_LIBS="-L$PYQTDIR -lqtcmodule"
-
-     AC_SUBST(PYQT_ROOT)
-     AC_SUBST(PYQT_INCLUDES)
-     AC_SUBST(PYQT_LIBS)
-
-     AC_MSG_RESULT(yes)
-  fi
+
+    pyqt_ok=no
+
+    if test "x$pyqt_vers" = "xold"
+    then
+        AC_CHECK_FILES("$PYQTDIR"/qt.py "$PYQTDIR"/libqtcmodule.so,pyqt_ok=yes,pyqt_ok=no) 
+        if test "x$pyqt_ok" = xno -o ! -d "$PYQTDIR"/sip ; then
+           AC_MSG_RESULT(no)
+           AC_MSG_WARN(pyqt not found)
+        else
+           PYQT_ROOT=$PYQTDIR
+           PYQT_INCLUDES="-I$PYQTDIR/sip"
+          PYQT_LIBS="-L${PYTHON_PREFIX}/lib/python${PYTHON_VERSION}/site-packages -L$PYQTDIR -lqtcmodule"
+           AC_SUBST(PYQT_ROOT)
+           AC_SUBST(PYQT_INCLUDES)
+           AC_SUBST(PYQT_LIBS)
+           AC_MSG_RESULT(yes)
+        fi
+    fi
+
+    if test "x$pyqt_vers" = "xnew"
+    then
+        AC_CHECK_FILES("$PYQTDIR"/lib/qt.py "$PYQTDIR"/lib/libqtcmodule.so,pyqt_ok=yes,pyqt_ok=no) 
+        if test "x$pyqt_ok" = xno ; then
+           AC_MSG_RESULT(no)
+           AC_MSG_WARN(pyqt not found)
+        else
+           PYQT_ROOT=$PYQTDIR
+           PYQT_INCLUDES="-I$PYQTDIR/sip"
+           PYQT_LIBS="-L$PYQTDIR/lib -lqtcmodule"
+           AC_SUBST(PYQT_ROOT)
+           AC_SUBST(PYQT_INCLUDES)
+           AC_SUBST(PYQT_LIBS)
+           AC_MSG_RESULT(yes)
+        fi
+    fi
 fi
 
 AC_ARG_WITH(pyuic,
@@ -54,14 +89,10 @@ else
        else
          PYQT_SIPS=${PYQT_SIPS}
        fi
-       PYQT_LIBS="-L${PYTHON_PREFIX}/lib/python${PYTHON_VERSION}/site-packages ${PYQT_LIBS}"
 fi
 
 AC_SUBST(PYUIC)
 AC_SUBST(PYQT_SIPS)
-AC_SUBST(PYQT_LIBS)
-
-
 
 AC_MSG_RESULT(for pyqt: $pyqt_ok)
 
index 7808c3e6708819f22a55ec1c5d182d1259b1f2b7..a6714b238c0ac91e9fc98009a315c2715e770f82 100644 (file)
@@ -17,9 +17,38 @@ then
     sip_ok=no
     AC_MSG_RESULT(sip not in PATH variable)
 else
+    version=`sip -V`
+    case "$version" in
+         3.2*)
+           sip_vers=old ;;
+         3.3*)
+           sip_vers=old ;;
+         3.4*)
+           sip_vers=new ;;
+         3.5*)
+           sip_vers=new ;;
+           *)
+           sip_vers=no ;;
+    esac
+
+    sip_ok=no
+
+    if test "x$sip_vers" = "xold"
+    then
+        sip_ok=yes
        SIP_ROOT="$SIPDIR"
        SIP_INCLUDES="${PYTHON_INCLUDES} -I${SIPDIR}"
        SIP_LIBS="-L${PYTHON_PREFIX}/lib/python${PYTHON_VERSION}/site-packages -L${SIPDIR} -lsip"
+    fi
+
+    if test "x$sip_vers" = "xnew"
+    then
+        sip_ok=yes
+       SIP_ROOT="$SIPDIR"
+       SIP_INCLUDES="${PYTHON_INCLUDES} -I${SIPDIR}/include"
+       SIP_LIBS="-L${SIPDIR}/lib -lsip"
+    fi
+
 fi
 
 AC_SUBST(SIP)
index 52aa2c19f0a78cc49c6527c54c9f0ea694f1f6fa..7356b84295492472fbfc9b739c9c89ec5edc4bc2 100644 (file)
@@ -101,8 +101,14 @@ void init_python()
    */
 
   PyInterp_base::salome_shared_modules_module =PyImport_ImportModule("salome_shared_modules");
+  if(PyInterp_base::salome_shared_modules_module == NULL){
+      MESSAGE("init_python: problem with salome_shared_modules import");
+      PyErr_Print();
+      PyErr_Clear();
+      salomeReleaseLock();
+      return;
+  }
   SCRUTE(PyInterp_base::salome_shared_modules_module->ob_refcnt);
-
   salomeReleaseLock();
 }
 
@@ -133,9 +139,17 @@ int compile_command(const char *command,PyObject *context)
   if (v == NULL)
     {
       /*
-       * Error encountered. It could be SyntaxError
+       * Error encountered. It should be SyntaxError
+       * so we don't write out traceback
        */
-      PyErr_Print();
+      PyObject *exception,*value,*tb;
+      PyErr_Fetch(&exception, &value, &tb);
+      PyErr_NormalizeException(&exception, &value, &tb);
+      PyErr_Display(exception, value, NULL);
+      Py_XDECREF(exception);
+      Py_XDECREF(value);
+      Py_XDECREF(tb);
+
       return -1;
     }
   else if (v == Py_None)
@@ -211,8 +225,8 @@ void PyInterp_base::initialize()
   if(m == NULL)
     {
       MESSAGE("Problem...");
-      ASSERT(0);
       PyErr_Print();
+      ASSERT(0);
       salomeReleaseLock(); 
       return;
     }   
index f4c0da963de2316bad8458c858a65a10aac17597..e3996723b17c4743104b6a6fb234781f35f8c9db 100644 (file)
@@ -78,8 +78,8 @@ void QAD_PyInterp::initContext()
   if(m == NULL)
     {
       MESSAGE("problem...");
-      ASSERT(0);
       PyErr_Print();
+      ASSERT(0);
       salomeReleaseLock(); 
       return;
     }  
@@ -90,21 +90,31 @@ void QAD_PyInterp::initContext()
     {
       PyDict_SetItemString(_g, "__builtins__", builtinmodule); // assign singleton __builtin__ module
     }
+// Debut modif CCAR
   /*
-   * Call salome_shared_modules to import salome shared modules that must not be initialized twice
-   * so import_shared_modules makes only a copy of the modules in _tstate->interp->modules
-   * (sys.modules)
+   * Import special module to change the import mechanism
    */
-  m= PyObject_CallMethod(salome_shared_modules_module,
-                        "import_shared_modules","O",
-                        _tstate->interp->modules);
-  if (m == NULL)
-    {
-      /*
-       * Problem  , print it
-       */
-      MESSAGE("problem...");
-      ASSERT(0);
+  m =PyImport_ImportModule("import_hook");
+  if(m == NULL){
+      MESSAGE("initContext: problem with import_hook import");
       PyErr_Print();
-    }
+      PyErr_Clear();
+      ASSERT(0);
+  }
+  /*
+   * Call init_shared_modules to initialize the shared import mechanism for modules 
+   * that must not be imported twice
+   */
+  if(m != NULL){
+      m= PyObject_CallMethod(m,
+                        "init_shared_modules","O",salome_shared_modules_module);
+      if (m == NULL){
+          MESSAGE("initContext: problem with init_shared_modules call");
+          PyErr_Print();
+          PyErr_Clear();
+          ASSERT(0);
+      }
+  }
+// Fin   modif CCAR
+
 }
index 3475d77dc4052661f9d56584db1eea7c5508555f..b247115741070d57a41a9817a5785cfb322d104c 100644 (file)
@@ -22,7 +22,9 @@ LIB = libSALOME_Swigcmodule.la
 LIB_SRC = 
 
 SWIG_DEF = libSALOME_Swig.i
-EXPORT_PYSCRIPTS = libSALOME_Swig.py Help.py PyInterp.py salome.py examplevtk1.py supervisionexample.py supervisiongeomexample.py salome_shared_modules.py batchmode_salome.py test_table.py test_big_table.py test_many_objects.py
+EXPORT_PYSCRIPTS = libSALOME_Swig.py Help.py PyInterp.py salome.py examplevtk1.py supervisionexample.py supervisiongeomexample.py salome_shared_modules.py batchmode_salome.py test_table.py test_big_table.py test_many_objects.py import_hook.py
+
+EXPORT_SHAREDPYSCRIPTS=kernel_shared_modules.py
 
 LIB_CLIENT_IDL = SALOMEDS.idl \
                 SALOME_Exception.idl
index 4f6d14c66df307e2ad01871675572d93aecdf879..de2b8742d34c86b15a89526af6411087f37b63f8 100644 (file)
-from SALOME_utilities import *
-
-"""
 """
-MESSAGE( "Module salome_shared_modules" )
-
-modules={}
-try:
-  # We try to import PyQt module. If present we import it
-  # as a "shared" module
-  import qt
-  modules["qt"]=qt.__dict__
-except:
-  pass
-
-# We keep in modules a copy of dictionnary modules
-# that need to be imported only once in multi-study context
-
-# Specific case : omniORB
-import omniORB
-modules["omniORB"]=omniORB.__dict__.copy()
-import omniORB.CORBA
-modules["omniORB.CORBA"]=omniORB.CORBA.__dict__.copy()
-modules["CORBA"]=modules["omniORB.CORBA"]
-import CosNaming
-modules["CosNaming"]=CosNaming.__dict__.copy()
-# end omniORB
-
-#
-# We search all Python CORBA (omniorb) modules.
-# A Python CORBA module has 2 associated Python packages 
-# These packages are named : <module_name> and <module_name>__POA
-#
-
-# 
-# SALOMEDS must be imported first, at least before any CORBA module
-# that references it.
-# It seems that import order of related CORBA modules is important
-# Perhaps, it's not sufficient so you should complete the list ???
-#
-import SALOMEDS
-import Engines
+This module with help of import_hook and *_shared_modules
+filters imports when using the embedded Python interpretor.
+
+Some imports can't be done more than once.
+This is related to the multi study feature that is implemented
+by using the Python multi interpreter feature.
+Some modules register objects or classes by calling modules
+implemented in C. These operations can't be done multiple times.
+So it's very important to control these imports.
+
+Examples:
+  - PyQt : import qt calls a C module to register classes
+  - OmniORB : import *_idl calls a C module to register CORBA interfaces
+
+Usage:
+  - First : the module salome_shared_modules is imported by main Python interpretor.
+    It will keep a dictionnary and a list that are shared among all
+    the subinterpretors and imports import_hook module that replaces
+    the standard import mechanism par one that prevents more than one import
+    for some modules identified by name (call register_name) or by a 
+    validator (call register_pattern).
+
+  Calls to register_name and register_pattern are done in modules named *_shared_modules
+  that could be found in the path SALOMEPATH
 
+"""
 import glob,os,sys
 
-repertoire=os.path.dirname(__file__)
-path=[repertoire,]
+import import_hook
+# shared_imported, patterns, register_name, register_pattern
+# will be shared by all Python sub interpretors
+from import_hook import shared_imported
+from import_hook import patterns
+from import_hook import register_name
+from import_hook import register_pattern
 
-# KERNEL is defined in KERNELCatalog
-#KERNEL_ROOT_DIR = os.getenv("KERNEL_ROOT_DIR")
-#if KERNEL_ROOT_DIR != None:
-#      path.append(os.path.join(KERNEL_ROOT_DIR,"lib","python"+sys.version[:3],"site-packages","salome"))
+register_name("salome_shared_modules")
 
+# Get the SALOMEPATH if set or else use KERNEL_ROOT_DIR that should be set.
+salome_path=os.environ.get("SALOMEPATH",os.getenv("KERNEL_ROOT_DIR"))
 
-#
-import SALOME_ModuleCatalog
-from SALOME_NamingServicePy import * 
-orb = CORBA.ORB_init([''], CORBA.ORB_ID)
-ns = SALOME_NamingServicePy_i(orb)
-modulecatalog = ns.Resolve('/Kernel/ModulCatalog')
-compos = []
-compos = modulecatalog.GetComponentList()
-
-for name in compos:
-       print name
-       MODULE_ROOT_DIR = os.getenv( name + "_ROOT_DIR" )
-       print MODULE_ROOT_DIR
-
-       if MODULE_ROOT_DIR != None:
-               path.append(os.path.join(MODULE_ROOT_DIR,"lib","python"+sys.version[:3],"site-packages","salome"))
-
-#SALOME_ROOT_DIR = os.getenv("SALOME_ROOT_DIR")
-#if SALOME_ROOT_DIR != None:
-#      path.append(os.path.join(SALOME_ROOT_DIR,"lib","python"+sys.version[:3],"site-packages","salome"))
-
-#SALOME_SITE_DIR = os.getenv("SALOME_SITE_DIR")
-#if SALOME_SITE_DIR != None:
-#        SALOME_SITE_NAME = os.getenv("SALOME_SITE_NAME")
-#        if SALOME_SITE_NAME != None:
-#              path.append(os.path.join(SALOME_SITE_DIR,"lib","python"+sys.version[:3],"site-packages",SALOME_SITE_NAME))
-
-MESSAGE( str(path) )
+list_modules=[]
 
+# Import all *_shared_modules in the path and store them in list_modules
+path=salome_path.split(":")
 for rep in path:
-   # Add rep directory in the Python path to be able to import modules 
-   sys.path[:0]=[rep]
-   listdir=glob.glob(os.path.join(rep,"*__POA"))
-   for elem in listdir:
-      if os.path.isdir(elem):
-         # Found a directory (Python package) named *__POA 
-         module__POA=os.path.basename(elem)
-         module=module__POA[:-5]
-         MESSAGE( "Import CORBA module: " + module + ".\n Directory: " + os.path.abspath(elem)[:-5] )
-         mod=__import__(module)
-         # force the reload of CORBA module to resolve all the include relations between modules
-         # specific of omniORBpy implementation (1.5)
-         reload(mod)
-         modules[module]=mod.__dict__.copy()
-   # Now we import modules found in shared_modules directory
-   r=os.path.join(rep,"shared_modules")
-   MESSAGE( r )
-   if os.path.isdir(r):
-      sys.path[:0]=[r]
-      listfich=glob.glob(os.path.join(r,"*.py"))
-      MESSAGE( str(listfich) )
-      for m in listfich:
-         module=os.path.basename(m)[:-3]
-         MESSAGE( "Import module: " + module + ".\n Location: " + os.path.abspath(m) )
-         mod=__import__(module)
-         modules[module]=mod.__dict__.copy()
-      # Don't keep r directory in the path to not pollute it
-      del sys.path[0]
+    # Import all *_shared_modules in rep
+    for f in glob.glob(os.path.join(rep,"lib","python"+sys.version[:3],"site-packages","salome","shared_modules","*_shared_modules.py")):
+        try:
+           m=__import__(os.path.splitext(os.path.basename(f))[0])
+           list_modules.append(m)
+        except:
+           pass
 
-   # Don't keep rep directory in the path to not pollute it
-   del sys.path[0]
-
-# End of CORBA modules import
-
-def import_shared_modules(sysmodules):
-   """
-      This function "imports" shared modules contained in modules dictionnary
-      in sysmodules.
-      All these modules are only copied and not completely imported (not executed)
-   """
-   # EDF-CCAR: 
-   # Problem with omniORB : omniORB creates a C Python module named  _omnipy
-   # this module has sub-modules : omni_func, ...
-   # _omnipy is quite a package but import with Python sub-interpreters does not seem to work 
-   # To make it work we need to add those sub-modules in sysmodules
-   import _omnipy
-   sysmodules["_omnipy.omni_func"]=_omnipy.omni_func
-   sysmodules["_omnipy.poa_func"]=_omnipy.poa_func
-   sysmodules["_omnipy.poamanager_func"]=_omnipy.poa_func
-   sysmodules["_omnipy.orb_func"]=_omnipy.orb_func
-
-   import imp
-
-   # All modules in the modules dictionnary are only copied, not completely imported 
-   for nom_module,module_dict in modules.items():
-      if sysmodules.has_key(nom_module):continue
-      m=imp.new_module(nom_module)
-      m.__dict__.update(module_dict)
-      sysmodules[nom_module]=m
+# 
+# If shared modules have been imported before installing import mechanism
+# we add them to shared_imported
+#
+for name,module in sys.modules.items():
+    if import_hook.is_shared(name) and shared_imported.get(name) is None:
+       #print "Module shared added to shared_imported: ",name
+       shared_imported[name]=module