Salome HOME
Porting to Mandrake 10.1 and new products:
[modules/kernel.git] / src / SALOME_SWIG_WITHOUTIHM / import_hook.py
1 """
2 This module replaces the standard import mechanism with one
3 that filters some imports that can't be done more than once.
4
5 This is related to the multi study feature that is implemented
6 by using the Python multi interpreter feature.
7 Some modules register objects or classes by calling modules
8 implemented in C. These operations can't be done multiple times.
9 So it's very important to control these imports.
10
11 Examples:
12   - PyQt : import qt calls a C module to register classes
13   - OmniORB : import *_idl calls a C module to register CORBA interfaces
14
15 Usage:
16   - First import the module : import import_hook. This module will
17     replace the original importer mechanism
18
19   - Next register the module names or pattern names to filter out::
20      import_hook.register_name("a")
21      import_hook.register_pattern(pattern)
22
23     where pattern is a function with one parameter, the module name
24     to be imported, that returns true or false depending if this module is
25     to be filtered or not.
26
27   - Then it's done
28
29 IMPORTANT : Every subinterpretor has its own import_hook module. import_hook is not shared among subinterpretors.
30 The mechanism only works if shared_imported and pattern are shared between all subinterpretors.
31 This is done by calling init_shared_modules().
32   
33 """
34 import sys, imp, __builtin__
35
36 # Keep in shared_imported a copy of dictionnary modules
37 # that need to be imported only once in multi-study context
38 shared_imported={}
39
40 # patterns contains functions that returns 1 or 0 depending if 
41 # the module name (argument) must be filtered out or not
42 # These functions are added by calling register_pattern
43 patterns=[]
44
45 original_import=__builtin__.__import__
46
47 def register_name(name):
48     if shared_imported.has_key(name):return
49     shared_imported[name]=None
50
51 def register_pattern(pattern):
52     patterns.append(pattern)
53
54 def is_shared(name):
55     if shared_imported.has_key(name):return 1
56     for pattern in patterns:
57         if pattern(name) : return 1
58     return 0
59
60 def get_shared_imported(name):
61     return shared_imported.get(name)
62
63 def set_shared_imported(name,module):
64     shared_imported[name]=module
65     #print "Module %s shared registered" % name,module
66
67 def get_shared_imported_with_copy(name):
68     module_dict= shared_imported.get(name)
69     m=imp.new_module(name)
70     m.__dict__.update(module_dict)
71     return m
72 def set_shared_imported_with_copy(name,module):
73     shared_imported[name]=module.__dict__.copy()
74     #print "Module %s shared registered" % name
75
76 def import_hook(name, globals=None, locals=None, fromlist=None):
77     #print "import_hook",name,fromlist
78     module=get_shared_imported(name)
79     if module:
80        sys.modules[name]=module
81        return module
82
83     module= original_import(name, globals, locals, fromlist)
84
85     if is_shared(name):
86        set_shared_imported(name,module)
87     return module
88
89 original_reload=__builtin__.reload
90
91 def reload_hook(module):
92     if is_shared(module.__name__):
93        return module
94     return original_reload(module)
95
96 __builtin__.__import__=import_hook
97 # Reload is not replaced 
98 #__builtin__.reload=reload_hook
99
100 def init_shared_modules(shared_module):
101     global shared_imported, patterns
102     shared_imported=shared_module.shared_imported
103     patterns=       shared_module.patterns
104     for k,v in shared_imported.items():
105        if v is not None:sys.modules[k]=v
106     shared_imported["salome_shared_modules"]=shared_module
107     import salome_shared_modules
108     for m in salome_shared_modules.list_modules:
109         m.init_shared_modules()