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