The Gaudi Framework  master (37c0b60a)
GaudiKernel.Configurable.Configurable Class Reference
Inheritance diagram for GaudiKernel.Configurable.Configurable:
Collaboration diagram for GaudiKernel.Configurable.Configurable:

Classes

class  DefaultName
 

Public Member Functions

def __new__ (cls, *args, **kwargs)
 
def __init__ (self, name=DefaultName)
 
def __getstate__ (self)
 
def __getnewargs__ (self)
 
def __setstate__ (self, dict)
 
def __len__ (self)
 
def __iter__ (self)
 
def __deepcopy__ (self, memo)
 
def __iadd__ (self, configs, descr=None)
 
def __getattr__ (self, attr)
 
def __setattr__ (self, name, value)
 
def __delattr__ (self, attr)
 
def __bool__ (self)
 
def remove (self, items)
 
def removeAll (self)
 
def copyChild (self, child)
 
def setParent (self, parentName)
 
def getParent (self)
 
def hasParent (self, parent)
 
def copyChildAndSetParent (self, cfg, parent)
 
def getChildren (self)
 
def getTools (self)
 
def children (self)
 
def getAllChildren (self)
 
def getSequence (self)
 
def setup (self)
 
def getProperties (self)
 
def getPropertiesWithDescription (self)
 
def getValuedProperties (self)
 
def properties (self)
 
def getDefaultProperties (cls)
 
def getDefaultProperty (cls, name)
 
def getProp (self, name)
 
def setProp (self, name, value)
 
def isPropertySet (self, name)
 
def getType (cls)
 
def getName (self)
 
def name (self)
 
def getJobOptName (self)
 
def isPublic (self)
 
def jobOptName (self)
 
def getFullName (self)
 
def getFullJobOptName (self)
 
def getPrintTitle (self)
 
def getTitleName (self)
 
def setDefaults (cls, handle)
 
def clone (self, name=None, **kwargs)
 
def splitName (self)
 
def addTool (self, tool, name=None)
 
def __repr__ (self)
 
def __str__ (self, indent=0, headerLastIndentUnit=indentUnit)
 
def isApplicable (self)
 
- Public Member Functions inherited from GaudiKernel.ConfigurableMeta.ConfigurableMeta
def __new__ (self, name, bases, dct)
 
def __call__ (cls, *args, **kwargs)
 

Static Public Attributes

 propertyNoValue
 
 indentUnit
 
 printHeaderWidth
 
 printHeaderPre
 
 allConfigurables
 
 configurableServices
 

Private Member Functions

def _isInSetDefaults (self)
 
def __setupServices (self)
 
def __setupDlls (self)
 
def __setupDefaults (self)
 

Static Private Member Functions

def _printHeader (indentStr, title)
 
def _printFooter (indentStr, title)
 

Private Attributes

 __children
 
 __tools
 
 _name
 
 _inSetDefaults
 
 _initok
 
 _setupok
 
 _unpickling
 

Static Private Attributes

 __slots__
 
 _configurationLocked
 

Detailed Description

Base class for Gaudi components that implement the IProperty interface.
Provides most of the boilerplate code, but the actual useful classes
are its derived ConfigurableAlgorithm, ConfigurableService, and
ConfigurableAlgTool.

Definition at line 149 of file Configurable.py.

Constructor & Destructor Documentation

◆ __init__()

def GaudiKernel.Configurable.Configurable.__init__ (   self,
  name = DefaultName 
)

Reimplemented in GaudiKernel.Configurable.ConfigurableAuditor, GaudiKernel.Configurable.ConfigurableAlgTool, GaudiKernel.Configurable.ConfigurableAlgorithm, and GaudiKernel.Configurable.ConfigurableGeneric.

Definition at line 339 of file Configurable.py.

339  def __init__(self, name=DefaultName):
340  # check class readiness, all required overloads should be there now
341  klass = self.__class__
342 
343  # this is an abstract class
344  if klass == Configurable:
345  raise TypeError(
346  "%s is an ABC and can not be instantiated" % str(Configurable)
347  )
348 
349  # the following methods require overloading
350  # NOT YET meths = { 'getServices' : 1, # retrieve list of services to configure
351  meths = {
352  "getDlls": 1, # provide list of Dlls to load
353  "getGaudiType": 1, # return string describing component class
354  "getHandle": 1,
355  } # provide access to C++ side component instance
356  # 'getType' : 1 } # return the type of the actual C++ component
357 
358  for meth, nArgs in meths.items():
359  try:
360  f = getattr(klass, meth)
361  except AttributeError:
362  raise NotImplementedError(
363  "%s is missing in class %s" % (meth, str(klass))
364  )
365 
366  # in addition, verify the number of arguments w/o defaults
367  nargcount = f.__code__.co_argcount
368  fdefaults = f.__defaults__
369  ndefaults = fdefaults and len(fdefaults) or 0
370  if not nargcount - ndefaults <= nArgs <= nargcount:
371  raise TypeError(
372  "%s.%s requires exactly %d arguments" % (klass, meth, nArgs)
373  )
374 
375  # for using this Configurable as a (Gaudi) sequence
376  self.__children = []
377  self.__tools = {}
378 
379  # know who we are
380  if name == Configurable.DefaultName:
381  if hasattr(self.__class__, "DefaultedName"):
382  self._name = self.__class__.DefaultedName
383  else:
384  self._name = self.getType()
385  else:
386  self._name = name
387 
388  # set to True when collecting defaults, False otherwise
389  self._inSetDefaults = False
390 
391  # for later, in case __init__ itself is overridden
392  self._initok = True
393 
394  # for debugging purposes (temporary)
395  self._setupok = False
396 
397  # used to prevent spurious deprecation warnings when unpickling
398  self._unpickling = False
399 

