90 """To Gaudi, any object with the same type/name is the same object. Hence,
91 this is mimicked in the configuration: instantiating a new Configurable
92 of a type with the same name will return the same instance."""
97 name = kwargs[
'name' ]
98 elif 'name' in cls.__init__.__code__.co_varnames:
100 index = list(cls.__init__.__code__.co_varnames).
index(
'name' )
103 name = args[ index - 1 ]
106 name = cls.__init__.__defaults__[ index - (len(args)+1) ]
111 except (IndexError,TypeError):
112 raise TypeError(
'no "name" argument while instantiating "%s"' % cls.
__name__ )
116 if hasattr( cls,
'DefaultedName' ):
117 name = cls.DefaultedName
120 elif not name
or type(name)
is not str:
122 raise TypeError(
'could not retrieve name from %s.__init__ arguments' % cls.
__name__ )
125 if 0 <= name.find(
'.' ):
126 raise NameError(
'"%s": Gaudi name indexing with "." to private configurables not '
127 'allowed, as it leads to uncheckable backdoors' % name )
129 if 0 <= name.find(
'/' ):
130 raise NameError(
'"%s": type separator "/" no allowed in component name, '
131 'typename is derived from configurable instead' % name )
136 conf = cls.configurables[ name ]
139 for n,v
in kwargs.items():
141 setattr( conf, n, v )
142 except AttributeError
as originalAttributeError:
145 acceptableKeyWord =
False
148 def flat( classtree ):
149 if isinstance(classtree, (list, tuple)):
150 return [ j
for i
in classtree
for j
in flat( i ) ]
157 allclasses = flat( inspect.getclasstree( [ conf.__class__ ] ) )
158 for confklass
in allclasses:
162 if n
in confklass.__init__.__code__.co_varnames:
163 acceptableKeyWord =
True
165 except AttributeError:
170 if not acceptableKeyWord:
171 raise originalAttributeError
181 conf = object.__new__( cls )
188 cls.
__init__( conf, *args, **kwargs )
192 cls.configurables[ name ] = conf
196 raise TypeError(
'attempt to redefine type of "%s" (was: %s, new: %s)' %
301 def __iadd__( self, configs, descr = None, index = None ):
303 raise RuntimeError( f
"cannot add children to locked configurable {self.getJobOptName()}" )
305 if not type(configs)
in (list,tuple):
306 configs = ( configs, )
312 if not isinstance( cfg, Configurable ):
313 raise TypeError(
"'%s' is not a Configurable" % str(cfg) )
318 ccjo = cc.getJobOptName()
320 if c.getJobOptName() == ccjo:
321 log.debug(
'attempt to add a duplicate (%s.%s) ... dupe ignored', joname
or self.
name(), ccjo )
331 descr.__set__( self, cc )
333 setattr( self, cc.getName(), cc )
334 except AttributeError:
415 """Get all (private) configurable children, both explicit ones (added with +=)
416 and the ones in the private GaudiHandle properties"""
419 for proxy
in self._properties.values():
421 c = proxy.__get__( self )
422 except AttributeError:
425 if isinstance(c,Configurable)
and not c.isPublic():
427 elif isinstance(c,GaudiHandles.GaudiHandle):
429 conf = c.configurable
430 except AttributeError:
433 if not conf.isPublic():
435 elif isinstance(c,GaudiHandles.GaudiHandleArray):
439 if isinstance(ci,Configurable):
443 conf = ci.configurable
444 except AttributeError:
649 def __str__( self, indent = 0, headerLastIndentUnit=indentUnit ):
650 def _sorted_repr_set(value):
651 """Helper to print sorted set representation"""
652 return "{" + repr(sorted(value))[1:-1] +
"}" if value
else "set()"
654 indentStr = indent*Configurable.indentUnit
659 if logging.WARNING <= log.level:
660 if not Configurable._printOnce:
661 Configurable._printOnce = 1
662 return "Reduced Configurable printout; change log level for more details, e.g.:\n import AthenaCommon.Configurable as Configurable\n Configurable.log.setLevel( INFO )\n" + title
671 headerIndent = (indent-1)*Configurable.indentUnit + headerLastIndentUnit
674 rep = Configurable._printHeader( headerIndent, title )
680 rep += indentStr +
'|-<no properties>' + os.linesep
684 for p
in props.keys():
685 nameWidth=
max(nameWidth,len(p))
686 propNames = sorted(props.keys())
690 prefix = indentStr +
'|-%-*s' % (nameWidth,p)
692 if log.isEnabledFor( logging.DEBUG ):
693 if v != Configurable.propertyNoValue:
694 address =
' @%11s' % hex(id(v))
699 default = defs.get(p)
701 if not isinstance(v,MutableSequence)
and v == Configurable.propertyNoValue:
703 strVal = repr(default)
707 if isinstance(v,Configurable):
708 vv = v.getGaudiHandle()
711 if isinstance(vv,(GaudiHandles.GaudiHandle,
712 GaudiHandles.GaudiHandleArray,
713 DataHandle.DataHandle)):
715 strDef = repr(default.toStringProperty())
716 if strDef == repr(vv.toStringProperty()):
718 elif isinstance(vv, set):
719 strVal = _sorted_repr_set(vv)
720 strDef = _sorted_repr_set(default)
723 strDef = repr(default)
725 line = prefix +
' = ' + strVal
727 if strDef
is not None:
729 if len(line) + len(strDef) > Configurable.printHeaderWidth:
730 line += os.linesep + indentStr +
'| ' + (len(prefix)-len(indentStr)-3)*
' '
731 line +=
' (default: %s)' % (strDef,)
733 rep += line + os.linesep
739 if isinstance(c, ConfigurableAlgorithm): childNotToSort.append(c)
740 else: childToSort.append(c)
742 childToSort.sort(key=
lambda x : x.getName())
743 for cfg
in childToSort + childNotToSort:
744 rep += cfg.__str__( indent + 1,
'|=' ) + os.linesep
747 rep += Configurable._printFooter( indentStr, title )
761 for key,val
in sorted(properties.items()):
762 if isinstance(val, (GaudiHandles.PublicToolHandle, GaudiHandles.PrivateToolHandle)):
763 propstr += val.getFullName()
764 elif isinstance(val,Configurable):
765 propstr +=
"({0}:{1})".format(key,val.getFlattenedProperties())
766 elif isinstance(val, (GaudiHandles.PublicToolHandleArray, GaudiHandles.PrivateToolHandleArray)):
769 if isinstance(th,Configurable):
770 propstr +=
"({0}:{1}".format(th.getFullName(), th.getFlattenedProperties())
772 propstr += th.getFullName()
774 propstr +=
"({0}:{1})".format(key,str(val))