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