Member Function Documentation

◆ __bool__()

def GaudiKernel.Configurable.Configurable.__bool__ (   self)

Definition at line 547 of file Configurable.py.

547  def __bool__(self):
548  return True
549 

◆ __deepcopy__()

def GaudiKernel.Configurable.Configurable.__deepcopy__ (   self,
  memo 
)

Reimplemented in GaudiKernel.Configurable.ConfigurableService, GaudiKernel.Configurable.ConfigurableAlgorithm, and GaudiKernel.Configurable.ConfigurableGeneric.

Definition at line 441 of file Configurable.py.

441  def __deepcopy__(self, memo):
442  newconf = object.__new__(self.__class__)
443  self.__class__.__init__(newconf, self.getName())
444 
445  for proxy in self._properties.values():
446  try:
447  proxy.__set__(newconf, proxy.__get__(self))
448  except AttributeError:
449  pass # means property was not set for self
450 
451  for c in self.__children:
452  newconf += c # processes proper copy semantics
453 
454  return newconf
455 

◆ __delattr__()

def GaudiKernel.Configurable.Configurable.__delattr__ (   self,
  attr 
)

Definition at line 522 of file Configurable.py.

522  def __delattr__(self, attr):
523  # remove as property, otherwise try as child
524  try:
525  # remove history etc., then reset to default (in case set before)
526  prop = self._properties[attr]
527  prop.__delete__(self)
528  prop.__set__(self, prop.default)
529  return # reaches here? was property: done now
530  except KeyError:
531  pass
532  # otherwise, remove the private tool
533  if attr in self.__tools:
534  del self.__tools[attr]
535 
536  # otherwise, remove child, if one is so named
537  for c in self.__children:
538  if c.getName() == attr:
539  self.__children.remove(c)
540 
541  # potentially, there are left over caches (certain user derived classes)
542  try:
543  del self.__dict__[attr]
544  except (AttributeError, KeyError):
545  pass
546 

◆ __getattr__()

def GaudiKernel.Configurable.Configurable.__getattr__ (   self,
  attr 
)

Definition at line 492 of file Configurable.py.

492  def __getattr__(self, attr): # until ToolProperties exist ...
493  if attr in self.__tools:
494  return self.__tools[attr]
495 
496  if attr in self._properties:
497  if isinstance(self._properties[attr].__get__(self), DataHandle):
498  return self._properties[attr].__get__(self)
499 
500  for c in self.__children:
501  if c.getName() == attr:
502  return c
503 
504  raise AttributeError(
505  "'%s' object has no attribute '%s'" % (self.__class__, attr)
506  )
507 

◆ __getnewargs__()

def GaudiKernel.Configurable.Configurable.__getnewargs__ (   self)

Definition at line 414 of file Configurable.py.

414  def __getnewargs__(self):
415  return (self._name,)
416 

◆ __getstate__()

def GaudiKernel.Configurable.Configurable.__getstate__ (   self)

Definition at line 401 of file Configurable.py.

401  def __getstate__(self):
402  dict = {}
403  for name, proxy in self._properties.items():
404  try:
405  dict[name] = proxy.__get__(self)
406  except AttributeError:
407  pass
408 
409  dict["_Configurable__children"] = self.__children
410  dict["_Configurable__tools"] = self.__tools
411  dict["_name"] = self._name
412  return dict
413 

◆ __iadd__()

def GaudiKernel.Configurable.Configurable.__iadd__ (   self,
  configs,
  descr = None 
)

Definition at line 457 of file Configurable.py.

457  def __iadd__(self, configs, descr=None):
458  if not isinstance(configs, (list, tuple)):
459  configs = (configs,)
460 
461  joname = self.getJobOptName()
462 
463  for cfg in configs:
464  # prevent type mismatches
465  if not isinstance(cfg, Configurable):
466  raise TypeError("'%s' is not a Configurable" % str(cfg))
467 
468  cc = self.copyChildAndSetParent(cfg, joname)
469 
470  # filters dupes; usually "ok" (backdoor should catch them)
471  ccjo = cc.getJobOptName()
472  for c in self.__children:
473  if c.getJobOptName() == ccjo:
474  log.error(
475  "attempt to add a duplicate ... dupe ignored%s",
476  error_explanation,
477  )
478  break
479  else:
480  self.__children.append(cc)
481 
482  try:
483  if descr: # support for tool properties
484  descr.__set__(self, cc)
485  else:
486  setattr(self, cc.getName(), cc)
487  except AttributeError:
488  pass # to allow free addition of tools/subalgorithms
489 
490  return self
491 

◆ __iter__()

def GaudiKernel.Configurable.Configurable.__iter__ (   self)

Definition at line 437 of file Configurable.py.

437  def __iter__(self):
438  return iter(self.__children)
439 

◆ __len__()

def GaudiKernel.Configurable.Configurable.__len__ (   self)

Definition at line 434 of file Configurable.py.

434  def __len__(self):
435  return len(self.__children)
436 

◆ __new__()

def GaudiKernel.Configurable.Configurable.__new__ (   cls,
args,
**  kwargs 
)
To Gaudi, any object with the same type/name is the same object. Hence,
this is mimicked in the configuration: instantiating a new Configurable
of a type with the same name will return the same instance.

Definition at line 180 of file Configurable.py.

