19from inspect
import isclass
21from GaudiConfig.ControlFlow
import (
56 "ConfigurableAlgorithm",
57 "ConfigurableAlgTool",
58 "ConfigurableAuditor",
59 "ConfigurableService",
67 "appendPostConfigAction",
68 "removePostConfigAction",
79log = logging.getLogger(
"Configurable")
84 Expand environment variables "data".
85 Data can be string, list, tuple and dictionary. For collection, all the
86 contained strings will be manipulated (recursively).
92 return os.path.expandvars(data)
93 elif typ
in [list, tuple]:
108 Error occurred in the configuration process.
117class PropertyReference(object):
122 return "@%s" % self.
name
127 refname, refprop = self.
name.rsplit(
".", 1)
128 if refname
in Configurable.allConfigurables:
129 conf = Configurable.allConfigurables[refname]
130 retval = getattr(conf, refprop)
131 if hasattr(retval,
"getFullName"):
132 retval = retval.getFullName()
134 raise NameError(
"name '%s' not found resolving '%s'" % (refname, self))
138 """This function allow transparent integration with
139 Configurable.getValuedProperties.
146 except AttributeError:
155 """Base class for Gaudi components that implement the IProperty interface.
156 Provides most of the boilerplate code, but the actual useful classes
157 are its derived ConfigurableAlgorithm, ConfigurableService, and
158 ConfigurableAlgTool."""
164 propertyNoValue =
"<no value>"
166 printHeaderWidth = 100
179 allConfigurables = {}
180 configurableServices = {}
183 _configurationLocked =
False
186 """To Gaudi, any object with the same type/name is the same object. Hence,
187 this is mimicked in the configuration: instantiating a new Configurable
188 of a type with the same name will return the same instance."""
192 func_defaults = cls.
__init__.__defaults__
196 name = kwargs[
"name"]
197 elif "name" in func_code.co_varnames:
199 index = list(func_code.co_varnames).index(
"name")
202 name = args[index - 1]
205 name = func_defaults[index - (len(args) + 1)]
210 except (IndexError, TypeError):
212 'no "name" argument while instantiating "%s"' % cls.
__name__
217 if hasattr(cls,
"DefaultedName"):
218 name = cls.DefaultedName
221 elif not name
or not isinstance(name, str):
224 "could not retrieve name from %s.__init__ arguments" % cls.
__name__
229 if issubclass(cls, ConfigurableAlgTool)
and "." not in name:
230 name =
"ToolSvc." + name
245 for n, v
in kwargs.items():
250 and "_enabled" not in kwargs
251 and isinstance(conf, ConfigurableUser)
255 setattr(conf,
"_enabled",
True)
259 spos = name.find(
"/")
262 ti_name =
"%s/%s" % (name, name)
270 if i_name == name[spos + 1 :]
and i_name
in cls.
configurables:
280 and i_name == name[spos + 1 :]
285 if conf.__class__
is ConfigurableGeneric:
289 newconf = object.__new__(cls)
290 cls.
__init__(newconf, *args, **kwargs)
295 for n
in newconf.__slots__:
297 for n
in conf._properties:
298 if names[n.lower()] != n:
300 "Option '%s' was used for %s, but the correct spelling is '%s'"
301 % (n, name, names[n.lower()])
303 setattr(newconf, names[n.lower()], getattr(conf, n))
304 for n, v
in kwargs.items():
305 setattr(newconf, n, v)
312 'attempt to redefine type of "%s" (was: %s, new: %s)%s',
314 conf.__class__.__name__,
322 for n, v
in kwargs.items():
327 conf = object.__new__(cls)
334 if base.__name__ ==
"ConfigurableService":
349 if klass == Configurable:
351 "%s is an ABC and can not be instantiated" % str(Configurable)
363 for meth, nArgs
in meths.items():
365 f = getattr(klass, meth)
366 except AttributeError:
367 raise NotImplementedError(
368 "%s is missing in class %s" % (meth, str(klass))
372 nargcount = f.__code__.co_argcount
373 fdefaults = f.__defaults__
374 ndefaults = fdefaults
and len(fdefaults)
or 0
375 if not nargcount - ndefaults <= nArgs <= nargcount:
377 "%s.%s requires exactly %d arguments" % (klass, meth, nArgs)
410 dict[name] = proxy.__get__(self)
411 except AttributeError:
414 dict[
"_Configurable__children"] = self.
__children
415 dict[
"_Configurable__tools"] = self.
__tools
416 dict[
"_name"] = self.
_name
424 from contextlib
import contextmanager
435 for n, v
in dict.items():
452 proxy.__set__(newconf, proxy.__get__(self))
453 except AttributeError:
463 if not isinstance(configs, (list, tuple)):
470 if not isinstance(cfg, Configurable):
471 raise TypeError(
"'%s' is not a Configurable" % str(cfg))
476 ccjo = cc.getJobOptName()
478 if c.getJobOptName() == ccjo:
480 "attempt to add a duplicate ... dupe ignored%s",
489 descr.__set__(self, cc)
491 setattr(self, cc.getName(), cc)
492 except AttributeError:
502 if isinstance(self.
_properties[attr].__get__(self), DataHandle):
506 if c.getName() == attr:
509 raise AttributeError(
510 "'%s' object has no attribute '%s'" % (self.
__class__, attr)
516 "%s: Configuration cannot be modified after the ApplicationMgr has been started."
521 except AttributeError:
522 raise AttributeError(
523 "Configurable '%s' does not have property '%s'."
532 prop.__delete__(self)
533 prop.__set__(self, prop.default)
543 if c.getName() == attr:
548 del self.__dict__[attr]
549 except (AttributeError, KeyError):
556 if not isinstance(items, (list, tuple)):
566 return copy.deepcopy(child)
580 if hasattr(cc,
"setParent")
and parent:
583 except RuntimeError
as e:
585 log.error(str(e) +
"%s", error_explanation)
586 ccbd = cc.configurables[cc.getJobOptName()]
590 if cc
in proxy.history:
591 proxy.__set__(ccbd, proxy.__get__(cc))
604 log.error(
"children() is deprecated, use getChildren() instead for consistency")
606 "getChildren() returns a copy; to add a child, use 'parent += child'%s",
612 """Get all (private) configurable children, both explicit ones (added with +=)
613 and the ones in the private GaudiHandle properties"""
618 c = proxy.__get__(self)
619 except AttributeError:
622 if isinstance(c, Configurable)
and not c.isPublic():
624 elif isinstance(c, GaudiHandle):
626 conf = c.configurable
627 except AttributeError:
630 if not conf.isPublic():
632 elif isinstance(c, GaudiHandleArray):
636 if isinstance(ci, Configurable):
640 conf = ci.configurable
641 except AttributeError:
653 elems.append(c.getFullName())
658 if not hasattr(self,
"_initok")
or not self.
_initok:
661 "Configurable.__init__ not called in %s override"
677 handle = self.getHandle()
679 log.debug(
"no handle for %s: not transporting properties", self.
_name)
684 if hasattr(self, name):
685 setattr(handle, name, getattr(self, name))
694 props[name] = proxy.__get__(self)
695 except AttributeError:
696 props[name] = Configurable.propertyNoValue
701 """Get all properties with their description string as { name : (value, desc) }."""
705 props[name] = (proxy.__get__(self), proxy.__doc__)
706 except AttributeError:
707 props[name] = (Configurable.propertyNoValue, proxy.__doc__)
714 value = proxy.__get__(self)
715 if hasattr(value,
"getFullName"):
716 value = value.getFullName()
717 elif isinstance(value, (list, set, tuple)):
720 if hasattr(i,
"getFullName"):
721 new_value.append(i.getFullName())
724 value = type(value)(new_value)
725 elif isinstance(value, dict):
728 if hasattr(value[i],
"getFullName"):
731 new_value[i] = value[i]
748 if k
not in c.__dict__
and hasattr(v,
"default"):
749 c.__dict__[k] = v.default
759 if name
in c.__dict__:
760 return c.__dict__[name]
765 if hasattr(v,
"default"):
773 """Returns the value of the given property."""
774 if hasattr(self, name):
775 return getattr(self, name)
780 """Set the value of a given property"""
781 return setattr(self, name, value)
784 """Tell if the property 'name' has been set or not.
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
790 if not hasattr(self, name):
793 if isinstance(default, (list, dict, set, DataHandle, GaudiHandleArray)):
794 value = getattr(self, name)
795 return value != default
816 "jobOptName() is deprecated, use getJobOptName() instead for consistency%s",
831 if log.isEnabledFor(logging.DEBUG):
839 def clone(self, name=None, **kwargs):
841 if hasattr(self,
"DefaultedName"):
842 name = self.DefaultedName
844 name = self.getType()
846 newconf = Configurable.__new__(self.__class__, name)
847 self.__class__.
__init__(newconf, name)
849 for proxy
in self._properties.values():
851 value = proxy.__get__(self)
852 if isinstance(value, (str, list, dict, tuple, set)):
854 value = type(value)(value)
855 proxy.__set__(newconf, value)
856 except AttributeError:
859 for c
in self.__children:
862 for n, t
in self.__tools.items():
863 newconf.addTool(t, n)
865 for name, value
in kwargs.items():
866 setattr(newconf, name, value)
872 dot = fullname.find(
".")
874 parentname = fullname[:dot]
875 longname = fullname[dot + 1 :]
879 dot = longname.find(
".")
881 name = longname[:dot]
884 return parentname, name, longname
887 if isclass(tool)
and issubclass(tool, ConfigurableAlgTool):
890 priv_tool = tool(self.
getName() +
"." + name)
891 elif isinstance(tool, ConfigurableAlgTool):
893 name = tool.splitName()[1]
894 priv_tool = tool.clone(self.
getName() +
"." + name)
897 classname = tool.__name__
899 classname = type(tool).__name__
901 "addTool requires AlgTool configurable. Got %s type" % classname
906 setattr(self, name, self.
__tools[name])
922 handle = __main__.Service(svc)
927 if hasattr(self,
"configure" + svc):
928 eval(
"self.configure" + svc +
"( handle )")
931 dlls = self.getDlls()
934 elif isinstance(dlls, types.StringType):
937 from __main__
import theApp
939 dlls = filter(
lambda d: d
not in theApp.Dlls, dlls)
952 preLen = Configurable.printHeaderPre
954 Configurable.printHeaderWidth - preLen - 3 - len(title)
956 postLen = max(preLen, postLen)
957 return indentStr +
"/%s %s %s" % (preLen *
"*", title, postLen *
"*")
961 preLen = Configurable.printHeaderPre
963 Configurable.printHeaderWidth - preLen - 12 - len(title)
965 postLen = max(preLen, postLen)
966 return indentStr +
"\\%s (End of %s) %s" % (preLen *
"-", title, postLen *
"-")
971 def __str__(self, indent=0, headerLastIndentUnit=indentUnit):
974 def _sorted_repr_set(value):
975 """Helper to print sorted set representation"""
976 return "{" + repr(sorted(value))[1:-1] +
"}" if value
else "set()"
978 indentStr = indent * Configurable.indentUnit
983 headerIndent = (indent - 1) * Configurable.indentUnit + headerLastIndentUnit
986 rep = Configurable._printHeader(headerIndent, title)
992 rep += indentStr +
"|-<no properties>" + os.linesep
996 for p
in props.keys():
997 nameWidth = max(nameWidth, len(p))
998 for p, v
in props.items():
1000 prefix = indentStr +
"|-%-*s" % (nameWidth, p)
1002 if log.isEnabledFor(logging.DEBUG):
1003 if v != Configurable.propertyNoValue:
1004 address =
" @%11s" % hex(id(v))
1009 default = defs.get(p)
1010 if v == Configurable.propertyNoValue:
1012 strVal = repr(default)
1016 if hasattr(v,
"getGaudiHandle"):
1017 vv = v.getGaudiHandle()
1020 if isinstance(vv, (GaudiHandle, GaudiHandleArray, DataHandle)):
1023 if hasattr(default,
"toStringProperty"):
1024 strDef = repr(default.toStringProperty())
1026 strDef = repr(default)
1027 if strDef == repr(vv.toStringProperty()):
1029 elif isinstance(vv, set):
1030 strVal = _sorted_repr_set(vv)
1031 strDef = _sorted_repr_set(default)
1034 strDef = repr(default)
1036 line = prefix +
" = " + strVal
1038 if strDef
is not None:
1040 if len(line) + len(strDef) > Configurable.printHeaderWidth:
1045 + (len(prefix) - len(indentStr) - 3) *
" "
1047 line +=
" (default: %s)" % (strDef,)
1049 rep += line + os.linesep
1061 rep += cfg.__str__(indent + 1,
"|=") + os.linesep
1064 rep += Configurable._printFooter(indentStr, title)
1069 Return True is the instance can be "applied".
1070 Always False for plain Configurable instances
1071 (i.e. not ConfigurableUser).
1087 object.__setattr__(obj, self.
__name__, value)
1094 Configurable.__init__(self, name)
1103 return "GenericComponent"
1114 super(ConfigurableGeneric, self).
__setattr__(name, value)
1118 if isinstance(value, Configurable):
1119 self.__dict__[name] = value
1123 if name
not in self._properties:
1125 self._properties[name].__set__(self, value)
1138 super(ConfigurableAlgorithm, self).
__init__(name)
1161 elif rhs
is CFFalse:
1163 return AndNode(self, rhs)
1170 return OrNode(self, rhs)
1173 return InvertNode(self)
1176 return OrderedNode(self, rhs)
1187 return repr(self) == repr(other)
1190 """Return a unique identifier for this object.
1192 As we use the `repr` of this object to check for equality, we use it
1193 here to define uniqueness.
1196 return hash((repr(self),))
1202 "AuditInitialize": 0,
1211 if isinstance(child, ConfigurableAlgTool)
and not child.isPublic():
1212 return copy.deepcopy(child)
1235 "AuditInitialize": 0,
1240 super(ConfigurableAlgTool, self).
__init__(name)
1245 name = name[name.find(
"/") + 1 :]
1269 return pop + Configurable.getPrintTitle(self)
1279 instance = name[name.rfind(
".") + 1 :]
1283 if isinstance(c, ConfigurableAlgTool):
1284 c.setParent(parentName +
"." + instance)
1307 return parent ==
"ToolSvc"
1318 name = name[name.rfind(
".") + 1 :]
1319 return str(self.
getType() +
"/" + name)
1326 __slots__ = {
"_jobOptName": 0,
"OutputLevel": 0,
"Enable": 1}
1329 super(ConfigurableAuditor, self).
__init__(name)
1331 name = name[name.find(
"/") + 1 :]
1355 "__used_instances__": [],
1367 __used_configurables__ = []
1370 __queried_configurables__ = []
1372 def __init__(self, name=Configurable.DefaultName, _enabled=True, **kwargs):
1373 super(ConfigurableUser, self).
__init__(name)
1374 for n, v
in kwargs.items():
1392 if isinstance(used, tuple):
1393 used, used_name = used
1397 if isinstance(used, str):
1398 used_class = confDbGetConfigurable(used)
1403 inst = used_class(name=used_name, _enabled=
False)
1404 except AttributeError:
1408 inst = used_class(name=used_name)
1412 if isinstance(queried, str):
1413 queried = confDbGetConfigurable(queried)
1414 inst = queried(_enabled=
False)
1415 except AttributeError:
1421 Declare that we are going to modify the Configurable 'other' in our
1422 __apply_configuration__.
1425 if hasattr(other,
"__users__"):
1426 other.__users__.append(self)
1430 Declare that we are going to retrieve property values from the
1431 ConfigurableUser 'other' in our __apply_configuration__.
1433 if not isinstance(other, ConfigurableUser):
1435 "'%s': Cannot make passive use of '%s', it is not a ConfigurableUser"
1436 % (self.
name(), other.name())
1438 other.__addActiveUseOf(self)
1452 Remove this ConfigurableUser instance from the users list of the used
1456 if hasattr(used,
"__users__"):
1457 used.__users__.remove(self)
1461 Propagate the property 'name' (if set) to other configurables (if possible).
1464 propagate to all the entries in __used_configurables__
1465 a configurable instance:
1466 propagate only to it
1467 list of configurable instances:
1468 propagate to all of them.
1472 - if the local property is set, the other property will be overwritten
1473 - local property not set and other set => keep other
1474 - local property not set and other not set => overwrite the default for
1475 ConfigurableUser instances and set the property for Configurables
1480 elif type(others)
not in [list, tuple]:
1486 for other
in [o
for o
in others
if name
in o.__slots__]:
1489 if other.isPropertySet(name):
1491 "Property '%(prop)s' is set in both '%(self)s' and '%(other)s', using '%(self)s.%(prop)s'"
1492 % {
"self": self.
name(),
"other": other.name(),
"prop": name}
1494 other.setProp(name, value)
1496 elif not other.isPropertySet(name):
1497 if isinstance(other, ConfigurableUser):
1498 otherType = type(other._properties[name].getDefault())
1499 other._properties[name].setDefault(value)
1500 if otherType
in (list, dict, set):
1503 other.setProp(name, otherType(value))
1505 other.setProp(name, value)
1510 Call propagateProperty for each property listed in 'names'.
1511 If 'names' is None, all the properties are propagated.
1515 names = [p
for p
in self.
__slots__ if not p.startswith(
"_")]
1521 Function to be overridden to convert the high level configuration into a
1523 The default implementation calls applyConf, which is the method defined
1524 in some ConfigurableUser implementations.
1530 Function to be overridden to convert the high level configuration into a
1537 Function used to define the name of the private instance of a given class
1539 This method is used when the __used_configurables_property__ declares the
1540 need of a private used configurable without specifying the name.
1542 if isinstance(cls, str):
1545 clName = cls.__name__
1546 return "%s_%s" % (self.name(), clName)
1550 Return the used instance with a given name.
1553 if i.name() == name:
1554 if hasattr(i,
"_enabled"):
1559 raise KeyError(name)
1563 Return True is the instance can be "applied".
1569postConfigActions = []
1574 Add a new callable ('function') to the list of post-configuration actions.
1575 If the callable is already in the list, it is moved to the end of the list.
1576 The list is directly accessible as 'GaudiKernel.Configurable.postConfigActions'.
1579 postConfigActions.remove(function)
1582 postConfigActions.append(function)
1587 Remove a callable from the list of post-config actions.
1588 The list is directly accessible as 'GaudiKernel.Configurable.postConfigActions'.
1590 postConfigActions.remove(function)
1593_appliedConfigurableUsers_ =
False
1598 Call the apply method of all the ConfigurableUser instances respecting the
1599 dependencies. First the C.U.s that are not used by anybody, then the used
1600 ones, when they are not used anymore.
1603 global _appliedConfigurableUsers_, postConfigActions
1604 if _appliedConfigurableUsers_:
1606 _appliedConfigurableUsers_ =
True
1608 def applicableConfUsers():
1610 Generator returning all the configurables that can be applied in the
1611 order in which they can be applied.
1626 for c
in Configurable.allConfigurables.values()
1629 except StopIteration:
1632 debugApplyOrder =
"GAUDI_DUBUG_CONF_USER" in os.environ
1633 for c
in applicableConfUsers():
1635 log.info(
"applying configuration of %s", c.name())
1637 sys.stderr.write(
"applying %r" % c)
1638 c.__apply_configuration__()
1641 log.info(
"skipping configuration of %s", c.name())
1643 if hasattr(c,
"__detach_used__"):
1650 for c
in Configurable.allConfigurables.values()
1651 if hasattr(c,
"__apply_configuration__")
and c._enabled
and not c._applied
1656 "Detected loop in the ConfigurableUser"
1657 " dependencies: %r" % [c.name()
for c
in leftConfUsers]
1661 unknown = set(Configurable.allConfigurables)
1665 log.debug(
"new configurable created automatically: %s", k)
1667 Configurable.allConfigurables[k].properties()
1671 for action
in postConfigActions:
1677 Obsolete (buggy) implementation of applyConfigurableUsers(), kept to provide
1678 backward compatibility for configurations that where relying (implicitly) on
1679 bug #103803, or on a specific (non guaranteed) order of execution.
1681 @see applyConfigurableUsers()
1684 global _appliedConfigurableUsers_, postConfigActions
1685 if _appliedConfigurableUsers_:
1687 _appliedConfigurableUsers_ =
True
1689 debugApplyOrder =
"GAUDI_DUBUG_CONF_USER" in os.environ
1692 for c
in Configurable.allConfigurables.values()
1693 if hasattr(c,
"__apply_configuration__")
1696 while applied
and confUsers:
1700 if hasattr(c,
"__users__")
and c.__users__:
1701 newConfUsers.append(c)
1706 enabled = (
not hasattr(c,
"_enabled"))
or c._enabled
1708 log.info(
"applying configuration of %s", c.name())
1710 sys.stderr.write(
"applying %r" % c)
1711 c.__apply_configuration__()
1714 log.info(
"skipping configuration of %s", c.name())
1715 if hasattr(c,
"__detach_used__"):
1718 confUsers = newConfUsers
1722 "Detected loop in the ConfigurableUser "
1723 " dependencies: %r" % [c.name()
for c
in confUsers]
1727 unknown = set(Configurable.allConfigurables)
1731 log.debug(
"new configurable created automatically: %s", k)
1733 Configurable.allConfigurables[k].properties()
1737 for action
in postConfigActions:
1743 Function to select all and only the configurables that have to be used in
1744 GaudiPython.AppMgr constructor.
1745 This is needed because in Athena the implementation have to be different (the
1746 configuration is used in a different moment).
1750 for k, v
in Configurable.allConfigurables.items()
1751 if v.getGaudiType() !=
"User"
1757 Clean up all configurations and configurables.
1759 for c
in Configurable.allConfigurables.values():
1760 c.__class__.configurables.clear()
1761 Configurable.allConfigurables.clear()
1764 ConfigurableGeneric.configurables.clear()
1768 from .ProcessJobOptions
import _included_files
1770 for file
in _included_files:
1771 dirname, basname = os.path.split(file)
1772 basname, ext = os.path.splitext(basname)
1773 if basname
in sys.modules:
1774 del sys.modules[basname]
1775 _included_files.clear()
1784 return self.
stack[-1]
1793 name = prefix + str(cnt)
1794 while name
in allConfigurables:
1796 name = prefix + str(cnt)
1800 from Configurables
import Gaudi__Sequencer
1806 if visitee
in (CFTrue, CFFalse):
1807 stack.append(self.
_newSeq(Invert=visitee
is CFFalse))
1808 elif isinstance(visitee, (ControlFlowLeaf, ConfigurableAlgorithm)):
1809 stack.append(visitee)
1810 elif isinstance(visitee, (OrNode, AndNode, OrderedNode)):
1815 ModeOR=isinstance(visitee, OrNode),
1816 ShortCircuit=
not isinstance(visitee, OrderedNode),
1819 elif isinstance(visitee, ignore):
1820 if hasattr(stack[-1],
"IgnoreFilterPassed"):
1821 stack[-1].IgnoreFilterPassed =
True
1824 self.
_newSeq(Members=[stack.pop()], IgnoreFilterPassed=
True)
1826 elif isinstance(visitee, InvertNode):
1827 if hasattr(stack[-1],
"Invert"):
1828 stack[-1].Invert =
True
1830 stack.append(self.
_newSeq(Members=[stack.pop()], Invert=
True))
1835 Convert a control flow expression to nested GaudiSequencers.
1837 if not isinstance(expression, ControlFlowNode):
1839 "ControlFlowNode instance expected, got %s" % type(expression).__name__
1842 expression.visitNode(visitor)
1843 return visitor.sequence
1848 Helper class to use a ControlFlowNode as an algorithm configurable
1855 if name
in Configurable.allConfigurables:
1856 instance = Configurable.allConfigurables[name]
1857 assert type(instance)
is cls, (
1858 "trying to reuse {0!r} as name of a {1} instance while it"
1860 "already used for an instance of {2}"
1864 instance = super(SuperAlgorithm, cls).
__new__(cls)
1865 Configurable.allConfigurables[name] = instance
1872 setattr(self, key, kwargs[key])
1897 Instantiate and algorithm of type 'typ' with a name suitable for use
1898 inside a SuperAlgorithm.
1900 name =
"{0}_{1}".
format(self.
name, kwargs.pop(
"name", typ.getType()))
1901 return typ(name, **kwargs)
1904 raise NotImplementedError()
1911 self.
graph.visitNode(visitor)
1914 super(SuperAlgorithm, self).
__setattr__(name, value)
1915 if name
in (
"_name",
"graph"):
1919 class PropSetter(object):
1920 def enter(self, node):
1922 setattr(node, name, value)
1923 except (ValueError, AttributeError):
1927 def leave(self, node):
1930 self._visitSubNodes(PropSetter())
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
_visitSubNodes(self, visitor)
__init__(self, name=Configurable.DefaultName)
__init__(self, name=Configurable.DefaultName)
__init__(self, name=Configurable.DefaultName)
__setattr__(self, name, value)
getDefaultProperty(cls, name)
getPropertiesWithDescription(self)
isPropertySet(self, name)
copyChildAndSetParent(self, cfg, parent)
__iadd__(self, configs, descr=None)
getDefaultProperties(cls)
bool _configurationLocked
__str__(self, indent=0, headerLastIndentUnit=indentUnit)
dict configurableServices
clone(self, name=None, **kwargs)
_printFooter(indentStr, title)
_printHeader(indentStr, title)
__init__(self, name=DefaultName)
setProp(self, name, value)
addTool(self, tool, name=None)
__setattr__(self, name, value)
__new__(cls, *args, **kwargs)
setParent(self, parentName)
getValuedProperties(self)
list __queried_configurables__
__init__(self, name=Configurable.DefaultName, _enabled=True, **kwargs)
__apply_configuration__(self)
propagateProperty(self, name, others=None, force=True)
__addActiveUseOf(self, other)
getUsedInstance(self, name)
propagateProperties(self, names=None, others=None, force=True)
__addPassiveUseOf(self, other)
list __used_configurables__
_getUniqueName(self, prefix)
_newSeq(self, prefix="seq_", **kwargs)
__get__(self, obj, type=None)
__set__(self, obj, value)
__setattr__(self, name, value)
__init__(self, name=None, **kwargs)
_visitSubNodes(self, visitor)
__new__(cls, name=None, **kwargs)
_makeAlg(self, typ, **kwargs)
makeSequences(expression)
appendPostConfigAction(function)
removePostConfigAction(function)
applyConfigurableUsers_old()