16__all__ = [
"PropertyProxy",
"GaudiHandlePropertyProxy",
"GaudiHandleArrayPropertyProxy"]
21from GaudiKernel
import ConfigurableDb
25log = logging.getLogger(
"PropertyProxy")
29 """A string version of isinstance().
30 <derived> is either an object instance, or a type
31 <base> is a string containing the name of the base class (or <derived> class)"""
32 if not isinstance(derived, type):
33 derived = type(derived)
34 if derived.__name__ == base:
36 for b
in derived.__bases__:
45 f
"received an instance of {type(value)}, but {tp} expected for property {name}"
52 if isinstance(value, str)
or derives_from(value,
"Configurable"):
55 elif isinstance(value, DataHandle):
60 raise ValueError(errmsg)
61 elif tp
in (list, tuple, dict, set):
65 elif tp
is set
and isinstance(value, list):
69 raise ValueError(errmsg)
76 except (TypeError, ValueError):
77 raise ValueError(errmsg)
83 allConfigurables[c.name()] = c
84 for cc
in c.getAllChildren():
90 def __init__(self, descr, docString=None, default=None):
96 if "[[deprecated]]" in docString:
98 if default
is not None:
107 default = property(getDefault, setDefault)
110 return (obj.getJobOptName()
or obj.getName()) +
"." + self.
descr.__name__
115 except AttributeError:
118 if isinstance(self.
__default, (list, dict, set)):
130 "Property %s is deprecated: %s",
136 proptype, allowcompat =
None,
False
137 if hasattr(self,
"default"):
139 if self.
descr.__name__ ==
"OutputLevel":
142 proptype = type(self.
history[obj][0])
150 and not isinstance(
None, proptype)
162 tpo = type(oldvec[0])
165 except AttributeError:
168 except ValueError
as e:
171 f
"inconsistent value types for {obj.getName()}.{self.descr.__name__} ({e})"
178 if not obj._isInSetDefaults()
or obj
not in self.
history:
180 if hasattr(self,
"default")
and self.
default is None:
181 obj.__iadd__(value, self.
descr)
184 self.
history.setdefault(obj, []).append(value)
193 """A class with some utilities for GaudiHandles and GaudiHandleArrays"""
195 def __init__(self, descr, docString, default, handleType, allowedType):
196 """<descr>: the real property in the object instance (from __slots__)
197 <docString>: the documentation string of this property
198 <default>: default value from C++ (via python generated by genconf)
199 <handleType>: real python handle type (e.g. PublicToolHandle, PrivateToolHandle, ...)
200 <allowedType>: allowed instance type for default
203 if not isinstance(default, allowedType):
205 f
"{descr.__name__}: {self.__class__.__name__} default: {default!r} is not a {allowedType.__name__}"
207 PropertyProxy.__init__(self, descr, docString, default)
214 except AttributeError:
217 default = obj.__class__.getDefaultProperty(self.
descr.__name__)
219 if default
is not None:
222 except AttributeError
as e:
224 raise RuntimeError(*e.args)
231 if not obj._isInSetDefaults()
or obj
not in self.
history:
236 self.
history.setdefault(obj, []).append(value)
239 """Check if <value> is a handle of the correct type"""
243 """Check if <value> is a configurable of the correct type"""
247 """Return the configurable instance corresponding to the toolhandle if possible.
248 Otherwise return None"""
251 typeAndNameTuple = typeAndName.split(
"/")
252 confType = typeAndNameTuple[0]
253 confClass = ConfigurableDb.getConfigurable(confType)
257 "%s: Configurable %s is not a %s",
264 confName = typeAndNameTuple[1]
268 return confClass(confName)
272 isString = isinstance(default, str)
273 if not isString
and self.
isConfig(default):
276 elif isString
or self.
isHandle(default):
279 typeAndName = default
282 typeAndName = default.typeAndName
289 if "/" in typeAndName:
290 typeAndName = typeAndName.replace(
"/", f
"/{obj.name()}.", 1)
292 typeAndName = f
"{typeAndName}/{obj.name()}.{typeAndName}"
299 except AttributeError
as e:
301 raise RuntimeError(*e.args)
304 f
"{self.fullPropertyName(obj)}: Default configurable for class {default.getType()} not found in ConfigurableDb.CfgDb"
309 f
"{self.fullPropertyName(obj)}: default value {default!r} is not of type {self._confTypeName} or {self._handleType.__name__}"
317 isString = isinstance(value, str)
328 if not value.isInToolSvc():
330 "You may need to add jobOptions lines something like:"
332 +
"from AthenaCommon.AppMgr import ToolSvc"
336 if value.getName() == value.getType():
337 suggestion += f
"{value.__class__.__name__}()"
340 f
"{value.__class__.__name__}({value.getName()!r})"
344 + f
": Public tool {value.getJobOptName()} is not yet in ToolSvc. {suggestion}"
348 elif value.hasParent(obj.getJobOptName()):
353 value = obj.copyChildAndSetParent(value, obj.getJobOptName())
360 f
"Property {self.fullPropertyName(obj)} value {value!r} is not a {self._confTypeName} nor a {self._handleType.__name__} nor a string"
368 GaudiHandlePropertyProxyBase.__init__(
369 self, descr, docString, default, type(default), GaudiHandle
375 """<descr>: the real property in the object instance (from __slots__)
376 <confTypeName>: string indicating the (base) class of allowed Configurables to be assigned.
377 <handleType>: real python handle type (e.g. PublicToolHandle, PrivateToolHandle, ...)
379 GaudiHandlePropertyProxyBase.__init__(
380 self, descr, docString, default, type(default).handleType, GaudiHandleArray
385 if not isinstance(value, list)
and not isinstance(value, self.
arrayType):
387 f
"{self.fullPropertyName(obj)}: Value {value!r} is not a list nor a {self.arrayType.__name__}"
394 cd = GaudiHandlePropertyProxyBase.convertDefaultToBeSet(self, obj, d)
396 newDefault.append(cd)
404 cv = GaudiHandlePropertyProxyBase.convertValueToBeSet(self, obj, v)
413 PropertyProxy.__init__(self, descr, docString, default)
418 except AttributeError:
421 default = obj.__class__.getDefaultProperty(self.
descr.__name__)
423 if default
is not None:
425 except AttributeError
as e:
427 raise RuntimeError(*e.args)
432 if not obj._isInSetDefaults()
or obj
not in self.
history:
437 self.
history.setdefault(obj, []).append(value)
443 mode = obj.__class__.getDefaultProperty(self.
descr.__name__).mode()
444 _type = obj.__class__.getDefaultProperty(self.
descr.__name__).type()
445 if isinstance(value, str):
447 elif isinstance(value, DataHandle):
448 return DataHandle(value.__str__(), mode, _type)
451 "received an instance of {}, but {} expected".
format(
452 type(value),
"str or DataHandle"
459 DataHandlePropertyProxy.__init__(self, descr, docString, default)
465 default = obj.__class__.getDefaultProperty(self.
descr.__name__)
466 mode = default.mode()
467 _type = default.type()
468 if isinstance(value, DataHandleVector):
470 if isinstance(value, (list, tuple)):
473 if isinstance(path, DataHandle):
475 if not isinstance(path, str):
477 f
"received an instance of {type(path)}, but str or DataHandle expected"
482 "received an instance of {}, but {} expected".
format(
483 type(value),
"list, tuple or DataHandleVector"
491 if isinstance(default, GaudiHandleArray):
494 if isinstance(default, GaudiHandle):
497 if isinstance(default, DataHandle):
500 if isinstance(default, DataHandleVector):
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
__get__(self, obj, type=None)
__set__(self, obj, value)
convertValueToBeSet(self, obj, value)
__init__(self, descr, docString, default)
convertValueToBeSet(self, obj, value)
__init__(self, descr, docString, default)
checkType(self, obj, value)
convertDefaultToBeSet(self, obj, default)
__init__(self, descr, docString, default)
convertValueToBeSet(self, obj, value)
__get__(self, obj, type=None)
convertDefaultToBeSet(self, obj, default)
convertValueToBeSet(self, obj, value)
__set__(self, obj, value)
getDefaultConfigurable(self, typeAndName, requester)
__init__(self, descr, docString, default, handleType, allowedType)
__init__(self, descr, docString, default)
__get__(self, obj, type=None)
__init__(self, descr, docString=None, default=None)
fullPropertyName(self, obj)
__set__(self, obj, value)
_isCompatible(tp, value, name)
_registerConfigurables(allConfigurables, c)
PropertyProxyFactory(descr, doc, default)
derives_from(derived, base)