180  def __new__(cls, *args, **kwargs):
181  """To Gaudi, any object with the same type/name is the same object. Hence,
182  this is mimicked in the configuration: instantiating a new Configurable
183  of a type with the same name will return the same instance."""
184 
185  global log
186  func_code = cls.__init__.__code__
187  func_defaults = cls.__init__.__defaults__
188  # try to get the name of the Configurable (having a name is compulsory)
189  if "name" in kwargs:
190  # simple keyword (by far the easiest)
191  name = kwargs["name"]
192  elif "name" in func_code.co_varnames:
193  # either positional in args, or default
194  index = list(func_code.co_varnames).index("name")
195  try:
196  # var names index is offset by one as __init__ is to be called with self
197  name = args[index - 1]
198  except IndexError:
199  # retrieve default value, then
200  name = func_defaults[index - (len(args) + 1)]
201  else:
202  # positional index is assumed (will work most of the time)
203  try:
204  name = args[1] # '0' is for self
205  except (IndexError, TypeError):
206  raise TypeError(
207  'no "name" argument while instantiating "%s"' % cls.__name__
208  )
209 
210  argname = name
211  if name == Configurable.DefaultName:
212  if hasattr(cls, "DefaultedName"):
213  name = cls.DefaultedName
214  else:
215  name = cls.getType()
216  elif not name or not isinstance(name, str):
217  # unnamed, highly specialized user code, etc. ... unacceptable
218  raise TypeError(
219  "could not retrieve name from %s.__init__ arguments" % cls.__name__
220  )
221 
222  # Handle the case of global tools to prepend ToolSvc in the name.
223  # This is needed for compatibility with old JobOptions files being read
224  if issubclass(cls, ConfigurableAlgTool) and "." not in name:
225  name = "ToolSvc." + name
226 
227  # close backdoor access to otherwise private subalgs/tools
228  # PM if 0 <= name.find( '.' ):
229  # PM # temp protection for old style types
230  # PM from OldStyleConfig import GenericConfigurable
231  # PM if not issubclass( cls, GenericConfigurable ): # except raised for new types only
232  # PM raise NameError( '"%s": backdoor access to private configurables not allowed' % name )
233 
234  # ordinary recycle case
235  if name in cls.configurables:
236  conf = cls.configurables[name]
237  if name != argname: # special case: user derived <-> real ... make same
238  cls.configurables[conf.getType()] = conf
239  # ---PM: Initialize additional properties
240  for n, v in kwargs.items():
241  if n != "name": # it should not be confused with a normal property
242  setattr(conf, n, v)
243  if (
244  not cls._configurationLocked
245  and "_enabled" not in kwargs
246  and isinstance(conf, ConfigurableUser)
247  ):
248  # Ensure that the ConfigurableUser gets enabled if nothing is
249  # specified in the constructor.
250  setattr(conf, "_enabled", True)
251  return conf
252 
253  # a couple of special cases (note that these cases don't mix)
254  spos = name.find("/")
255  ti_name = None
256  if spos < 0:
257  ti_name = "%s/%s" % (name, name)
258  if ti_name in cls.configurables:
259  # support for old-style name as type/name lookup where name==type
260  return cls.configurables[ti_name]
261 
262  i_name = None
263  if spos > 0:
264  i_name = name[:spos]
265  if i_name == name[spos + 1 :] and i_name in cls.configurables:
266  # this is the opposite of the above special case
267  return cls.configurables[i_name]
268 
269  # the following is purely for debugging support and should realistically bomb
270  conf = (
271  cls.allConfigurables.get(name, None)
272  or (spos < 0 and cls.allConfigurables.get(ti_name, None))
273  or (
274  spos > 0
275  and i_name == name[spos + 1 :]
276  and cls.allConfigurables.get(i_name, None)
277  )
278  )
279  if conf: # wrong type used?
280  if conf.__class__ is ConfigurableGeneric:
281  # If the instance found is ConfigurableGeneric then
282  # we create a new one with the proper type and fill with
283  # the contents of the generic one
284  newconf = object.__new__(cls)
285  cls.__init__(newconf, *args, **kwargs)
286  # initialize with the properties of generic configurable
287  # (we map the names of the properties to lowercase versions because
288  # old options are not case sensitive)
289  names = {}
290  for n in newconf.__slots__:
291  names[n.lower()] = n
292  for n in conf._properties:
293  if names[n.lower()] != n:
294  log.warning(
295  "Option '%s' was used for %s, but the correct spelling is '%s'"
296  % (n, name, names[n.lower()])
297  )
298  setattr(newconf, names[n.lower()], getattr(conf, n))
299  for n, v in kwargs.items():
300  setattr(newconf, n, v)
301  cls.configurables[name] = newconf
302  cls.allConfigurables[name] = newconf
303  return newconf
304  else:
305  # will be an actual error in the future (now only report as such)
306  log.error(
307  'attempt to redefine type of "%s" (was: %s, new: %s)%s',
308  name,
309  conf.__class__.__name__,
310  cls.__name__,
311  error_explanation,
312  )
313  # in the future:
314  # return None # will bomb on use (or go unharmed on non-use)
315  # for now, allow use through allConfigurables lookup
316  # ---PM: Initialize additional properties
317  for n, v in kwargs.items():
318  setattr(conf, n, v)
319  return conf
320 
321  # still here: create a new instance and initialize it
322  conf = object.__new__(cls)
323  cls.__init__(conf, *args, **kwargs)
324 
325  # update normal, per-class cache
326  cls.configurables[name] = conf
327 
328  for base in cls.__bases__:
329  if base.__name__ == "ConfigurableService":
330  cls.configurableServices[name] = conf
331 
332  # update generics super-cache, if needed
333  cls.allConfigurables[name] = conf
334  # -->PM#if hasattr( cls, 'getType' ) and name.find('/') < 0:
335  # -->PM# cls.allConfigurables[ cls.getType() + '/' + name ] = conf
336 
337  return conf
338 

◆ __repr__()

def GaudiKernel.Configurable.Configurable.__repr__ (   self)

Definition at line 969 of file Configurable.py.

