The Gaudi Framework  v37r1 (a7f61348)
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  # 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  from os.path import join as path_join
125 
126  log.debug("loading confDb files...")
127  nFiles = 0 # counter of imported files
128  pathlist = os.getenv("LD_LIBRARY_PATH", "").split(os.pathsep)
129  ignored_files = set(os.environ.get("CONFIGURABLE_DB_IGNORE", "").split(","))
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
136  for f in [
137  path_join(path, f) for f in os.listdir(path) if f.endswith(".confdb")
138  ]
139  if os.path.isfile(f) and f not in ignored_files
140  ]
141  # check if we use "*_merged.confdb"
142  mergedConfDbFiles = [f for f in confDbFiles if f.endswith("_merged.confdb")]
143  if mergedConfDbFiles:
144  # use only the merged ones
145  confDbFiles = mergedConfDbFiles
146 
147  for confDb in confDbFiles:
148  log.debug("\t-loading [%s]...", confDb)
149  try:
150  cfgDb._loadModule(confDb)
151  except Exception as err:
152  log.warning("Could not load file [%s] !", confDb)
153  log.warning("Reason: %s", err)
154  nFiles += 1
155  log.debug("loading confDb files... [DONE]")
156  nPkgs = len(set([k["package"] for k in cfgDb.values()]))
157  log.debug("loaded %i confDb packages", nPkgs)
158  return nFiles
159 
160 
161 def getConfigurable(className, requester="", assumeCxxClass=True):
162  confClass = className
163  if assumeCxxClass:
164  # assume className is C++: --> translate to python
165  try:
166  confClass = str.translate(confClass, _transtable)
167  except AttributeError:
168  # Python 2 compatibility
169  confClass = string.translate(confClass, _transtable)
170  # see if I have it in my dictionary
171  confClassInfo = cfgDb.get(confClass)
172  if not confClassInfo:
173  confClassInfo = cfgDb.get(confClass)
174  # get the python module
175  confMod = confClassInfo and confClassInfo.get("module")
176  if not confMod:
177  log.warning("%s: Class %s not in database", requester, className)
178  return None
179  # load the module
180  try:
181  mod = __import__(confMod, globals(), locals(), confClass)
182  except ImportError:
183  log.warning(
184  "%s: Module %s not found (needed for configurable %s)",
185  requester,
186  confMod,
187  className,
188  )
189  return None
190  # get the class
191  try:
192  confClass = getattr(mod, confClass)
193  except AttributeError:
194  log.warning(
195  "%s: Configurable %s not found in module %s", requester, confClass, confMod
196  )
197  return None
198  # Got it!
199  log.debug("%s: Found configurable %s in module %s", requester, confClass, confMod)
200 
201  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:161
GaudiKernel.ConfigurableDb._Singleton.__obj
__obj
Definition: ConfigurableDb.py:101
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:107
GaudiKernel.ConfigurableDb._Singleton
Definition: ConfigurableDb.py:98
GaudiKernel.ConfigurableDb.loadConfigurableDb
def loadConfigurableDb()
Definition: ConfigurableDb.py:119
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:103