The Gaudi Framework  v38r0 (2143aa4c)
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 148 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 338 of file Configurable.py.

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

Member Function Documentation

◆ __bool__()

def GaudiKernel.Configurable.Configurable.__bool__ (   self)

Definition at line 546 of file Configurable.py.

546  def __bool__(self):
547  return True
548 

◆ __deepcopy__()

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

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

Definition at line 440 of file Configurable.py.

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

◆ __delattr__()

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

Definition at line 521 of file Configurable.py.

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

◆ __getattr__()

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

Definition at line 491 of file Configurable.py.

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

◆ __getnewargs__()

def GaudiKernel.Configurable.Configurable.__getnewargs__ (   self)

Definition at line 413 of file Configurable.py.

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

◆ __getstate__()

def GaudiKernel.Configurable.Configurable.__getstate__ (   self)

Definition at line 400 of file Configurable.py.

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

◆ __iadd__()

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

Definition at line 456 of file Configurable.py.

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

◆ __iter__()

def GaudiKernel.Configurable.Configurable.__iter__ (   self)

Definition at line 436 of file Configurable.py.

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

◆ __len__()

def GaudiKernel.Configurable.Configurable.__len__ (   self)

Definition at line 433 of file Configurable.py.

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

◆ __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 179 of file Configurable.py.

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

◆ __repr__()

def GaudiKernel.Configurable.Configurable.__repr__ (   self)

Definition at line 968 of file Configurable.py.

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

◆ __setattr__()

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

Reimplemented in GaudiKernel.Configurable.ConfigurableGeneric.

Definition at line 507 of file Configurable.py.

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

◆ __setstate__()

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

Definition at line 416 of file Configurable.py.

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

◆ __setupDefaults()

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

Definition at line 943 of file Configurable.py.

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

◆ __setupDlls()

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

Definition at line 930 of file Configurable.py.

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

◆ __setupServices()

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

Definition at line 912 of file Configurable.py.

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

◆ __str__()

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

Definition at line 971 of file Configurable.py.

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

◆ _isInSetDefaults()

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

Definition at line 909 of file Configurable.py.

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

◆ _printFooter()

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

Definition at line 960 of file Configurable.py.

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

◆ _printHeader()

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

Definition at line 951 of file Configurable.py.

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

◆ addTool()

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

Definition at line 886 of file Configurable.py.

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

◆ children()

def GaudiKernel.Configurable.Configurable.children (   self)

Definition at line 597 of file Configurable.py.

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

◆ clone()

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

Definition at line 839 of file Configurable.py.

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

◆ copyChild()

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

Reimplemented in GaudiKernel.Configurable.ConfigurableService.

Definition at line 559 of file Configurable.py.

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

◆ copyChildAndSetParent()

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

Definition at line 571 of file Configurable.py.

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

◆ 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 605 of file Configurable.py.

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

◆ getChildren()

def GaudiKernel.Configurable.Configurable.getChildren (   self)

Definition at line 591 of file Configurable.py.

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

◆ getDefaultProperties()

def GaudiKernel.Configurable.Configurable.getDefaultProperties (   cls)

Definition at line 735 of file Configurable.py.

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

◆ getDefaultProperty()

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

Definition at line 751 of file Configurable.py.

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

◆ getFullJobOptName()

def GaudiKernel.Configurable.Configurable.getFullJobOptName (   self)

Definition at line 824 of file Configurable.py.

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

◆ getFullName()

def GaudiKernel.Configurable.Configurable.getFullName (   self)

Reimplemented in GaudiKernel.Configurable.ConfigurableAlgTool.

Definition at line 821 of file Configurable.py.

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

◆ 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 807 of file Configurable.py.

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

◆ getName()

def GaudiKernel.Configurable.Configurable.getName (   self)

Definition at line 801 of file Configurable.py.

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

◆ getParent()

def GaudiKernel.Configurable.Configurable.getParent (   self)

Reimplemented in GaudiKernel.Configurable.ConfigurableAlgTool.

Definition at line 565 of file Configurable.py.

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

◆ getPrintTitle()

def GaudiKernel.Configurable.Configurable.getPrintTitle (   self)

Reimplemented in GaudiKernel.Configurable.ConfigurableAlgTool.

Definition at line 827 of file Configurable.py.

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

◆ getProp()

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

Definition at line 772 of file Configurable.py.

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

◆ getProperties()

def GaudiKernel.Configurable.Configurable.getProperties (   self)

Definition at line 684 of file Configurable.py.

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

◆ getPropertiesWithDescription()

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

Definition at line 694 of file Configurable.py.

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

◆ getSequence()

def GaudiKernel.Configurable.Configurable.getSequence (   self)

Definition at line 644 of file Configurable.py.

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

◆ getTitleName()

def GaudiKernel.Configurable.Configurable.getTitleName (   self)

Definition at line 830 of file Configurable.py.

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

◆ getTools()

def GaudiKernel.Configurable.Configurable.getTools (   self)

Definition at line 594 of file Configurable.py.

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

◆ getType()

def GaudiKernel.Configurable.Configurable.getType (   cls)