969  def __repr__(self):
970  return "{0}({1!r})".format(self.__class__.__name__, self.name())
971 

◆ __setattr__()

def GaudiKernel.Configurable.Configurable.__setattr__ (   self,
  name,
  value 
)

Reimplemented in GaudiKernel.Configurable.ConfigurableGeneric.

Definition at line 508 of file Configurable.py.

508  def __setattr__(self, name, value):
509  if self._configurationLocked:
510  raise RuntimeError(
511  "%s: Configuration cannot be modified after the ApplicationMgr has been started."
512  % self.name()
513  )
514  try:
515  super(Configurable, self).__setattr__(name, value)
516  except AttributeError:
517  raise AttributeError(
518  "Configurable '%s' does not have property '%s'."
519  % (self.__class__.__name__, name)
520  )
521 

◆ __setstate__()

def GaudiKernel.Configurable.Configurable.__setstate__ (   self,
  dict 
)

Definition at line 417 of file Configurable.py.

417  def __setstate__(self, dict):
418  self._initok = True
419  from contextlib import contextmanager
420 
421  @contextmanager
422  def unpickling():
423  try:
424  self._unpickling = True
425  yield
426  finally:
427  self._unpickling = False
428 
429  with unpickling():
430  for n, v in dict.items():
431  setattr(self, n, v)
432 

◆ __setupDefaults()

def GaudiKernel.Configurable.Configurable.__setupDefaults (   self)
private

Definition at line 944 of file Configurable.py.

944  def __setupDefaults(self):
945  # set handle defaults flags to inform __setattr__ that it is being
946  # called during setDefaults of the concrete Configurable
947  self._inSetDefaults = True
948  self.setDefaults(self)
949  self._inSetDefaults = False
950 

◆ __setupDlls()

def GaudiKernel.Configurable.Configurable.__setupDlls (   self)
private

Definition at line 931 of file Configurable.py.

931  def __setupDlls(self):
932  dlls = self.getDlls()
933  if not dlls:
934  dlls = []
935  elif isinstance(dlls, types.StringType):
936  dlls = [dlls]
937 
938  from __main__ import theApp
939 
940  dlls = filter(lambda d: d not in theApp.Dlls, dlls)
941  if dlls:
942  theApp.Dlls += dlls
943 

◆ __setupServices()

def GaudiKernel.Configurable.Configurable.__setupServices (   self)
private

Definition at line 913 of file Configurable.py.

913  def __setupServices(self):
914  # svcs = self.getServices()
915  # if not svcs:
916  svcs = []
917  # elif type(svcs) == types.StringType:
918  # svcs = [ svcs ]
919 
920  import __main__
921 
922  for svc in svcs:
923  handle = __main__.Service(svc) # noqa: F841 (used in eval below)
924  # services should be configurables as well, but aren't for now
925  # handle.setup()
926 
927  # allow Configurable to make some changes
928  if hasattr(self, "configure" + svc):
929  eval("self.configure" + svc + "( handle )")
930 

◆ __str__()

def GaudiKernel.Configurable.Configurable.__str__ (   self,
  indent = 0,
  headerLastIndentUnit = indentUnit 
)

Definition at line 972 of file Configurable.py.

972  def __str__(self, indent=0, headerLastIndentUnit=indentUnit):
973  global log # to print some info depending on output level
974 
975  def _sorted_repr_set(value):
976  """Helper to print sorted set representation"""
977  return "{" + repr(sorted(value))[1:-1] + "}" if value else "set()"
978 
979  indentStr = indent * Configurable.indentUnit
980  # print header
981  title = self.getPrintTitle()
982  # print line to easily see start-of-configurable
983  if indent > 0:
984  headerIndent = (indent - 1) * Configurable.indentUnit + headerLastIndentUnit
985  else:
986  headerIndent = ""
987  rep = Configurable._printHeader(headerIndent, title)
988  rep += os.linesep
989  # print own properties
990  props = self.getProperties()
991  defs = self.getDefaultProperties()
992  if not props:
993  rep += indentStr + "|-<no properties>" + os.linesep
994  else:
995  # get property name with
996  nameWidth = 0
997  for p in props.keys():
998  nameWidth = max(nameWidth, len(p))
999  for p, v in props.items():
1000  # start with indent and property name
1001  prefix = indentStr + "|-%-*s" % (nameWidth, p)
1002  # add memory address for debugging (not for defaults)
1003  if log.isEnabledFor(logging.DEBUG):
1004  if v != Configurable.propertyNoValue:
1005  address = " @%11s" % hex(id(v))
1006  else:
1007  address = 13 * " "
1008  prefix += address
1009  # add value and default
1010  default = defs.get(p)
1011  if v == Configurable.propertyNoValue:
1012  # show default value as value, and no extra 'default'
1013  strVal = repr(default)
1014  strDef = None
1015  else:
1016  # convert configurable to handle
1017  if hasattr(v, "getGaudiHandle"):
1018  vv = v.getGaudiHandle()
1019  else:
1020  vv = v
1021  if isinstance(vv, (GaudiHandle, GaudiHandleArray, DataHandle)):
1022  strVal = repr(vv)
1023  # the default may not be a GaudiHandle (?)
1024  if hasattr(default, "toStringProperty"):
1025  strDef = repr(default.toStringProperty())
1026  else:
1027  strDef = repr(default)
1028  if strDef == repr(vv.toStringProperty()):
1029  strDef = None
1030  elif isinstance(vv, set):
1031  strVal = _sorted_repr_set(vv)
1032  strDef = _sorted_repr_set(default)
1033  else:
1034  strVal = repr(vv)
1035  strDef = repr(default)
1036  # add the value
1037  line = prefix + " = " + strVal
1038  # add default if present
1039  if strDef is not None:
1040  # put default on new line if too big
1041  if len(line) + len(strDef) > Configurable.printHeaderWidth:
1042  line += (
1043  os.linesep
1044  + indentStr
1045  + "| "
1046  + (len(prefix) - len(indentStr) - 3) * " "
1047  )
1048  line += " (default: %s)" % (strDef,)
1049  # add the line to the total string
1050  rep += line + os.linesep
1051  # print out full private configurables
1052  # if isinstance(v,Configurable) and not v.isPublic():
1053 
1058 
1059  # print configurables + their properties, or loop over sequence
1060  # for cfg in self.__children:
1061  for cfg in self.getAllChildren():
1062  rep += cfg.__str__(indent + 1, "|=") + os.linesep
1063 
1064  # print line to easily see end-of-configurable. Note: No linesep!
1065  rep += Configurable._printFooter(indentStr, title)
1066  return rep
1067 

