From: caremoli Date: Thu, 5 Jun 2003 17:54:20 +0000 (+0000) Subject: CCAR (EDF-RD): X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=6feaf2404b22b972b638fbe1b8319adbd9b0a249;p=modules%2Fyacs.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/src/SALOME_SWIG/import_hook.py b/src/SALOME_SWIG/import_hook.py new file mode 100644 index 000000000..b67812fda --- /dev/null +++ b/src/SALOME_SWIG/import_hook.py @@ -0,0 +1,106 @@ +""" +This module replaces the standard import mechanism with one +that filters some imports that 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 import the module : import import_hook. This module will + replace the original importer mechanism + + - Next register the module names or pattern names to filter out:: + import_hook.register_name("a") + import_hook.register_pattern(pattern) + + where pattern is a function with one parameter, the module name + to be imported, that returns true or false depending if this module is + to be filtered or not. + + - Then it's done + +IMPORTANT : Every subinterpretor has its own import_hook module. import_hook is not shared among subinterpretors. +The mechanism only works if shared_imported and pattern are shared between all subinterpretors. +This is done by calling init_shared_modules(). + +""" +import sys, imp, __builtin__ + +# Keep in shared_imported a copy of dictionnary modules +# that need to be imported only once in multi-study context +shared_imported={} + +# patterns contains functions that returns 1 or 0 depending if +# the module name (argument) must be filtered out or not +# These functions are added by calling register_pattern +patterns=[] + +original_import=__builtin__.__import__ + +def register_name(name): + if shared_imported.has_key(name):return + shared_imported[name]=None + +def register_pattern(pattern): + patterns.append(pattern) + +def is_shared(name): + if shared_imported.has_key(name):return 1 + for pattern in patterns: + if pattern(name) : return 1 + return 0 + +def get_shared_imported(name): + return shared_imported.get(name) +def set_shared_imported(name,module): + shared_imported[name]=module + #print "Module %s shared registered" % name + +def get_shared_imported_with_copy(name): + module_dict= shared_imported.get(name) + m=imp.new_module(name) + m.__dict__.update(module_dict) + return m +def set_shared_imported_with_copy(name,module): + shared_imported[name]=module.__dict__.copy() + #print "Module %s shared registered" % name + +def import_hook(name, globals=None, locals=None, fromlist=None): + module=get_shared_imported(name) + if module: + sys.modules[name]=module + return module + + module= original_import(name, globals, locals, fromlist) + + if is_shared(name): + set_shared_imported(name,module) + return module + +original_reload=__builtin__.reload + +def reload_hook(module): + if is_shared(module.__name__): + return module + return original_reload(module) + +__builtin__.__import__=import_hook +# Reload is not replaced +#__builtin__.reload=reload_hook + +def init_shared_modules(shared_module): + global shared_imported, patterns + shared_imported=shared_module.shared_imported + patterns= shared_module.patterns + shared_imported["salome_shared_modules"]=shared_module + import salome_shared_modules + for m in salome_shared_modules.list_modules: + m.init_shared_modules() + diff --git a/src/SALOME_SWIG/kernel_shared_modules.py b/src/SALOME_SWIG/kernel_shared_modules.py new file mode 100644 index 000000000..dc4811aa3 --- /dev/null +++ b/src/SALOME_SWIG/kernel_shared_modules.py @@ -0,0 +1,80 @@ +""" + +""" +import glob,os,sys + +import import_hook +from import_hook import register_name +from import_hook import register_pattern + +register_name("qt") +register_pattern(lambda(x):x.endswith("_idl")) + +register_name("omniORB") +register_name("CosNaming") + +register_name("Engines") +register_name("SALOME") +register_name("SALOMEDS") +register_name("SALOME_ModuleCatalog") + +# BE CAREFUL +# Engines, SALOME, SALOMEDS must be imported in that order because : +# Engines imports SALOME_Component_idl +# SALOME imports SALOME_Session_idl and SALOME_Exception_idl which imports SALOME_Component_idl +# and SALOMEDS imports SALOMEDS_idl and SALOMEDS_Attributes_idl which imports SALOME_Exception_idl +# If SALOME is imported before Engines, that module would not be completely imported +import Engines +import SALOME +import SALOMEDS + +import SALOME_ModuleCatalog +from SALOME_utilities import MESSAGE +# +# We search all Python CORBA (omniorb) modules. +# A Python CORBA module has 2 associated Python packages +# These packages are named : and __POA +# +# That module is normally installed in shared_modules +# So we should find CORBA shared modules in .. +repertoire=os.path.join(os.path.dirname(__file__),'..') +path=[repertoire,] +# +for rep in path: + # Add rep directory in the Python path to be able to import modules + 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] ) + register_name(module) + + # Now we import modules found in shared_modules directory + r=os.path.join(rep,"shared_modules") + if os.path.isdir(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) ) + register_name(module) + + +def init_shared_modules(): + """ + This function initializes shared modules that need to be + """ + # 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 sys.modules + import sys + import _omnipy + sys.modules["_omnipy.omni_func"]=_omnipy.omni_func + sys.modules["_omnipy.poa_func"]=_omnipy.poa_func + sys.modules["_omnipy.poamanager_func"]=_omnipy.poamanager_func + sys.modules["_omnipy.orb_func"]=_omnipy.orb_func +