DUNE-DAQ
DUNE Trigger and Data Acquisition software
Toggle main menu visibility
Loading...
Searching...
No Matches
dunedaq
sourcecode
conffwk
python
conffwk
ConfigObject.py
Go to the documentation of this file.
1
#!/usr/bin/env python
2
# vim: set fileencoding=utf-8 :
3
# DUNE DAQ modification notice:
4
# This file has been modified from the original ATLAS config source for the DUNE DAQ project.
5
# Fork baseline commit: 67a24e731 (2022-10-27).
6
# Renamed since fork: yes (from python/config/ConfigObject.py to python/conffwk/ConfigObject.py).
7
8
# Created by Andre Anjos <andre.dos.anjos@cern.ch>
9
# Mon 22 Oct 2007 04:12:01 PM CEST
10
11
"""A pythonic wrapper over the OKS ConfigObject wrapper.
12
13
Necessary to give the user a more pythonic experience than dealing with
14
std::vector objects and memory management.
15
"""
16
#import libpyconffwk
17
import
logging
18
from
.
import
dalproperty
19
from
._daq_conffwk_py
import
_ConfigObject
20
from
.proxy
import
_DelegateMetaFunction
21
22
class
_ConfigObjectProxy
(object,
23
metaclass=_DelegateMetaFunction):
24
memberclass = _ConfigObject
25
26
27
class
ConfigObject
(
_ConfigObjectProxy
):
28
"""ConfigObjects are generic representations of objects in OKS."""
29
30
def
__init__
(self, raw_object, schema, configuration):
31
"""Initializes a ConfigObject in a certain Configuration database.
32
33
This method will initialize the ConfigObject and recursively any other
34
objects under it. If the number of recursions is too big, it may stop
35
python from going on. In this case, you may reset the limit with:
36
37
import sys
38
sys.setrecursionlimit(10000) # for example
39
40
raw_object -- This is the libpyconffwk.ConfigObject to initialize this
41
object from.
42
43
schema -- A pointer to the overall schema from the Configuration
44
database to which this object is associated.
45
46
configuration -- The database this object belongs too. This is needed
47
to bind the database lifetime to this object
48
49
Raises RuntimeError in case of problems.
50
"""
51
super(ConfigObject, self).
__init__
(raw_object)
52
53
self.
__schema__
= schema[self.class_name()]
54
self.
__overall_schema__
= schema
55
self.
__cache__
= {}
56
self.
__configuration__
= configuration
57
58
def
__getitem__
(self, name):
59
"""Returns the attribute or relation defined by 'name'.
60
61
If an attribute does not exist, instead of a wrapper exception,
62
you get an AttributeError.
63
64
Raises KeyError, if the 'name' is not a valid class item.
65
"""
66
if
name
in
self.
__schema__
[
'attribute'
]:
67
return
(self.
__schema__
[
'attribute'
][name]
68
[
'co_get_method'
](self, name))
69
70
elif
name
in
self.
__cache__
:
71
return
self.
__cache__
[name]
72
73
elif
name
in
self.
__schema__
[
'relation'
]:
74
try
:
75
data = self.
__schema__
[
76
'relation'
][name][
'co_get_method'
](self, name)
77
if
self.
__schema__
[
'relation'
][name][
'multivalue'
]:
78
self.
__cache__
[name] = \
79
[
ConfigObject
(k, self.
__overall_schema__
,
80
self.
__configuration__
)
81
for
k
in
data]
82
else
:
83
self.
__cache__
[name] =
None
84
if
data:
85
self.
__cache__
[name] = \
86
ConfigObject
(data, self.
__overall_schema__
,
87
self.
__configuration__
)
88
89
except
RuntimeError
as
e:
90
if
self.
__schema__
[
'relation'
][name][
'multivalue'
]:
91
self.
__cache__
[name] = []
92
else
:
93
self.
__cache__
[name] =
None
94
logging.warning(
'Problems retrieving relation "%s" of '
95
'object "%s". Resetting and ignoring. '
96
'OKS error: %s'
%
97
(name, self.full_name(), str(e)))
98
99
return
self.
__cache__
[name]
100
101
# shout if you get here
102
raise
KeyError(
'"%s" is not an attribute or relation of class "%s"'
%
103
(name, self.class_name()))
104
105
def
__eq__
(self, other):
106
"""True is the 2 objects have the same class and ID and conffwk database
107
"""
108
return
(self.class_name() == other.class_name())
and
\
109
(self.UID() == other.UID())
110
111
def
__ne__
(self, other):
112
"""True if the 2 objects *not* have the same class and ID."""
113
return
not
(self == other)
114
115
def
__hash__
(self):
116
"""True is the 2 objects have the same class and ID and conffwk database
117
"""
118
return
hash(self.full_name())
119
120
def
__setitem__
(self, name, value):
121
"""Sets the attribute or relation defined by 'name'.
122
123
This method works as a wrapper around the several set functions
124
attached to ConfigObjects, by making them feel a bit more pythonic.
125
If attributes do not exist in a certain ConfigObject, we raise an
126
AttributeError. If a value cannot be set, we raise a ValueError instead
127
of the classical SWIG RuntimeErrors everywhere.
128
129
Raises AttributeError, if the 'name' is not a valid class item.
130
Raises ValueError, if I cannot set the value you want to the variable
131
132
Returns 'value', so you can daisy-chain attributes in the normal way.
133
"""
134
try
:
135
if
name
in
self.
__schema__
[
'attribute'
]:
136
self.
__schema__
[
'attribute'
][name][
'co_set_method'
](
137
self, name, value)
138
139
elif
name
in
self.
__schema__
[
'relation'
]:
140
self.
__schema__
[
'relation'
][name][
'co_set_method'
](
141
self, name, value)
142
self.
__cache__
[name] = value
143
144
else
:
145
# shout if you get here
146
raise
KeyError(
'"%s" is not an attribute or relation of '
147
'class "%s"'
%
148
(name, self.class_name()))
149
150
except
RuntimeError
as
e:
151
raise
ValueError(
"Error setting value of variable '%s' in %s "
152
"to '%s': %s"
153
% (name, repr(self), str(value), str(e)))
154
155
return
value
156
157
def
__repr__
(self):
158
return
'<ConfigObject \''
+ self.full_name() +
'\'>'
159
160
def
__str__
(self):
161
return
self.full_name() + \
162
' (%d attributes, %d relations), inherits from %s'
% \
163
(len(self.
__schema__
[
'attribute'
]),
164
len(self.
__schema__
[
'relation'
]),
165
self.
__schema__
[
'superclass'
])
166
167
def
update_dal
(self, d, followup_method, get_method, cache=None,
168
recurse=True):
169
"""Sets each attribute defined in the DAL object 'd', with the value.
170
171
This method will update the ConfigObject attributes and its
172
relationships recursively, cooperatively with the Configuration class.
173
The recursion is implemented in a very easy way in these terms.
174
175
Keyword arguments:
176
177
d -- This is the DAL object you are trying to set this
178
ConfigObject from.
179
180
followup_method -- The Configuration method to call for the recursion.
181
This one varies with the type of change you are performing (adding or
182
updating).
183
184
get_method -- The Configuration method to call for retrieving objects
185
from the associated database.
186
187
cache -- This is a cache that may be set by the Configuration object if
188
necessary. Users should *never* set this variable. This variable is
189
there to handle recursions gracefully.
190
191
recurse -- This is a boolean flag that indicates if you want to enable
192
recursion or not in the update. If set to 'True' (the default), I'll
193
recurse until all objects in the tree are updated. Otherwise, I'll not
194
recurse at all and just make sure my attributes and relationships are
195
set to what you determine they should be. Please note that if you
196
decide to update relationships, that the objects to which you are
197
pointing to should be available in the database (directly or indirectly
198
through includes) if you choose to do this non-recursively.
199
200
"""
201
for
k
in
self.
__schema__
[
'attribute'
].keys():
202
if
hasattr(d, k)
and
getattr(d, k)
is
not
None
:
203
self[k] = getattr(d, k)
204
205
for
k, v
in
self.
__schema__
[
'relation'
].items():
206
if
not
hasattr(d, k):
207
continue
208
209
# if you get here, d has attribute k and it is not None
210
if
v[
'multivalue'
]:
211
if
not
getattr(d, k):
212
self[k] = []
213
else
:
214
# please, note you cannot just "append" to ConfigObject
215
# multiple relationships, since a new value (i.e. a new
216
# list) is returned each time you use __getitem__.
217
# So, you have to set all in one go.
218
val = []
219
for
i
in
getattr(d, k):
220
if
cache
and
i.fullName()
in
cache:
221
val.append(cache[i.fullName()])
222
elif
recurse:
223
val.append(followup_method(
224
i, cache=cache, recurse=recurse))
225
else
:
226
val.append(get_method(i.className(), i.id))
227
self[k] = val
228
229
else
:
# this is the simplest case
230
i = getattr(d, k)
231
if
i:
232
if
cache
and
i.fullName()
in
cache:
233
self[k] = cache[i.fullName()]
234
elif
recurse:
235
self[k] = followup_method(
236
i, cache=cache, recurse=recurse)
237
else
:
238
self[k] = get_method(i.className(), i.id)
239
else
:
240
self[k] =
None
241
242
def
as_dal
(self, cache):
243
"""Returns a DAL representation of myself and my descendents.
244
245
In this implementation, we by-pass the type checking facility to gain
246
in time and because we know that if the ConfigObject was set, it must
247
conform to OKS in any case.
248
"""
249
dobj = self.
__schema__
[
'dal'
](id=self.UID())
250
for
k
in
dobj.oksTypes():
251
cache[k][self.UID()] = dobj
252
253
for
a
in
self.
__schema__
[
'attribute'
].keys():
254
setattr(dobj.__class__, a,
255
property(dalproperty._return_attribute(a, dobj, self[a]),
256
dalproperty._assign_attribute(a)))
257
258
for
r
in
self.
__schema__
[
'relation'
].keys():
259
data = self[r]
260
261
if
self.
__schema__
[
'relation'
][r][
'multivalue'
]:
262
263
getter = dalproperty. \
264
_return_relation(r, multi=
True
, cache=cache,
265
data=data, dalobj=dobj)
266
267
else
:
268
269
getter = dalproperty. \
270
_return_relation(r, cache=cache,
271
data=data, dalobj=dobj)
272
273
setattr(dobj.__class__, r,
274
property(getter,
275
dalproperty._assign_relation(r)))
276
277
return
dobj
278
279
def
set_obj
(self, name, value):
280
"""Sets the sigle-value relation 'name' to the provided 'value'
281
282
"""
283
284
# the C++ implementation of set_obj wants
285
# a libpyconffwk.ConfigObject instance. So
286
# we have to extract it from our proxy
287
288
if
value
is
not
None
:
289
value = value._obj
290
291
return
super(ConfigObject, self).
set_obj
(name, value)
292
293
def
set_objs
(self, name, value):
294
"""Sets the multi-value relation 'name' to the provided 'value'
295
296
"""
297
298
# the C++ implementation of set_objs wants
299
# a libpyconffwk.ConfigObject instances. So
300
# we have to extract them from our proxy
301
302
if
value
is
not
None
:
303
tmp = [e._obj
if
e
is
not
None
else
e
for
e
in
value]
304
else
:
305
tmp =
None
306
307
return
super(ConfigObject, self).
set_objs
(name, tmp)
conffwk.ConfigObject.ConfigObject
Definition
ConfigObject.py:27
conffwk.ConfigObject.ConfigObject.set_obj
set_obj(self, name, value)
Definition
ConfigObject.py:279
conffwk.ConfigObject.ConfigObject.__hash__
__hash__(self)
Definition
ConfigObject.py:115
conffwk.ConfigObject.ConfigObject.__setitem__
__setitem__(self, name, value)
Definition
ConfigObject.py:120
conffwk.ConfigObject.ConfigObject.__repr__
__repr__(self)
Definition
ConfigObject.py:157
conffwk.ConfigObject.ConfigObject.__cache__
dict __cache__
Definition
ConfigObject.py:55
conffwk.ConfigObject.ConfigObject.__configuration__
__configuration__
Definition
ConfigObject.py:56
conffwk.ConfigObject.ConfigObject.update_dal
update_dal(self, d, followup_method, get_method, cache=None, recurse=True)
Definition
ConfigObject.py:168
conffwk.ConfigObject.ConfigObject.__overall_schema__
__overall_schema__
Definition
ConfigObject.py:54
conffwk.ConfigObject.ConfigObject.__str__
__str__(self)
Definition
ConfigObject.py:160
conffwk.ConfigObject.ConfigObject.__eq__
__eq__(self, other)
Definition
ConfigObject.py:105
conffwk.ConfigObject.ConfigObject.__getitem__
__getitem__(self, name)
Definition
ConfigObject.py:58
conffwk.ConfigObject.ConfigObject.__schema__
__schema__
Definition
ConfigObject.py:53
conffwk.ConfigObject.ConfigObject.as_dal
as_dal(self, cache)
Definition
ConfigObject.py:242
conffwk.ConfigObject.ConfigObject.__ne__
__ne__(self, other)
Definition
ConfigObject.py:111
conffwk.ConfigObject.ConfigObject.__init__
__init__(self, raw_object, schema, configuration)
Definition
ConfigObject.py:30
conffwk.ConfigObject.ConfigObject.set_objs
set_objs(self, name, value)
Definition
ConfigObject.py:293
conffwk.ConfigObject._ConfigObjectProxy
Definition
ConfigObject.py:23
Generated on
for DUNE-DAQ by
1.17.0