◆ _isInSetDefaults()

def GaudiKernel.Configurable.Configurable._isInSetDefaults (   self)
private

Definition at line 910 of file Configurable.py.

910  def _isInSetDefaults(self):
911  return self._inSetDefaults
912 

◆ _printFooter()

def GaudiKernel.Configurable.Configurable._printFooter (   indentStr,
  title 
)
staticprivate

Definition at line 961 of file Configurable.py.

961  def _printFooter(indentStr, title):
962  preLen = Configurable.printHeaderPre
963  postLen = (
964  Configurable.printHeaderWidth - preLen - 12 - len(title)
965  ) # - len(indentStr)
966  postLen = max(preLen, postLen)
967  return indentStr + "\\%s (End of %s) %s" % (preLen * "-", title, postLen * "-")
968 

◆ _printHeader()

def GaudiKernel.Configurable.Configurable._printHeader (   indentStr,
  title 
)
staticprivate

Definition at line 952 of file Configurable.py.

952  def _printHeader(indentStr, title):
953  preLen = Configurable.printHeaderPre
954  postLen = (
955  Configurable.printHeaderWidth - preLen - 3 - len(title)
956  ) # - len(indentStr)
957  postLen = max(preLen, postLen)
958  return indentStr + "/%s %s %s" % (preLen * "*", title, postLen * "*")
959 

◆ addTool()

def GaudiKernel.Configurable.Configurable.addTool (   self,
  tool,
  name = None 
)

Definition at line 887 of file Configurable.py.

887  def addTool(self, tool, name=None):
888  if isclass(tool) and issubclass(tool, ConfigurableAlgTool):
889  if name is None:
890  name = tool.__name__
891  priv_tool = tool(self.getName() + "." + name)
892  elif isinstance(tool, ConfigurableAlgTool):
893  if name is None:
894  name = tool.splitName()[1]
895  priv_tool = tool.clone(self.getName() + "." + name)
896  else:
897  if isclass(tool):
898  classname = tool.__name__
899  else:
900  classname = type(tool).__name__
901  raise TypeError(
902  "addTool requires AlgTool configurable. Got %s type" % classname
903  )
904  self.__tools[name] = priv_tool
905  if name in self.__slots__:
906  # this is to avoid that the property hides the tool
907  setattr(self, name, self.__tools[name])
908  return self.__tools[name]
909 

◆ children()

def GaudiKernel.Configurable.Configurable.children (   self)

Definition at line 598 of file Configurable.py.

598  def children(self):
599  log.error("children() is deprecated, use getChildren() instead for consistency")
600  log.error(
601  "getChildren() returns a copy; to add a child, use 'parent += child'%s",
602  error_explanation,
603  )
604  return self.__children # by ref, for compatibility
605 

◆ clone()

def GaudiKernel.Configurable.Configurable.clone (   self,
  name = None,
**  kwargs 
)

Definition at line 840 of file Configurable.py.

840  def clone(self, name=None, **kwargs):
841  if not name:
842  if hasattr(self, "DefaultedName"):
843  name = self.DefaultedName
844  else:
845  name = self.getType()
846 
847  newconf = Configurable.__new__(self.__class__, name)
848  self.__class__.__init__(newconf, name)
849 
850  for proxy in self._properties.values():
851  try:
852  value = proxy.__get__(self)
853  if isinstance(value, (str, list, dict, tuple, set)):
854  # clone the values of the properties for basic types
855  value = type(value)(value)
856  proxy.__set__(newconf, value)
857  except AttributeError:
858  pass
859 
860  for c in self.__children:
861  newconf += c # processes proper copy semantics
862 
863  for n, t in self.__tools.items():
864  newconf.addTool(t, n)
865 
866  for name, value in kwargs.items():
867  setattr(newconf, name, value)
868 
869  return newconf
870 

◆ copyChild()

def GaudiKernel.Configurable.Configurable.copyChild (   self,
  child 
)

Reimplemented in GaudiKernel.Configurable.ConfigurableService.

Definition at line 560 of file Configurable.py.

560  def copyChild(self, child):
561  return copy.deepcopy(child)
562 

◆ copyChildAndSetParent()

def GaudiKernel.Configurable.Configurable.copyChildAndSetParent (   self,
  cfg,
  parent 
)

Definition at line 572 of file Configurable.py.

572  def copyChildAndSetParent(self, cfg, parent):
573  cc = self.copyChild(cfg)
574 
575  if hasattr(cc, "setParent") and parent:
576  try:
577  cc.setParent(parent)
578  except RuntimeError as e:
579  # temporary backdoor resolution for compatibility
580  log.error(str(e) + "%s", error_explanation)
581  ccbd = cc.configurables[cc.getJobOptName()]
582 
583  # merge properties, new over pre-existing
584  for proxy in self._properties.values():
585  if cc in proxy.history:
586  proxy.__set__(ccbd, proxy.__get__(cc))
587 
588  # consolidate
589  cc = ccbd
590  return cc
591 

