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