Gaudi Framework, version v21r8

Home   Generated: 17 Mar 2010

ConfigurableMeta.py

Go to the documentation of this file.
00001 # File: AthenaCommon/python/ConfigurableMeta.py
00002 # Author: Wim Lavrijsen (WLavrijsen@lbl.gov)
00003 
00004 import GaudiKernel.PropertyProxy as PropertyProxy
00005 
00006 
00007 ### data
00008 __version__ = '1.0.1'
00009 __author__  = 'Wim Lavrijsen (WLavrijsen@lbl.gov)'
00010 
00011 __all__ = [ 'ConfigurableMeta' ]
00012 
00013 ### this metaclass installs PropertyProxy descriptors for Gaudi properties
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      # enfore use of classmethod for getType() and setDefaults()
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      # collect what are properties (basically, any public name; C++ variables
00028      # shouldn't start with an '_' because of portability constraints, hence
00029      # it is safe to assume that any such vars are python private ones)
00030         newclass = type.__new__( self, name, bases, dct )
00031 
00032      # cache references of instances by name for duplicate removal
00033         newclass.configurables = {}
00034 
00035      # loop over slots, which are all assumed to be properties, create proxies, defaults
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      # complete set of properties includes those from base classes
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      # Get the instance: `singleton' logic needs to be in __new__, not here,
00071      # for compatibililty with pickling.)
00072         cfg = cls.__new__( cls, *args, **kwargs )
00073 
00074      # Initialize the object, if not done already.
00075         if not hasattr(cfg, '_initok') or not cfg._initok:
00076             cls.__init__( cfg, *args, **kwargs )
00077 
00078         return cfg

Generated at Wed Mar 17 18:06:32 2010 for Gaudi Framework, version v21r8 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004