◆ getAllChildren()

def GaudiKernel.Configurable.Configurable.getAllChildren (   self)
Get all (private) configurable children, both explicit ones (added with +=)
and the ones in the private GaudiHandle properties

Definition at line 606 of file Configurable.py.

606  def getAllChildren(self):
607  """Get all (private) configurable children, both explicit ones (added with +=)
608  and the ones in the private GaudiHandle properties"""
609  childs = []
610  # add private configurable properties (also inside handles)
611  for proxy in self._properties.values():
612  try:
613  c = proxy.__get__(self)
614  except AttributeError:
615  pass
616  else:
617  if isinstance(c, Configurable) and not c.isPublic():
618  childs.append(c)
619  elif isinstance(c, GaudiHandle):
620  try:
621  conf = c.configurable
622  except AttributeError:
623  pass
624  else:
625  if not conf.isPublic():
626  childs.append(conf)
627  elif isinstance(c, GaudiHandleArray):
628  # only setup private arrays
629  if not c.isPublic():
630  for ci in c:
631  if isinstance(ci, Configurable):
632  childs.append(ci)
633  else:
634  try:
635  conf = ci.configurable
636  except AttributeError:
637  pass
638  else:
639  childs.append(conf)
640 
641  # add explicit children
642  childs += self.__children
643  return childs
644 

◆ getChildren()

def GaudiKernel.Configurable.Configurable.getChildren (   self)

Definition at line 592 of file Configurable.py.

592  def getChildren(self):
593  return self.__children[:] # read only
594 

◆ getDefaultProperties()

def GaudiKernel.Configurable.Configurable.getDefaultProperties (   cls)

Definition at line 736 of file Configurable.py.

736  def getDefaultProperties(cls):
737  class collector:
738  pass
739 
740  # user provided defaults
741  c = collector()
742  cls.setDefaults(c)
743 
744  # defaults from C++
745  for k, v in cls._properties.items():
746  if k not in c.__dict__ and hasattr(v, "default"):
747  c.__dict__[k] = v.default
748 
749  return c.__dict__
750 

◆ getDefaultProperty()

def GaudiKernel.Configurable.Configurable.getDefaultProperty (   cls,
  name 
)

Definition at line 752 of file Configurable.py.

752  def getDefaultProperty(cls, name):
753  class collector:
754  pass
755 
756  # user provided defaults
757  c = collector()
758  cls.setDefaults(c)
759 
760  if name in c.__dict__:
761  return c.__dict__[name]
762 
763  # defaults from C++
764  try:
765  v = cls._properties[name]
766  if hasattr(v, "default"):
767  return v.default
768  except KeyError:
769  pass
770 
771  return None
772 

◆ getFullJobOptName()

def GaudiKernel.Configurable.Configurable.getFullJobOptName (   self)

Definition at line 825 of file Configurable.py.

825  def getFullJobOptName(self):
826  return "%s/%s" % (self.getType(), self.getJobOptName() or self.getName())
827 

◆ getFullName()

def GaudiKernel.Configurable.Configurable.getFullName (   self)

Reimplemented in GaudiKernel.Configurable.ConfigurableAlgTool.

Definition at line 822 of file Configurable.py.

822  def getFullName(self):
823  return str(self.getType() + "/" + self.getName())
824 

◆ getJobOptName()

def GaudiKernel.Configurable.Configurable.getJobOptName (   self)

Reimplemented in GaudiKernel.Configurable.ConfigurableAuditor, GaudiKernel.Configurable.ConfigurableAlgTool, GaudiKernel.Configurable.ConfigurableAlgorithm, and GaudiKernel.Configurable.ConfigurableGeneric.

Definition at line 808 of file Configurable.py.

808  def getJobOptName(self): # full hierachical name
809  return self.getName()
810 

◆ getName()

def GaudiKernel.Configurable.Configurable.getName (   self)

Definition at line 802 of file Configurable.py.

802  def getName(self):
803  return self._name
804 

◆ getParent()

def GaudiKernel.Configurable.Configurable.getParent (   self)

Reimplemented in GaudiKernel.Configurable.ConfigurableAlgTool.

Definition at line 566 of file Configurable.py.

566  def getParent(self):
567  return ""
568 

◆ getPrintTitle()

def GaudiKernel.Configurable.Configurable.getPrintTitle (   self)

Reimplemented in GaudiKernel.Configurable.ConfigurableAlgTool.

Definition at line 828 of file Configurable.py.

828  def getPrintTitle(self):
829  return self.getGaudiType() + " " + self.getTitleName()
830 

◆ getProp()

def GaudiKernel.Configurable.Configurable.getProp (   self,
  name 
)
Returns the value of the given property.

Definition at line 773 of file Configurable.py.

773  def getProp(self, name):
774  """Returns the value of the given property."""
775  if hasattr(self, name):
776  return getattr(self, name)
777  else:
778  return self.getDefaultProperties()[name]
779 

◆ getProperties()

def GaudiKernel.Configurable.Configurable.getProperties (   self)

Definition at line 685 of file Configurable.py.

685  def getProperties(self):
686  props = {}
687  for name, proxy in self._properties.items():
688  try:
689  props[name] = proxy.__get__(self)
690  except AttributeError:
691  props[name] = Configurable.propertyNoValue
692 
693  return props
694 

◆ getPropertiesWithDescription()

def GaudiKernel.Configurable.Configurable.getPropertiesWithDescription (   self)
Get all properties with their description string as { name : (value, desc) }.

Definition at line 695 of file Configurable.py.

