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