00001
00002
00003
00004 import GaudiKernel.PropertyProxy as PropertyProxy
00005
00006
00007
00008 __version__ = '1.0.1'
00009 __author__ = 'Wim Lavrijsen (WLavrijsen@lbl.gov)'
00010
00011 __all__ = [ 'ConfigurableMeta' ]
00012
00013
00014 class ConfigurableMeta( type ):
00015 """The setting of Gaudi component properties needs to be deferred and
00016 history of who set what where needs to be collected. This is done
00017 by using PropertyProxy descriptors rather than the default ones."""
00018
00019 def __new__( self, name, bases, dct ):
00020
00021 if 'getType' in dct and not isinstance( dct[ 'getType' ], classmethod ):
00022 dct[ 'getType' ] = classmethod( dct[ 'getType' ] )
00023
00024 if 'setDefaults' in dct and not isinstance( dct[ 'setDefaults' ], classmethod ):
00025 dct[ 'setDefaults' ] = classmethod( dct[ 'setDefaults' ] )
00026
00027
00028
00029
00030 newclass = type.__new__( self, name, bases, dct )
00031
00032
00033 newclass.configurables = {}
00034
00035
00036 properties = {}
00037 slots = dct.get( '__slots__' )
00038 if slots:
00039 props = [ x for x in slots if x[0] != '_' ]
00040 propDict = dct.get('_propertyDocDct')
00041 for prop in props:
00042 docString = propDict and propDict.get(prop)
00043 if type(slots) == dict:
00044 default = slots[prop]
00045 else:
00046 default = None
00047 proxy = PropertyProxy.PropertyProxyFactory( getattr( newclass, prop ), docString, default )
00048
00049 properties[ prop ] = proxy
00050 setattr( newclass, prop, proxy )
00051
00052
00053 for base in bases:
00054 try:
00055 bprops = base._properties.copy()
00056 bprops.update( properties )
00057 properties = bprops
00058 except AttributeError:
00059 pass
00060
00061 newclass._properties = properties
00062
00063 return newclass
00064
00065 def __call__( cls, *args, **kwargs ):
00066 """To Gaudi, any object with the same type/name is the same object. Hence,
00067 this is mimicked in the configuration: instantiating a new Configurable
00068 of a type with the same name will return the same instance."""
00069
00070
00071
00072 cfg = cls.__new__( cls, *args, **kwargs )
00073
00074
00075 if not hasattr(cfg, '_initok') or not cfg._initok:
00076 cls.__init__( cfg, *args, **kwargs )
00077
00078 return cfg