695  def getPropertiesWithDescription(self):
696  """Get all properties with their description string as { name : (value, desc) }."""
697  props = {}
698  for name, proxy in self._properties.items():
699  try:
700  props[name] = (proxy.__get__(self), proxy.__doc__)
701  except AttributeError:
702  props[name] = (Configurable.propertyNoValue, proxy.__doc__)
703  return props
704 

◆ getSequence()

def GaudiKernel.Configurable.Configurable.getSequence (   self)

Definition at line 645 of file Configurable.py.

645  def getSequence(self):
646  elems = []
647  for c in self.__children:
648  elems.append(c.getFullName())
649  return elems
650 

◆ getTitleName()

def GaudiKernel.Configurable.Configurable.getTitleName (   self)

Definition at line 831 of file Configurable.py.

831  def getTitleName(self):
832  if log.isEnabledFor(logging.DEBUG):
833  return self.getFullJobOptName()
834  else:
835  return self.getFullName()
836 

◆ getTools()

def GaudiKernel.Configurable.Configurable.getTools (   self)

Definition at line 595 of file Configurable.py.

595  def getTools(self):
596  return self.__tools.values() # read only
597 

◆ getType()

def GaudiKernel.Configurable.Configurable.getType (   cls)

Definition at line 799 of file Configurable.py.

799  def getType(cls):
800  return cls.__name__
801 

◆ getValuedProperties()

def GaudiKernel.Configurable.Configurable.getValuedProperties (   self)

Definition at line 705 of file Configurable.py.

705  def getValuedProperties(self):
706  props = {}
707  for name, proxy in self._properties.items():
708  if self.isPropertySet(name):
709  value = proxy.__get__(self)
710  if hasattr(value, "getFullName"):
711  value = value.getFullName()
712  elif isinstance(value, (list, set, tuple)):
713  new_value = []
714  for i in value:
715  if hasattr(i, "getFullName"):
716  new_value.append(i.getFullName())
717  else:
718  new_value.append(i)
719  value = type(value)(new_value)
720  elif isinstance(value, dict):
721  new_value = {}
722  for i in value:
723  if hasattr(value[i], "getFullName"):
724  new_value[i] = value[i].getFullName()
725  else:
726  new_value[i] = value[i]
727  value = new_value
728  props[name] = value
729 
730  return props
731 

◆ hasParent()

def GaudiKernel.Configurable.Configurable.hasParent (   self,
  parent 
)

Reimplemented in GaudiKernel.Configurable.ConfigurableAlgTool.

Definition at line 569 of file Configurable.py.

569  def hasParent(self, parent):
570  return False
571 

◆ isApplicable()

def GaudiKernel.Configurable.Configurable.isApplicable (   self)
Return True is the instance can be "applied".
Always False for plain Configurable instances
(i.e. not ConfigurableUser).

Reimplemented in GaudiKernel.Configurable.ConfigurableUser.

Definition at line 1068 of file Configurable.py.

1068  def isApplicable(self):
1069  """
1070  Return True is the instance can be "applied".
1071  Always False for plain Configurable instances
1072  (i.e. not ConfigurableUser).
1073  """
1074  return False
1075 
1076 
1077 # classes for generic Gaudi component ===========
1078 
1079 

◆ isPropertySet()

def GaudiKernel.Configurable.Configurable.isPropertySet (   self,
  name 
)
Tell if the property 'name' has been set or not.

Because of a problem with list and dictionary properties, in those cases
if the value is equal to the default, the property is considered as not
set.

Definition at line 784 of file Configurable.py.

784  def isPropertySet(self, name):
785  """Tell if the property 'name' has been set or not.
786 
787  Because of a problem with list and dictionary properties, in those cases
788  if the value is equal to the default, the property is considered as not
789  set.
790  """
791  if not hasattr(self, name):
792  return False
793  default = self.getDefaultProperty(name)
794  if isinstance(default, (list, dict, set, DataHandle, GaudiHandleArray)):
795  value = getattr(self, name)
796  return value != default
797  return True
798 

◆ isPublic()

def GaudiKernel.Configurable.Configurable.isPublic (   self)

Reimplemented in GaudiKernel.Configurable.ConfigurableAlgTool.

Definition at line 811 of file Configurable.py.

811  def isPublic(self):
812  return True
813 

◆ jobOptName()

def GaudiKernel.Configurable.Configurable.jobOptName (   self)

Definition at line 815 of file Configurable.py.

815  def jobOptName(self):
816  log.error(
817  "jobOptName() is deprecated, use getJobOptName() instead for consistency%s",
818  error_explanation,
819  )
820  return self.getJobOptName() # compatibility
821 

◆ name()

def GaudiKernel.Configurable.Configurable.name (   self)

Definition at line 805 of file Configurable.py.

805  def name(self):
806  return self.getName()
807 

◆ properties()

def GaudiKernel.Configurable.Configurable.properties (   self)

Definition at line 732 of file Configurable.py.

732  def properties(self):
733  return self.getProperties() # compatibility
734 

◆ remove()

def GaudiKernel.Configurable.Configurable.remove (   self,
  items 
)

Definition at line 550 of file Configurable.py.

550  def remove(self, items):
551  if not isinstance(items, (list, tuple)):
552  items = [items]
553 
554  self.__children = [e for e in self.__children if e not in items]
555 

◆ removeAll()

def GaudiKernel.Configurable.Configurable.removeAll (   self)

Definition at line 556 of file Configurable.py.

556  def removeAll(self):
557  self.remove(self.__children)
558 

◆ setDefaults()

def GaudiKernel.Configurable.Configurable.setDefaults (   cls,
  handle 
)

Definition at line 837 of file Configurable.py.

837  def setDefaults(cls, handle):
838  pass
839 

◆ setParent()

def GaudiKernel.Configurable.Configurable.setParent (   self,
  parentName 
)

