7import os, weakref, copy
8from GaudiKernel.GaudiHandles
import GaudiHandle, GaudiHandleArray
9from GaudiKernel.DataHandle
import DataHandle
12from AthenaCommon
import ConfigurableDb
16__author__ =
'Wim Lavrijsen (WLavrijsen@lbl.gov), Martin Woudstra (Martin.Woudstra@cern.ch)'
18__all__ = [
'PropertyProxy',
19 'GaudiHandlePropertyProxy',
20 'GaudiHandleArrayPropertyProxy' ]
23from AthenaCommon.Logging
import logging
24log = logging.getLogger(
'PropertyProxy' )
28 """A string version of isinstance().
29 <derived> is either an object instance, or a type
30 <base> is a string containing the name of the base class (or <derived> class)"""
31 if not isinstance( derived, type ):
32 derived =
type(derived)
34 if derived.__name__ == base:
37 for b
in derived.__bases__:
51 if ( tp == str
or type(value)
is str )
and not isinstance( value, tp ):
53 raise ValueError(
"received an instance of %s, but %s expected, context: %s" % (
type(value),tp, context) )
54 elif ( tp == int )
and type(value)
is float:
56 raise ValueError(
"received an instance of %s, but %s expected, context: %s" % (
type(value),tp, context) )
61 except ValueError
as verr:
62 if isinstance( value, tp ):
67 raise ValueError(
"received non-convertible type %s, but builtin type expected, reason: %s context: %s" % (
type(value), str(verr), context) )
70 raise ValueError(
"received an instance of %s, but %s expected, reason: %s, context: %s" % (
type(value),tp, str(verr), context) )
71 except TypeError
as terr:
72 raise TypeError(
"received an instance of %s, but %s expected, reason: %s, context: %s" % (
type(value),tp, str(terr), context) )
77 def __init__( self, descr, docString=None, default=None ):
78 self.
history = weakref.WeakKeyDictionary()
82 if default
is not None:
91 default = property( getDefault, setDefault )
94 return (obj.getJobOptName()
or obj.getName()) +
'.' + self.
descr.__name__
100 except AttributeError:
116 if builtins.type( value )
is dict:
117 from ctypes
import pythonapi, py_object
118 from _ctypes
import PyObj_FromPtr
119 PyDictProxy_New = pythonapi.PyDictProxy_New
120 PyDictProxy_New.argtypes = (py_object,)
121 PyDictProxy_New.rettype = py_object
122 value = PyObj_FromPtr( PyDictProxy_New( value ) )
123 elif builtins.type( value )
is list:
124 value = tuple( value )
127 value = copy.copy( value )
135 'can not change property "%s" of locked configurable "%s"' %
136 (self.
descr.__name__, obj.getJobOptName()) )
140 if hasattr( self,
'default' ):
146 if proptype
and not isinstance(proptype,
type(
None)):
151 if proptype == tuple
or proptype == list:
155 tpo =
type(oldvec[0])
158 except AttributeError:
164 if not obj._isInSetDefaults()
or obj
not in self.
history:
166 if hasattr( self,
'default' )
and self.
default is None:
167 obj.__iadd__( value, self.
descr )
170 self.
history.setdefault( obj, [] ).append( value )
180 """A class with some utilities for GaudiHandles and GaudiHandleArrays"""
182 def __init__(self, descr, docString, default, handleType, allowedType ):
183 """<descr>: the real property in the object instance (from __slots__)
184 <docString>: the documentation string of this property
185 <default>: default value from C++ (via python generated by genconf)
186 <handleType>: real python handle type (e.g. PublicToolHandle, PrivateToolHandle, ...)
187 <allowedType>: allowed instance type for default
190 if not isinstance(default,allowedType):
191 raise TypeError(
"%s: %s default: %r is not a %s" % \
192 ( descr.__name__, self.__class__.__name__, default, allowedType.__name__ ) )
193 PropertyProxy.__init__( self, descr, docString, default )
202 except AttributeError:
205 default = obj.__class__.getDefaultProperty( self.
descr.__name__ )
207 if obj.isPrinting():
return default
214 default = copy.deepcopy(default)
220 elif isinstance(default,GaudiHandleArray):
224 default = copy.deepcopy(default)
234 except AttributeError
as e:
236 traceback.print_exc()
238 raise RuntimeError(
"AttributeError(%s)" % e.args)
247 'can not change property "%s" of locked configurable "%s"' %
248 (self.
descr.__name__, obj.getJobOptName()) )
252 if not obj._isInSetDefaults()
or obj
not in self.
history:
257 self.
history.setdefault( obj, [] ).append( value )
261 """Check if <value> is a handle of the correct type"""
266 """Check if <value> is a configurable of the correct type"""
271 """Return the configurable instance corresponding to the toolhandle if possible.
272 Otherwise return None"""
274 typeAndNameTuple = typeAndName.split(
'/')
275 confType = typeAndNameTuple[0]
276 confClass = ConfigurableDb.getConfigurable(confType)
279 log.error(
"%s: Configurable %s is not a %s",
283 confName = typeAndNameTuple[1]
287 return confClass(confName)
292 isString =
type(default)
is str
293 if not isString
and self.
isConfig(default):
296 elif isString
or self.
isHandle(default):
299 typeAndName = default
302 typeAndName = default.typeAndName
308 except AttributeError
as e:
310 raise RuntimeError(*e.args)
312 raise RuntimeError(
"%s: Default configurable for class %s not found in ConfigurableDb.CfgDb" % \
316 raise TypeError(
"%s: default value %r is not of type %s or %s" % \
322 if value
is None: value =
''
323 isString =
type(value)
is str
334 if not value.isInToolSvc():
335 suggestion =
'You may need to add jobOptions lines something like:' + os.linesep + \
336 'from AthenaCommon.AppMgr import ToolSvc' + os.linesep + \
338 if value.getName() == value.getType():
339 suggestion +=
'%s()' % value.__class__.__name__
341 suggestion +=
'%s(%r)' % (value.__class__.__name__,value.getName())
343 ': Public tool %s is not yet in ToolSvc. %s' %
344 (value.getJobOptName(),suggestion) )
347 elif value.hasParent( obj.getJobOptName() ):
352 return obj.copyChildAndSetParent( value, obj.getJobOptName() )
354 raise TypeError(
"Property %s value %r is not a %s nor a %s nor a string" % \
362 GaudiHandlePropertyProxyBase.__init__( self, descr, docString, default,
type(default), GaudiHandle )
367 """<descr>: the real property in the object instance (from __slots__)
368 <confTypeName>: string indicating the (base) class of allowed Configurables to be assigned.
369 <handleType>: real python handle type (e.g. PublicToolHandle, PrivateToolHandle, ...)
371 GaudiHandlePropertyProxyBase.__init__( self, descr, docString, default,
type(default).handleType, GaudiHandleArray )
376 if not isinstance( value, list )
and not isinstance( value, self.
arrayType ):
377 raise TypeError(
"%s: Value %r is not a list nor a %s" % \
385 cd = GaudiHandlePropertyProxyBase.convertDefaultToBeSet( self, obj, d )
386 if cd: newDefault.append( cd )
395 cv = GaudiHandlePropertyProxyBase.convertValueToBeSet( self, obj, v )
396 if cv: newValue.append( cv )
403 PropertyProxy.__init__(self, descr, docString, default)
408 except AttributeError:
411 default = obj.__class__.getDefaultProperty(self.
descr.__name__)
415 except AttributeError
as e:
417 raise RuntimeError(*e.args)
422 if not obj._isInSetDefaults()
or obj
not in self.
history:
427 self.
history.setdefault(obj, []).append(value)
433 mode = obj.__class__.getDefaultProperty(self.
descr.__name__).mode()
434 _type = obj.__class__.getDefaultProperty(self.
descr.__name__).
type()
435 if type(value)
is str:
437 elif isinstance(value, DataHandle):
438 return DataHandle(value.__str__(), mode, _type)
440 raise ValueError(
"received an instance of %s, but %s expected" %
441 (
type(value),
'str or DataHandle'))
446 if isinstance(default,GaudiHandleArray):
449 if isinstance(default,GaudiHandle):
452 if isinstance(default,DataHandle):
an iterator over instances of a given type in StoreGateSvc.
convertValueToBeSet(self, obj, value)
__init__(self, descr, docString, default)
__set__(self, obj, value)
__get__(self, obj, type=None)
__init__(self, descr, docString, default)
convertValueToBeSet(self, obj, value)
checkType(self, obj, value)
convertDefaultToBeSet(self, obj, default)
getDefaultConfigurable(self, typeAndName, requester)
__set__(self, obj, value)
convertValueToBeSet(self, obj, value)
__get__(self, obj, type=None)
convertDefaultToBeSet(self, obj, default)
__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)
PropertyProxyFactory(descr, doc, default)
derives_from(derived, base)
_isCompatible(tp, value, context="")