Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v36r16 (ea80daf8)
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 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  from os.path import join as path_join
126 
127  log.debug("loading confDb files...")
128  nFiles = 0 # counter of imported files
129  pathlist = os.getenv("LD_LIBRARY_PATH", "").split(os.pathsep)
130  ignored_files = set(os.environ.get("CONFIGURABLE_DB_IGNORE", "").split(","))
131  for path in pathlist:
132  if not os.path.isdir(path):
133  continue
134  log.debug("walking in [%s]...", path)
135  confDbFiles = [
136  f
137  for f in [
138  path_join(path, f) for f in os.listdir(path) if f.endswith(".confdb")
139  ]
140  if os.path.isfile(f) and f not in ignored_files
141  ]
142  # check if we use "*_merged.confdb"
143  mergedConfDbFiles = [f for f in confDbFiles if f.endswith("_merged.confdb")]
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(
185  "%s: Module %s not found (needed for configurable %s)",
186  requester,
187  confMod,
188  className,
189  )
190  return None
191  # get the class
192  try:
193  confClass = getattr(mod, confClass)
194  except AttributeError:
195  log.warning(
196  "%s: Configurable %s not found in module %s", requester, confClass, confMod
197  )
198  return None
199  # Got it!
200  log.debug("%s: Found configurable %s in module %s", requester, confClass, confMod)
201 
202  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:162
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