122 def conf2toConfigurable( comp, indent="", parent="", servicesOfThisCA=[], suppressDupes=False, propType="" ):
124 Method converts from Conf2 ( comp argument ) to old Configurable
125 If the Configurable of the same name exists, the properties merging process is invoked
127 _log = logging.getLogger(
"conf2toConfigurable" )
130 _log.debug(
"%sComponent is already OLD Configurable object %s, no conversion",
131 indent, comp.getName() )
134 if isinstance(comp, str):
135 if comp
and 'ServiceHandle' not in propType:
136 _log.warning(
"%sComponent '%s' in '%s' is of type string, no conversion, "
137 "some properties possibly not set?", indent, comp, parent)
140 if comp.getType() ==
'AthSequencer':
141 _log.debug(
"%sComponent is a sequence %s, attempt to merge",
142 indent, comp.getName())
147 _log.debug(
"%sConverting from GaudiConfig2 object %s type %s, parent %s",
148 indent, comp.getName(), comp.__class__.__name__ , parent)
150 def _alreadyConfigured( comp, parent ):
151 instanceName = comp.getName()
152 for conf
in Configurable.allConfigurables.values():
155 conf_name=conf.name()
160 if conf_name==instanceName:
161 if conf.getParent() == parent:
162 _log.debug(
"%s Matched component: '%s' with parent %s with same from allConfigurables match.",
163 indent, instanceName, parent
if parent
else "[not set]" )
166 _log.debug(
"%sComponent: '%s' had parent %s whilst this allConfigurables match had parent %s.",
167 indent, instanceName, parent
if parent
else "[not set]", conf.getParent() )
170 def _createConf2Object( name ):
171 typename, instanceName = name.split(
"/")
if "/" in name
else (name,name)
172 return CompFactory.getComp( typename.replace(
"__",
"::") )( instanceName )
174 def _configurableToConf2( comp, indent="" ):
175 _log.debug(
"%sConverting Conf2 to Configurable class %s, type %s", indent, comp.getFullName(),
type(comp) )
176 conf2Object = _createConf2Object( comp.getFullName() )
177 _getProperties( comp, conf2Object,
_indent( indent ) )
180 def _getProperties( src, dest, indent="" ):
181 """Read properties on src and set them on dest (GaudiConfig2) configurable"""
182 for prop, value
in src.getProperties().
items():
183 _log.debug(
"%sDealing with class %s property %s value type %s",
184 indent, src.getFullJobOptName(), prop,
type(value) )
185 if "ServiceHandle" in str(
type( value ) ):
186 instance = _alreadyConfigured(value, src.getName())
188 setattr( dest, prop, _configurableToConf2(instance,
_indent(indent)) )
190 if isinstance(value, _semanticsHelpers):
192 setattr( dest, prop, value )
194 def _findConfigurableClass( name ):
195 """Find old-style Configurable class for name"""
197 name = name.replace(
"::",
"__")
200 name=name.replace(
"<",
"_")
201 name=name.replace(
">",
"_")
202 name=name.replace(
", ",
"_")
204 classObj = getattr( CfgMgr, name )
207 raise ConfigurationError(f
"CAtoGlobalWrapper could not find the component of type {name}")
211 def _areSettingsSame( conf1, conf2, indent="",servicesOfThisCA=[] ):
212 """Are the properties the same between old-style conf1 and new-style conf2 instance?"""
213 from AthenaCommon.AppMgr
import ToolSvc
215 _log.debug(
"%sChecking if settings are the same %s (%s) old(new)",
216 indent, conf1.getFullName(), conf2.getFullJobOptName() )
218 if conf1.getType() != conf2.__cpp_type__:
219 raise ConfigurationError(
"Old/new ({} | {}) cpp types are not the same for ({} | {}) !".
format(
220 conf1.getType(), conf2.__cpp_type__,
221 conf1.getFullName(), conf2.getFullJobOptName() ) )
223 alreadySetProperties = conf1.getValuedProperties().
copy()
225 _log.debug(
"%sExisting properties: %s", indent, alreadySetProperties )
226 _log.debug(
"%sNew properties: %s", indent, conf2._properties )
228 for pname, pvalue
in conf2._properties.items():
231 _log.warning(
"%sNew configuration object %s property %s has legacy configuration "
232 "components assigned to it %s. Skipping comparison, no guarantees "
233 "about configuration consistency.",
234 indent, conf2.getName(), pname, pvalue.getName() )
237 propType = conf2._descriptors[pname].cpp_type
238 _log.debug(
"%sComparing type: %s for: %s in: %s", indent, propType, pname, conf1.getFullJobOptName() )
240 if "PrivateToolHandleArray" in propType:
241 toolDict = {_.getName(): _
for _
in alreadySetProperties[pname]}
242 _log.debug(
'Private tool properties? %s', toolDict)
243 newCdict = {_.getName() : _
for _
in pvalue}
244 oldCset =
set(toolDict); newCset =
set(newCdict)
245 _log.debug(
'Private tool property names? %s %s', oldCset, newCset)
246 if (
not (oldCset == newCset) ):
249 _log.debug(
'%s PrivateToolHandleArray %s of %s does not have the same named components',indent, pname, conf1.getFullJobOptName() )
250 _log.debug(
'%s Old (conf1) %s for %s',indent,
sorted(oldCset), conf1.getFullJobOptName())
251 _log.debug(
'%s New (conf2) %s for %s',indent,
sorted(newCset), conf2.getFullJobOptName())
252 _log.debug(
'%s Will try to merge them, but this might go wrong!',indent)
253 for oldC
in oldCset & newCset:
254 _areSettingsSame( toolDict[oldC], newCdict[oldC],
_indent(indent),servicesOfThisCA)
257 for newC
in sorted(newCset-oldCset):
258 className = newCdict[newC].getFullJobOptName().
split(
"/" )[0]
259 _log.debug(
'%s%s not in old config. Will try to create conf1 instance using '
260 'this className: %s, and merge.',indent, newC, className)
261 configurableClass = _findConfigurableClass( className )
264 tmpName = newC + className +
str(len(indent))
265 instance = configurableClass( tmpName )
268 instance._name = newCdict[newC].name
269 if hasattr(instance,
'_jobOptName'):
270 instance._jobOptName = instance._name
272 instance.allConfigurables[instance._name] = instance.allConfigurables.pop(tmpName)
273 instance.configurables[instance._name] = instance.configurables.pop(tmpName)
276 _log.debug(
'%s will now add %s to array.',indent, instance)
279 alreadySetProperties[pname].
append(conf1.getChildren()[-1])
281 elif "PublicToolHandleArray" in propType:
282 toolSet = {_.getName()
for _
in alreadySetProperties[pname]}
283 _log.debug(
'Public tool handle array properties? %s %s', toolSet, pvalue)
286 if isinstance(newC, str):
287 pubtoolclass, pubtoolname = newC.split(
'/')
288 if pubtoolname
not in toolSet:
289 klass = _findConfigurableClass( pubtoolclass )
290 instance =
klass(pubtoolname)
292 alreadySetProperties[pname].
append(instance)
294 _log.warning(
'Not handling actual Configurable2s for public tool merging yet')
297 elif (
"PrivateToolHandle" in propType
or
298 "GaudiConfig2.Configurables" in propType
or
299 "ServiceHandle" in propType):
300 existingVal = getattr(conf1, pname)
301 if isinstance( pvalue, str ):
303 if "ServiceHandle" in propType
and pvalue
in servicesOfThisCA:
304 _log.debug(
"%sThe service %s is part of the CA. Consistency checks will be performed when the service is merged")
307 _log.debug(
"%sThe %s '%s' of GaudiConfig2 component %s.%s is a string, "
308 "skipping deeper checks",
309 indent, propType, pvalue, conf2.name, pname)
311 _log.debug(
"%sThe property value for %s of %s is None. Skipping.", indent, pname, conf2.name )
313 elif str(existingVal) ==
"":
314 className = pvalue.getFullJobOptName().
split(
"/" )[0]
315 pvalueCompName = pvalue.getFullJobOptName().
split(
"/" )[1]
316 _log.debug(
"%sThe existing value for %s of %s is an empty handle. "
317 "Will try to create conf1 instance using this className: %s, and merge.",
318 indent, pname, conf2.name, className )
319 configurableClass = _findConfigurableClass( className )
322 tmpName = pvalueCompName + className +
str(len(indent))
323 instance = configurableClass( tmpName )
325 instance._name = pvalueCompName
326 if hasattr(instance,
'_jobOptName'):
327 instance._jobOptName = instance._name
329 instance.allConfigurables[instance._name] = instance.allConfigurables.pop(tmpName)
330 instance.configurables[instance._name] = instance.configurables.pop(tmpName)
332 setattr(conf1, pname, instance)
333 existingVal = getattr(conf1, pname)
334 _areSettingsSame( existingVal, pvalue, indent,servicesOfThisCA)
336 _log.debug(
"%sSome kind of handle and, object type %s existing %s",
337 indent,
type(pvalue),
type(existingVal) )
338 _areSettingsSame( existingVal, pvalue, indent,servicesOfThisCA)
340 if isinstance(pvalue, _semanticsHelpers):
343 if pname
not in alreadySetProperties:
344 _log.debug(
"%sAdding property: %s for %s", indent, pname, conf2.getName() )
346 setattr(conf1, pname, pvalue)
347 except AttributeError:
348 _log.info(
"%sCould not set attribute. Type of conf1 %s.",indent,
type(conf1) )
351 elif alreadySetProperties[pname] != pvalue:
358 if (isinstance(pvalue, str)
and isinstance(alreadySetProperties[pname], str)):
360 and pvalue.split(
'/')[-1] == alreadySetProperties[pname]):
363 _log.warning(
"%sProperties here are strings and not exactly the same. "
364 "ASSUMING they match types but we cannot check. %s for %s",
365 indent, pname, conf2.getName() )
367 if (
'+' in alreadySetProperties[pname].toStringProperty()
and
368 alreadySetProperties[pname].toStringProperty().
split(
'+')[-1] == pvalue):
371 except AttributeError :
377 _log.debug(
"%sMerging property: %s for new config: %s", indent, pname, conf2.getName() )
379 clone = conf2.getInstance(
"Clone")
380 setattr(clone, pname, alreadySetProperties[pname])
383 getattr(conf2, pname), getattr(clone, pname)) )
384 except (TypeError, ValueError):
385 err_message = f
"Failed merging new config value ({getattr(conf2, pname)}) and old config value ({getattr(clone, pname)}) for the ({pname}) property of {conf1.getFullJobOptName() } ({conf2.getFullJobOptName()}) old (new)."
386 _log.fatal( err_message )
387 raise ConfigurationError(err_message)
389 _log.debug(
"existingConfigurable.name: %s, pname: %s, updatedPropValue: %s",
390 conf1.name(), pname, updatedPropValue )
392 setattr(conf1, pname, updatedPropValue)
394 _log.debug(
"%sInvoked GaudiConf2 semantics to merge the %s and the %s to %s "
395 "for property %s of %s",
396 indent, alreadySetProperties[pname], pvalue, pname,
397 updatedPropValue, existingConfigurable.getFullName())
399 _log.debug(
"%sConf2 Full name: %s ", indent, comp.getFullJobOptName() )
400 existingConfigurable = _alreadyConfigured( comp, parent )
402 if existingConfigurable:
403 _log.debug(
"%sPre-existing configurable %s was found, checking if has the same properties",
404 indent, existingConfigurable.getFullJobOptName() )
405 _areSettingsSame( existingConfigurable, comp, indent, servicesOfThisCA )
406 _log.debug(
"%sPre-existing configurable %s was found to have the same properties",
408 instance = existingConfigurable
if not suppressDupes
else None
411 _log.debug(
"%sExisting Conf1 not found. Creating component configurable %s",
412 indent, comp.getFullJobOptName() )
413 configurableClass = _findConfigurableClass( comp.getFullJobOptName().
split(
"/" )[0] )
414 instance = configurableClass( comp.name )