9 from AthenaConfiguration.ComponentAccumulator
import isComponentAccumulatorCfg
11 ConfigurableAlgorithm,
19 """@c PyComponents is a placeholder where all factories for the python
20 components will be collected and stored for easy look-up and call from
22 The @a PyComponents.instances dictionary will store the instance
24 PyComponents.instances[ 'alg1' ] = <PyAthena::Alg/alg1 instance>
25 All this boilerplate code will of course be done automatically for the user
26 as soon as she uses the (python) @PyConfigurable classes.
33 v = pycomp.properties()[propname]
34 if v == pycomp.propertyNoValue:
35 from AthenaCommon.AppMgr
import ServiceMgr
as svcMgr
36 if propname ==
'OutputLevel' and hasattr (svcMgr,
'MessageSvc'):
38 v = getattr(svcMgr.MessageSvc, propname)
40 v = pycomp.getDefaultProperty(propname)
48 self.__dict__[
'__cpp_type__'] = self.getType()
49 for n,v
in kw.items():
57 import AthenaCommon.Logging
as _L
58 return _L.logging.getLogger( self.getName() )
65 state.update(self.__dict__)
69 self.__dict__.update(state)
73 if isinstance(self, LegacyConfigurable):
74 from AthenaCommon.AppMgr
import ServiceMgr
as svcMgr
75 if not hasattr( svcMgr,
'PyComponentMgr' ):
76 from AthenaPython.AthenaPythonCompsConf
import PyAthena__PyComponentMgr
77 svcMgr += PyAthena__PyComponentMgr(
'PyComponentMgr')
84 o = PyComponents.instances.get(self.getName(),
None)
85 if not (o
is None)
and not (o
is self):
86 err =
"A python component [%r] has already been "\
87 "registered with the PyComponents registry !" % o
88 raise RuntimeError(err)
89 PyComponents.instances[self.getName()] = self
92 """Basic merge for Python components.
93 Checks that all attributes/properties are identical.
99 raise TypeError(f
"cannot merge instance of {type(other).__name__} into "
100 f
"an instance of { type(self).__name__}")
102 if self.name != other.name:
103 raise ValueError(f
"cannot merge configurables with different names ({self.name} and {other.name})")
105 for prop
in other.__dict__:
106 if (hasattr(self, prop)
and getattr(self, prop) == getattr(other, prop)):
109 raise ValueError(f
"conflicting settings for property {prop} of {self.name}: "
110 f
"{getattr(self,prop)} vs {getattr(other,prop)}")
121 _alg_base = _svc_base = _tool_base = _aud_base = GaudiConfig2.Configurable
123 _alg_base = ConfigurableAlgorithm
124 _svc_base = ConfigurableService
125 _tool_base = ConfigurableAlgTool
126 _aud_base = ConfigurableAuditor
132 if isinstance(self, LegacyConfigurable):
133 _alg_base.__init__(self, name)
135 _alg_base.__init__(self, name, **kw)
136 CfgPyComponent.__init__(self, name, **kw)
139 def getType(self):
return 'PyAthena::Alg'
143 from AthenaPython
import PyAthena
144 setattr(PyAthena.algs, self.getName(), self)
147 CfgPyComponent.setup(self)
148 if isinstance(self, LegacyConfigurable):
149 ConfigurableAlgorithm.setup(self)
155 if isinstance(self, LegacyConfigurable):
156 _svc_base.__init__(self, name)
158 _svc_base.__init__(self, name, **kw)
159 CfgPyComponent.__init__(self, name, **kw)
162 def getType(self):
return 'PyAthena::Svc'
166 from AthenaPython
import PyAthena
167 setattr(PyAthena.services, self.getName(), self)
170 CfgPyComponent.setup(self)
171 if isinstance(self, LegacyConfigurable):
172 _svc_base.setup(self)
178 if isinstance(self, LegacyConfigurable):
179 _tool_base.__init__(self, name)
181 _tool_base.__init__(self, name, **kw)
182 CfgPyComponent.__init__(self, name, **kw)
185 def getType(self):
return 'PyAthena::Tool'
188 CfgPyComponent.setup(self)
189 if isinstance(self, LegacyConfigurable):
190 _tool_base.setup(self)
196 _aud_base.__init__(self, name)
197 CfgPyComponent.__init__(self, name, **kw)
200 def getType(self):
return 'PyAthena::Aud'
203 CfgPyComponent.setup(self)
204 if isinstance(self, LegacyConfigurable):
205 _aud_base.setup(self)
210 """a class to mimic the gaudi C++ {Tool,Svc}Handle classes: automatic call
211 to `initialize` when __getattr__ is called on the instance.
214 msg = parent.msg.verbose
216 parentName=parent.name()
218 parentName=parent.name
219 msg(
'installing py-comp-handle for [%s.%s]...',
220 parentName, attr_name)
221 self.__dict__.update({
224 '_attr': getattr(parent, attr_name),
225 '_init_called':
False,
227 msg(
'installing py-comp-handle for [%s.%s]... [done]',
228 parentName, attr_name)
232 if self.__dict__[
'_init_called']:
234 parent = self.__dict__[
'_parent']
237 self.__dict__[
'_init_called'] =
True
239 setattr(parent, self.__dict__[
'_name'], obj)
242 if n.startswith(
'_'):
244 obj = self.__dict__[
'_attr']
246 return getattr(obj, n)
249 if n.startswith(
'_'):
251 obj = self.__dict__[
'_attr']
253 return setattr(obj, n, v)
259 (CfgPyAlgorithm, CfgPyService, CfgPyAlgTool, CfgPyAud)
263 """loop over all pycomponents, inspect their attributes and install
264 a handle in place of (sub) pycomponents to trigger the auto-initialize
265 behaviour of (C++) XyzHandles.
267 import PyUtils.Logging
as L
268 msg = L.logging.getLogger(
'PyComponentMgr').verbose
269 comps = PyComponents.instances.items()
271 msg(
'installing fancy getattrs... (%i)', ncomps)
273 msg(
'handling [%s]...', k)
274 for attr_name, attr
in comp.__dict__.items():
276 msg(
' ==> [%s]...', attr_name)
277 setattr(comp, attr_name,
279 msg(
' ==> [%s]... [done]', attr_name)
280 msg(
'installing fancy getattrs... (%i) [done]',ncomps)