ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Control
AthenaCommon
python
ConfigurableMeta.py
Go to the documentation of this file.
1
# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2
3
# File: AthenaCommon/python/ConfigurableMeta.py
4
# Author: Wim Lavrijsen (WLavrijsen@lbl.gov)
5
6
import
weakref
7
from
AthenaCommon
import
Logging, PropertyProxy
8
9
10
11
__version__ =
'1.2.0'
12
__author__ =
'Wim Lavrijsen (WLavrijsen@lbl.gov)'
13
14
__all__ = [
'ConfigurableMeta'
]
15
16
17
18
log = Logging.logging.getLogger(
'ConfigurableMeta'
)
19
20
21
22
class
ConfigurableMeta
(
type
):
23
"""The setting of Gaudi component properties needs to be deferred and
24
history of who set what where needs to be collected. This is done
25
by using PropertyProxy descriptors rather than the default ones."""
26
27
def
__new__
( self, name, bases, dct ):
28
# enforce use of classmethod for getType() and setDefaults()
29
if
'getType'
in
dct
and
not
isinstance( dct[
'getType'
], classmethod ):
30
dct[
'getType'
] = classmethod( dct[
'getType'
] )
31
32
if
'setDefaults'
in
dct
and
not
isinstance( dct[
'setDefaults'
], classmethod ):
33
dct[
'setDefaults'
] = classmethod( dct[
'setDefaults'
] )
34
35
# collect what are properties (basically, any public name; C++ variables
36
# shouldn't start with an '_' because of portability constraints, hence
37
# it is safe to assume that any such vars are python private ones)
38
newclass = type.__new__( self, name, bases, dct )
39
40
if
'AthenaCommon'
not
in
newclass.__module__:
41
# check for required methods and the right number of arguments
42
# meths = { 'getServices' : 1, # retrieve list of services to configure
43
meths = {
'getDlls'
: 1,
# provide list of Dlls to load
44
'getGaudiType'
: 1,
# return string describing component class
45
'getHandle'
: 1,
# provide access to C++ side component instance
46
'getType'
: 1 }
# return the type of the actual C++ component
47
48
for
meth, nArgs
in
meths.items():
49
try
:
50
f = getattr( newclass, meth )
51
except
AttributeError:
52
raise
NotImplementedError(
"%s is missing in class %s"
% (meth,str(newclass)))
53
54
# in addition, verify the number of arguments w/o defaults
55
nargcount = f.__code__.co_argcount
56
dflts = f.__defaults__
57
ndefaults = dflts
and
len(dflts)
or
0
58
if
not
nargcount - ndefaults <= nArgs <= nargcount:
59
raise
TypeError(
"%s.%s requires exactly %d arguments"
% (newclass,meth,nArgs))
60
61
# cache references of instances by name for duplicate removal
62
newclass.configurables = weakref.WeakValueDictionary()
63
64
# loop over slots, which are all assumed to be properties, create proxies, defaults
65
properties = {}
66
slots = dct.get(
'__slots__'
)
67
if
slots:
68
props = [ x
for
x
in
slots
if
x[0] !=
'_'
]
69
propDict = dct.get(
'_propertyDocDct'
)
70
for
prop
in
props:
71
docString = propDict
and
propDict.get(prop)
72
if
type
(slots)
is
dict:
73
default = slots[prop]
74
else
:
75
default =
None
76
proxy = PropertyProxy.PropertyProxyFactory(
77
getattr( newclass, prop ), docString, default )
78
79
properties[ prop ] = proxy
80
setattr( newclass, prop, proxy )
81
82
# complete set of properties includes those from base classes
83
for
base
in
bases:
84
try
:
85
bprops = base._properties.copy()
86
bprops.update( properties )
87
properties = bprops
88
except
AttributeError:
89
pass
90
91
newclass._properties = properties
92
93
return
newclass
94
95
def
__call__
( cls, *args, **kwargs ):
96
"""To Gaudi, any object with the same type/name is the same object. Hence,
97
this is mimicked in the configuration: instantiating a new Configurable
98
of a type with the same name will return the same instance."""
99
100
# Get the instance: `singleton' logic needs to be in __new__, not here,
101
# for compatibililty with pickling.)
102
cfg = cls.__new__( cls, *args, **kwargs )
103
104
# Initialize the object, if not done already.
105
if
cfg
and
(
not
hasattr(cfg,
'_fInitOk'
)
or
not
cfg._fInitOk ):
106
cls.__init__( cfg, *args, **kwargs )
107
108
return
cfg
ElementLink_p1
Definition
ElementLink_p1.h:23
python.ConfigurableMeta.ConfigurableMeta
this metaclass installs PropertyProxy descriptors for Gaudi properties
Definition
ConfigurableMeta.py:22
python.ConfigurableMeta.ConfigurableMeta.__new__
__new__(self, name, bases, dct)
Definition
ConfigurableMeta.py:27
python.ConfigurableMeta.ConfigurableMeta.__call__
__call__(cls, *args, **kwargs)
Definition
ConfigurableMeta.py:95
Generated on
for ATLAS Offline Software by
1.17.0