| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ConfigurableDb.py
Go to the documentation of this file.
1 # File: AthenaCommon/python/ConfigurableDb.py
2 # Author: Sebastien Binet (binet@cern.ch)
3
4 """A singleton holding informations on the whereabouts of all the automatically
5 generated Configurables.
6 This repository of (informations on) Configurables is used by the PropertyProxy
7 class to locate Configurables and feed the JobOptionsSvc. It could also be used
8 to feed the AthenaEmacs module..."""
9
10 __all__ = [ 'CfgDb', 'cfgDb', 'loadConfigurableDb', 'getConfigurable' ]
11
12 import string
13 _transtable = string.maketrans('<>&*,: ().', '__rp__s___')
14
15 import logging
16 log = logging.getLogger( 'ConfigurableDb' )
17
18 class _CfgDb( dict ):
19 """
20 A singleton class holding informations about automatically generated
21 Configurables.
22 --> package holding that Configurable
23 --> library holding the components related to that Configurable
24 --> python module holding the Configurable
25 --> a dictionary of duplicates
26 """
27
28 __slots__ = {
29 '_duplicates' : { },
30 }
31
32 def __init__(self):
33 object.__init__(self)
34 self._duplicates = {}
35 return
36
37 def add( self, configurable, package, module, lib ):
38 """Method to populate the Db.
39 It is called from the auto-generated Xyz_confDb.py files (genconf.cpp)
40 @param configurable: the name of the configurable being added
41 @param package: the name of the package which holds this Configurable
42 @param module: the name of the python module holding the Configurable
43 @param lib: the name of the library holding the component(s) (ie: the
44 C++ Gaudi component which is mapped by the Configurable)
45 """
46 cfg = { 'package' : package,
47 'module' : module,
48 'lib' : lib }
49 if self.has_key( configurable ):
50 ## check if it comes from the same library...
51 if cfg['lib'] != self[configurable]['lib']:
52 log.debug( "dup!! [%s] p=%s m=%s lib=%s",
53 configurable, package, module, lib )
54 if self._duplicates.has_key(configurable):
55 self._duplicates[configurable] += [ cfg ]
56 else:
57 self._duplicates[configurable] = [ cfg ]
58 pass
59 else:
60 log.debug( "added [%s] p=%s m=%s lib=%s",
61 configurable, package, module, lib )
62 self[configurable] = cfg
63 pass
64 return
65
66 def duplicates(self):
67 return self._duplicates
68
69 pass # class _CfgDb
70
71 class _Singleton( object ):
72
73 ## the object this singleton is holding
74 ## No other object will be created...
75 __obj = _CfgDb()
76
77 def __call__( self ):
78 return self.__obj
79
80 pass # class _Singleton
81
82 CfgDb = _Singleton()
83
84 # clean-up
85 del _Singleton
86 del _CfgDb
87
88 ## default name for CfgDb instance
89 cfgDb = CfgDb()
90
91 ## Helper function to load all ConfigurableDb files holding informations
92 def loadConfigurableDb():
93 """Helper function to load all ConfigurableDb files (modules) holding
94 informations about Configurables
95 """
96 import os
97 import sys
98 from zipfile import is_zipfile, ZipFile
99 from glob import glob
100 from os.path import join as path_join
101 log.debug( "importing confDb packages..." )
102 nFiles = 0 # counter of imported files
103 for path in sys.path:
104 log.debug( "walking in [%s]..." % path )
105 if not os.path.exists(path):
106 continue
107 if is_zipfile(path):
108 # turn filename syntax into module syntax: remove path+extension and replace / with . (dot)
109 confDbModules = [ os.path.splitext(f)[0].replace('/','.')
110 for f in ZipFile(path).namelist()
111 if f.endswith("_merged_confDb.py") or f.endswith("_merged_confDb.pyc") ]
112 else:
113 # turn filename syntax into module syntax: remove path+extension and replace / with . (dot)
114 confDbModules = [ os.path.splitext( f[len(path)+1:] )[0].replace(os.sep,'.')
115 for f in glob(path_join(path, "*_merged_confDb.py"))
116 if os.path.isfile(f) ]
117 for confDbModule in confDbModules:
118 nFiles += 1
119 log.debug( "\t-importing [%s]..." % confDbModule )
120 try:
121 mod = __import__( confDbModule )
122 except ImportError, err:
123 log.warning( "Could not import module [%s] !", confDbModule )
124 log.warning( "Reason: %s", err )
125 pass
126 else:
127 # don't need to keep the module
128 del mod
129 pass
130 pass # loop over sys.path
131 log.debug( "importing confDb packages... [DONE]" )
132 nPkgs = len( set([k['package'] for k in cfgDb.values()]) )
133 log.debug( "imported %i confDb packages" % nPkgs )
134 return nFiles
135
136
137 def getConfigurable( className, requester='', assumeCxxClass=True ):
138 confClass=className
139 if assumeCxxClass:
140 # assume className is C++: --> translate to python
141 confClass = string.translate( confClass, _transtable )
142 # see if I have it in my dictionary
143 confClassInfo = cfgDb.get(confClass)
144 if not confClassInfo:
145 confClassInfo = cfgDb.get(confClass)
146 # get the python module
147 confMod = confClassInfo and confClassInfo.get('module')
148 if not confMod:
149 log.warning( "%s: Class %s not in database", requester, className )
150 return None
151 # load the module
152 try:
153 mod = __import__(confMod,globals(),locals(),confClass)
154 except ImportError:
155 log.warning( "%s: Module %s not found (needed for configurable %s)",
156 requester, confMod, className )
157 return None
158 # get the class
159 try:
160 confClass = getattr(mod,confClass)
161 except AttributeError:
162 log.warning( "%s: Configurable %s not found in module %s",
163 requester, confClass, confMod )
164 return None
165 # Got it!
166 log.debug( "%s: Found configurable %s in module %s",
167 requester, confClass, confMod )
168
169 return confClass