Definition at line 798 of file Configurable.py.

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

◆ getValuedProperties()

def GaudiKernel.Configurable.Configurable.getValuedProperties (   self)

Definition at line 704 of file Configurable.py.

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

◆ hasParent()

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

Reimplemented in GaudiKernel.Configurable.ConfigurableAlgTool.

Definition at line 568 of file Configurable.py.

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

◆ 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 1067 of file Configurable.py.

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

◆ 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 783 of file Configurable.py.

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

◆ isPublic()

def GaudiKernel.Configurable.Configurable.isPublic (   self)

Reimplemented in GaudiKernel.Configurable.ConfigurableAlgTool.

Definition at line 810 of file Configurable.py.

810  def isPublic(self):
811  return True
812 

◆ jobOptName()

def GaudiKernel.Configurable.Configurable.jobOptName (   self)

Definition at line 814 of file Configurable.py.

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

◆ name()

def GaudiKernel.Configurable.Configurable.name (   self)

Definition at line 804 of file Configurable.py.

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

◆ properties()

def GaudiKernel.Configurable.Configurable.properties (   self)

Definition at line 731 of file Configurable.py.

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

◆ remove()

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

Definition at line 549 of file Configurable.py.

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

◆ removeAll()

def GaudiKernel.Configurable.Configurable.removeAll (   self)

Definition at line 555 of file Configurable.py.

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

◆ setDefaults()

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

Definition at line 836 of file Configurable.py.

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

◆ setParent()

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

Reimplemented in GaudiKernel.Configurable.ConfigurableAlgTool.

Definition at line 562 of file Configurable.py.

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

◆ setProp()

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

Definition at line 779 of file Configurable.py.

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

◆ setup()

def GaudiKernel.Configurable.Configurable.setup (   self)

Definition at line 650 of file Configurable.py.

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

◆ splitName()

def GaudiKernel.Configurable.Configurable.splitName (   self)

Definition at line 870 of file Configurable.py.

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

Member Data Documentation

◆ __children

GaudiKernel.Configurable.Configurable.__children
private

Definition at line 375 of file Configurable.py.

◆ __slots__

GaudiKernel.Configurable.Configurable.__slots__
staticprivate

Definition at line 163 of file Configurable.py.

◆ __tools

GaudiKernel.Configurable.Configurable.__tools
private

Definition at line 376 of file Configurable.py.

◆ _configurationLocked

GaudiKernel.Configurable.Configurable._configurationLocked
staticprivate

Definition at line 177 of file Configurable.py.

◆ _initok

GaudiKernel.Configurable.Configurable._initok
private

Definition at line 391 of file Configurable.py.

◆ _inSetDefaults

GaudiKernel.Configurable.Configurable._inSetDefaults
private

Definition at line 388 of file Configurable.py.

◆ _name

GaudiKernel.Configurable.Configurable._name
private

Definition at line 381 of file Configurable.py.

◆ _setupok

GaudiKernel.Configurable.Configurable._setupok
private

Definition at line 394 of file Configurable.py.

◆ _unpickling

GaudiKernel.Configurable.Configurable._unpickling
private

Definition at line 397 of file Configurable.py.

◆ allConfigurables

GaudiKernel.Configurable.Configurable.allConfigurables
static

Definition at line 173 of file Configurable.py.

◆ configurableServices

GaudiKernel.Configurable.Configurable.configurableServices
static

Definition at line 174 of file Configurable.py.

◆ indentUnit

GaudiKernel.Configurable.Configurable.indentUnit
static

Definition at line 159 of file Configurable.py.

◆ printHeaderPre

GaudiKernel.Configurable.Configurable.printHeaderPre
static

Definition at line 161 of file Configurable.py.

◆ printHeaderWidth

GaudiKernel.Configurable.Configurable.printHeaderWidth
static

Definition at line 160 of file Configurable.py.

◆ propertyNoValue

GaudiKernel.Configurable.Configurable.propertyNoValue
static

Definition at line 158 of file Configurable.py.


The documentation for this class was generated from the following file:
MSG::hex
MsgStream & hex(MsgStream &log)
Definition: MsgStream.h:282
bug_34121.name
name
Definition: bug_34121.py:20
GaudiAlg.HistoUtils.__str__
__str__
Definition: HistoUtils.py:538
GaudiPartProp.decorators.__getattr__
__getattr__
decorate the attribute access for Gaudi.ParticleProperty
Definition: decorators.py:185
GaudiPartProp.decorators.get
get
decorate the vector of properties
Definition: decorators.py:282
max
EventIDBase max(const EventIDBase &lhs, const EventIDBase &rhs)
Definition: EventIDBase.h:225
GaudiPartProp.tests.id
id
Definition: tests.py:111
bug_34121.tool
tool
Definition: bug_34121.py:17
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:176
GaudiPython.Pythonizations.__iter__
__iter__
Definition: Pythonizations.py:143
gaudirun.type
type
Definition: gaudirun.py:160
StringKeyEx.keys
keys
Definition: StringKeyEx.py:63
GaudiAlg.HistoUtils.__repr__
__repr__
Definition: HistoUtils.py:535
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