| The Gaudi Framework v32r1 (f65d50dc)

ConfigurableDb.py
Go to the documentation of this file.
1 # File: AthenaCommon/python/ConfigurableDb.py
2 # Author: Sebastien Binet (binet@cern.ch)
3 """A singleton holding informations on the whereabouts of all the automatically
4 generated Configurables.
5 This repository of (informations on) Configurables is used by the PropertyProxy
6 class to locate Configurables and feed the JobOptionsSvc. It could also be used
7 to feed the AthenaEmacs module..."""
8
9 __all__ = ['CfgDb', 'cfgDb', 'loadConfigurableDb', 'getConfigurable']
10
11 import string
12 try:
13 _transtable = str.maketrans('<>&*,: ().', '__rp__s___')
14 except AttributeError:
15 # Python 2 compatibility
16 _transtable = string.maketrans('<>&*,: ().', '__rp__s___')
17
18 import logging
19 log = logging.getLogger('ConfigurableDb')
20
21
22 class _CfgDb(dict):
23 """
24 A singleton class holding informations about automatically generated
25 Configurables.
26 --> package holding that Configurable
27 --> library holding the components related to that Configurable
28 --> python module holding the Configurable
29 --> a dictionary of duplicates
30 """
31
32 __slots__ = {
33 '_duplicates': {},
34 }
35
36 def __init__(self):
37 object.__init__(self)
38 self._duplicates = {}
39
40 def add(self, configurable, package, module, lib):
41 """Method to populate the Db.
42 It is called from the auto-generated Xyz_confDb.py files (genconf.cpp)
43 @param configurable: the name of the configurable being added
44 @param package: the name of the package which holds this Configurable
45 @param module: the name of the python module holding the Configurable
46 @param lib: the name of the library holding the component(s) (ie: the
47 C++ Gaudi component which is mapped by the Configurable)
48 """
49 cfg = {'package': package, 'module': module, 'lib': lib}
50 if self.has_key(configurable):
51 # check if it comes from the same library...
52 if cfg['lib'] != self[configurable]['lib']:
53 log.debug("dup!! [%s] p=%s m=%s lib=%s", configurable, package,
54 module, lib)
55 if self._duplicates.has_key(configurable):
56 self._duplicates[configurable] += [cfg]
57 else:
58 self._duplicates[configurable] = [cfg]
59 else:
60 log.debug("added [%s] p=%s m=%s lib=%s", configurable, package,
61 module, lib)
62 self[configurable] = cfg
63
64 def duplicates(self):
65 return self._duplicates
66
67 def _loadModule(self, fname):
68 f = open(fname)
69 for i, ll in enumerate(f):
70 l = ll.strip()
71 if l.startswith('#') or len(l) <= 0:
72 continue
73 try:
74 line = l.split()
75 cname = line[2]
76 pkg = line[0].split('.')[0]
77 module = line[0]
78 lib = line[1]
79 self.add(cname, pkg, module, lib)
80 except Exception:
81 f.close()
82 raise Exception(
83 "invalid line format: %s:%d: %r" % (fname, i + 1, ll))
84 f.close()
85
86
87 class _Singleton(object):
88
89 # the object this singleton is holding
90 # No other object will be created...
91 __obj = _CfgDb()
92
93 def __call__(self):
94 return self.__obj
95
96
97 CfgDb = _Singleton()
98
99 # clean-up
100 del _Singleton
101 del _CfgDb
102
103 # default name for CfgDb instance
104 cfgDb = CfgDb()
105
106 # Helper function to load all ConfigurableDb files holding informations
107
108
109 def loadConfigurableDb():
110 """Helper function to load all ConfigurableDb files (modules) holding
111 informations about Configurables
112 """
113 import os
114 import sys
115 from glob import glob
116 from os.path import join as path_join
117 log.debug("loading confDb files...")
118 nFiles = 0 # counter of imported files
119 if sys.platform == 'darwin':
120 pathlist = os.getenv("DYLD_LIBRARY_PATH", "").split(os.pathsep)
121 else:
122 pathlist = os.getenv("LD_LIBRARY_PATH", "").split(os.pathsep)
123 for path in pathlist:
124 if not os.path.isdir(path):
125 continue
126 log.debug("walking in [%s]...", path)
127 confDbFiles = [
128 f for f in [
129 path_join(path, f) for f in os.listdir(path)
130 if f.endswith('.confdb')
131 ] if os.path.isfile(f)
132 ]
133 # check if we use "*_merged.confdb"
134 mergedConfDbFiles = [
135 f for f in confDbFiles if f.endswith('_merged.confdb')
136 ]
137 if mergedConfDbFiles:
138 # use only the merged ones
139 confDbFiles = mergedConfDbFiles
140
141 for confDb in confDbFiles:
142 log.debug("\t-loading [%s]...", confDb)
143 try:
144 cfgDb._loadModule(confDb)
145 except Exception as err:
146 log.warning("Could not load file [%s] !", confDb)
147 log.warning("Reason: %s", err)
148 nFiles += 1
149 log.debug("loading confDb files... [DONE]")
150 nPkgs = len(set([k['package'] for k in cfgDb.values()]))
151 log.debug("loaded %i confDb packages", nPkgs)
152 return nFiles
153
154
155 def getConfigurable(className, requester='', assumeCxxClass=True):
156 confClass = className
157 if assumeCxxClass:
158 # assume className is C++: --> translate to python
159 try:
160 confClass = str.translate(confClass, _transtable)
161 except AttributeError:
162 # Python 2 compatibility
163 confClass = string.translate(confClass, _transtable)
164 # see if I have it in my dictionary
165 confClassInfo = cfgDb.get(confClass)
166 if not confClassInfo:
167 confClassInfo = cfgDb.get(confClass)
168 # get the python module
169 confMod = confClassInfo and confClassInfo.get('module')
170 if not confMod:
171 log.warning("%s: Class %s not in database", requester, className)
172 return None
173 # load the module
174 try:
175 mod = __import__(confMod, globals(), locals(), confClass)
176 except ImportError:
177 log.warning("%s: Module %s not found (needed for configurable %s)",
178 requester, confMod, className)
179 return None
180 # get the class
181 try:
182 confClass = getattr(mod, confClass)
183 except AttributeError:
184 log.warning("%s: Configurable %s not found in module %s", requester,
185 confClass, confMod)
186 return None
187 # Got it!
188 log.debug("%s: Found configurable %s in module %s", requester, confClass,
189 confMod)
190
191 return confClass
GaudiKernel.ConfigurableDb.loadConfigurableDb
def loadConfigurableDb()
Definition: ConfigurableDb.py:109
GaudiKernel.ConfigurableDb._CfgDb
Definition: ConfigurableDb.py:22
GaudiKernel.ConfigurableDb._CfgDb.duplicates
def duplicates(self)
Definition: ConfigurableDb.py:64
GaudiKernel.ConfigurableDb._Singleton.__call__
def __call__(self)
Definition: ConfigurableDb.py:93
GaudiKernel.ConfigurableDb._CfgDb._loadModule
def _loadModule(self, fname)
Definition: ConfigurableDb.py:67
GaudiKernel.ConfigurableDb.CfgDb
CfgDb
Definition: ConfigurableDb.py:97
GaudiKernel.ConfigurableDb._CfgDb.__init__
def __init__(self)
Definition: ConfigurableDb.py:36
GaudiKernel.ConfigurableDb._CfgDb.add
def add(self, configurable, package, module, lib)
Definition: ConfigurableDb.py:40
GaudiKernel.ConfigurableDb._Singleton.__obj
__obj
Definition: ConfigurableDb.py:91
GaudiKernel.ConfigurableDb._Singleton
Definition: ConfigurableDb.py:87
GaudiKernel.ConfigurableDb._CfgDb._duplicates
_duplicates
Definition: ConfigurableDb.py:38
GaudiKernel.ConfigurableDb.getConfigurable
def getConfigurable(className, requester='', assumeCxxClass=True)
Definition: ConfigurableDb.py:155