From: caremoli Date: Thu, 5 Jun 2003 17:54:21 +0000 (+0000) Subject: CCAR (EDF-RD): X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2FCCAR_br1;p=modules%2Fkernel.git CCAR (EDF-RD): - 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 _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 --- diff --git a/bin/runSalome.py b/bin/runSalome.py index 070be63dd..cc3a72b16 100755 --- a/bin/runSalome.py +++ b/bin/runSalome.py @@ -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() + diff --git a/salome_adm/unix/config_files/check_pyqt.m4 b/salome_adm/unix/config_files/check_pyqt.m4 index ec915a4ad..62b4668b6 100644 --- a/salome_adm/unix/config_files/check_pyqt.m4 +++ b/salome_adm/unix/config_files/check_pyqt.m4 @@ -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) diff --git a/salome_adm/unix/config_files/check_sip.m4 b/salome_adm/unix/config_files/check_sip.m4 index 7808c3e67..a6714b238 100644 --- a/salome_adm/unix/config_files/check_sip.m4 +++ b/salome_adm/unix/config_files/check_sip.m4 @@ -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) diff --git a/src/SALOMEGUI/PyInterp_base.cxx b/src/SALOMEGUI/PyInterp_base.cxx index 52aa2c19f..7356b8429 100644 --- a/src/SALOMEGUI/PyInterp_base.cxx +++ b/src/SALOMEGUI/PyInterp_base.cxx @@ -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; } diff --git a/src/SALOMEGUI/QAD_PyInterp.cxx b/src/SALOMEGUI/QAD_PyInterp.cxx index f4c0da963..e3996723b 100644 --- a/src/SALOMEGUI/QAD_PyInterp.cxx +++ b/src/SALOMEGUI/QAD_PyInterp.cxx @@ -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 + } diff --git a/src/SALOME_SWIG/Makefile.in b/src/SALOME_SWIG/Makefile.in index 3475d77dc..b24711574 100644 --- a/src/SALOME_SWIG/Makefile.in +++ b/src/SALOME_SWIG/Makefile.in @@ -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 diff --git a/src/SALOME_SWIG/salome_shared_modules.py b/src/SALOME_SWIG/salome_shared_modules.py index 4f6d14c66..de2b8742d 100644 --- a/src/SALOME_SWIG/salome_shared_modules.py +++ b/src/SALOME_SWIG/salome_shared_modules.py @@ -1,144 +1,64 @@ -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 : and __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