Reimplemented in GaudiKernel.Configurable.ConfigurableAlgTool.

Definition at line 563 of file Configurable.py.

563  def setParent(self, parentName):
564  pass
565 

◆ setProp()

def GaudiKernel.Configurable.Configurable.setProp (   self,
  name,
  value 
)
Set the value of a given property

Definition at line 780 of file Configurable.py.

780  def setProp(self, name, value):
781  """Set the value of a given property"""
782  return setattr(self, name, value)
783 

◆ setup()

def GaudiKernel.Configurable.Configurable.setup (   self)

Definition at line 651 of file Configurable.py.

651  def setup(self):
652  # make sure base class init has been called
653  if not hasattr(self, "_initok") or not self._initok:
654  # could check more, but this is the only explanation
655  raise TypeError(
656  "Configurable.__init__ not called in %s override"
657  % self.__class__.__name__
658  )
659 
660  # log.debug("calling setup() on " + self.getFullJobOptName())
661 
662  # setup self: this collects all values on the python side
663  self.__setupServices()
664  self.__setupDlls()
665  self.__setupDefaults()
666 
667  # setup children
668  for c in self.getAllChildren():
669  c.setup()
670 
671  # now get handle to work with for moving properties into the catalogue
672  handle = self.getHandle()
673  if not handle:
674  log.debug("no handle for %s: not transporting properties", self._name)
675  return # allowed, done early
676 
677  # pass final set of properties on to handle on the C++ side or JobOptSvc
678  for name in self._properties.keys():
679  if hasattr(self, name): # means property has python-side value/default
680  setattr(handle, name, getattr(self, name))
681 
682  # for debugging purposes
683  self._setupok = True
684 

◆ splitName()

def GaudiKernel.Configurable.Configurable.splitName (   self)

Definition at line 871 of file Configurable.py.

871  def splitName(self):
872  fullname = self.getName()
873  dot = fullname.find(".")
874  if dot != -1:
875  parentname = fullname[:dot]
876  longname = fullname[dot + 1 :]
877  else:
878  parentname = ""
879  longname = fullname
880  dot = longname.find(".")
881  if dot != -1:
882  name = longname[:dot]
883  else:
884  name = longname
885  return parentname, name, longname
886 

Member Data Documentation

◆ __children

GaudiKernel.Configurable.Configurable.__children
private

Definition at line 376 of file Configurable.py.

◆ __slots__

GaudiKernel.Configurable.Configurable.__slots__
staticprivate

Definition at line 164 of file Configurable.py.

◆ __tools

GaudiKernel.Configurable.Configurable.__tools
private

Definition at line 377 of file Configurable.py.

◆ _configurationLocked

GaudiKernel.Configurable.Configurable._configurationLocked
staticprivate

Definition at line 178 of file Configurable.py.

◆ _initok

GaudiKernel.Configurable.Configurable._initok
private

Definition at line 392 of file Configurable.py.

◆ _inSetDefaults

GaudiKernel.Configurable.Configurable._inSetDefaults
private

Definition at line 389 of file Configurable.py.

◆ _name

GaudiKernel.Configurable.Configurable._name
private

Definition at line 382 of file Configurable.py.

◆ _setupok

GaudiKernel.Configurable.Configurable._setupok
private

Definition at line 395 of file Configurable.py.

◆ _unpickling

GaudiKernel.Configurable.Configurable._unpickling
private

Definition at line 398 of file Configurable.py.

◆ allConfigurables

GaudiKernel.Configurable.Configurable.allConfigurables
static

Definition at line 174 of file Configurable.py.

◆ configurableServices

GaudiKernel.Configurable.Configurable.configurableServices
static

Definition at line 175 of file Configurable.py.

◆ indentUnit

GaudiKernel.Configurable.Configurable.indentUnit
static

Definition at line 160 of file Configurable.py.

◆ printHeaderPre

GaudiKernel.Configurable.Configurable.printHeaderPre
static

Definition at line 162 of file Configurable.py.

◆ printHeaderWidth

GaudiKernel.Configurable.Configurable.printHeaderWidth
static

Definition at line 161 of file Configurable.py.

◆ propertyNoValue

GaudiKernel.Configurable.Configurable.propertyNoValue
static

Definition at line 159 of file Configurable.py.


The documentation for this class was generated from the following file:
MSG::hex
MsgStream & hex(MsgStream &log)
Definition: MsgStream.h:281
GaudiPartProp.decorators.__getattr__
__getattr__
decorate the attribute access for Gaudi.ParticleProperty
Definition: decorators.py:186
GaudiPartProp.decorators.get
get
decorate the vector of properties
Definition: decorators.py:283
GaudiPartProp.decorators.__repr__
__repr__
decorate the vector of properties
Definition: decorators.py:173
GaudiPartProp.tests.id
id
Definition: tests.py:111
bug_34121.tool
tool
Definition: bug_34121.py:18
format
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
gaudiComponentHelp.properties
properties
Definition: gaudiComponentHelp.py:68
GaudiPartProp.decorators.__len__
__len__
Definition: decorators.py:177
GaudiPython.Pythonizations.__iter__
__iter__
Definition: Pythonizations.py:143
gaudirun.type
type
Definition: gaudirun.py:160
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
StringKeyEx.keys
keys
Definition: StringKeyEx.py:64
GaudiPartProp.decorators.__str__
__str__
decorate the printout for Gaudi::ParticleProperty
Definition: decorators.py:176
Gaudi::ParticleProperties::index
size_t index(const Gaudi::ParticleProperty *property, const Gaudi::Interfaces::IParticlePropertySvc *service)
helper utility for mapping of Gaudi::ParticleProperty object into non-negative integral sequential id...
Definition: IParticlePropertySvc.cpp:39