Salome HOME
CCAR (EDF-RD):
[modules/kernel.git] / src / SALOME_SWIG / 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 def set_shared_imported(name,module):
63     shared_imported[name]=module
64     #print "Module %s shared registered" % name
65
66 def get_shared_imported_with_copy(name):
67     module_dict= shared_imported.get(name)
68     m=imp.new_module(name)
69     m.__dict__.update(module_dict)
70     return m
71 def set_shared_imported_with_copy(name,module):
72     shared_imported[name]=module.__dict__.copy()
73     #print "Module %s shared registered" % name
74
75 def import_hook(name, globals=None, locals=None, fromlist=None):
76     module=get_shared_imported(name)
77     if module:
78        sys.modules[name]=module
79        return module
80
81     module= original_import(name, globals, locals, fromlist)
82
83     if is_shared(name):
84        set_shared_imported(name,module)
85     return module
86
87 original_reload=__builtin__.reload
88
89 def reload_hook(module):
90     if is_shared(module.__name__):
91        return module
92     return original_reload(module)
93
94 __builtin__.__import__=import_hook
95 # Reload is not replaced 
96 #__builtin__.reload=reload_hook
97
98 def init_shared_modules(shared_module):
99     global shared_imported, patterns
100     shared_imported=shared_module.shared_imported
101     patterns=       shared_module.patterns
102     shared_imported["salome_shared_modules"]=shared_module
103     import salome_shared_modules
104     for m in salome_shared_modules.list_modules:
105         m.init_shared_modules()
106