The Gaudi Framework
master (bb4415cc)
Toggle main menu visibility
Loading...
Searching...
No Matches
semantics.py
Go to the documentation of this file.
1
11
import
copy
12
import
json
13
import
logging
14
import
re
15
import
sys
16
from
collections.abc
import
MutableMapping, MutableSequence, MutableSet
17
18
import
GaudiKernel.GaudiHandles
19
from
GaudiKernel.DataHandle
import
DataHandle, DataHandleVector
20
from
GaudiKernel.GaudiHandles
import
GaudiHandle
21
22
from
.
import
Configurable, Configurables
23
24
_log = logging.getLogger(__name__)
25
is_64bits = sys.maxsize > 2**32
26
27
28
class
PropertySemantics
(object):
29
"""
30
Basic property semantics implementation, with no validation/transformation.
31
32
Not to be used directly for any actual property, use only specializations.
33
"""
34
35
__handled_types__ = ()
36
37
def
__init__
(self, cpp_type):
38
self.
_name
=
None
39
self.
cpp_type
= cpp_type
40
41
@property
42
def
name
(self):
43
return
self.
_name
44
45
@name.setter
46
def
name
(self, value):
47
self.
_name
= value
48
49
@property
50
def
cpp_type
(self):
51
return
self.
_cpp_type
52
53
@cpp_type.setter
54
def
cpp_type
(self, value):
55
if
not
any(
56
h.match(value)
if
hasattr(h,
"match"
)
else
h == value
57
for
h
in
self.
__handled_types__
58
):
59
raise
TypeError(
"C++ type {!r} not supported"
.
format
(value))
60
self.
_cpp_type
= value
61
62
def
load
(self, value):
63
"""
64
Transformation for data when reading the property.
65
"""
66
return
value
67
68
def
store
(self, value):
69
"""
70
Validation/transformation of the data to be stored.
71
"""
72
return
value
73
74
def
is_set
(self, value):
75
"""
76
Allow overriding the definition of "is set" if we need helper types.
77
"""
78
return
True
79
80
def
opt_value
(self, value):
81
"""
82
Option string version of value.
83
"""
84
if
hasattr(value,
"__opt_value__"
):
85
return
value.__opt_value__()
86
return
value
87
88
def
merge
(self, a, b):
89
"""
90
"Merge" two values.
91
92
Used when merging two Configurable instances, by default just ensure
93
the two values do not conflict, but it can be overridden in
94
derived semantics to, for example, append to the two lists.
95
"""
96
if
self.
store
(a) != self.
store
(b):
97
raise
ValueError(
"cannot merge values %r and %r"
% (a, b))
98
return
a
99
100
101
class
DefaultSemantics
(
PropertySemantics
):
102
"""
103
Special semantics that makes a deep copy of the default value on first access
104
and considers a property set if its value is different from the default.
105
106
This semantics is meant to be used whenever there is no specific semantic
107
(with proper change detection) implemented for a type.
108
"""
109
110
__handled_types__ = (re.compile(
r".*"
),)
111
112
def
default
(self, value):
113
# remember the default value we got and return a copy
114
self.
_default
= value
115
self.
_is_set
=
False
116
return
copy.deepcopy(value)
117
118
def
store
(self, value):
119
# flag that the value was explicitly set
120
self.
_is_set
=
True
121
return
super(DefaultSemantics, self).
store
(value)
122
123
def
is_set
(self, value):
124
try
:
125
# we assume the property was set if it was changed
126
return
self.
_is_set
or
self.
_default
!= value
127
except
AttributeError:
128
# either self._is_set or self._default is not defined,
129
# so the value was not explicitly set nor modified
130
# from the default
131
return
False
132
133
134
class
_JSONValue
:
135
def
__init__
(self, data, explicitly_set):
136
self.
data
= data
137
self.
default
= copy.deepcopy(data)
138
self.
explicitly_set
= explicitly_set
139
140
def
__eq__
(self, other):
141
return
isinstance(other, _JSONValue)
and
self.
data
== other.data
142
143
144
class
_JSONOption
(str):
145
def
__opt_repr__
(self):
146
return
str(self)
147
148
149
class
JSONSemantics
(
PropertySemantics
):
150
__handled_types__ = (
151
"nlohmann::json"
,
152
re.compile(
r"nlohmann::(?:json_abi[^:]*::)?basic_json<.*>$"
),
153
)
154
155
@staticmethod
156
def
_normalize
(value):
157
return
json.loads(json.dumps(value, allow_nan=
False
))
158
159
def
default
(self, value):
160
data = json.loads(value)
if
isinstance(value, str)
else
self.
_normalize
(value)
161
return
_JSONValue
(data,
False
)
162
163
def
load
(self, value):
164
return
value.data
165
166
def
store
(self, value):
167
return
_JSONValue
(self.
_normalize
(value),
True
)
168
169
def
is_set
(self, value):
170
return
value.explicitly_set
or
value.data != value.default
171
172
def
opt_value
(self, value):
173
if
not
isinstance(value, _JSONValue):
174
value = self.
default
(value)
175
return
_JSONOption
(
176
json.dumps(
177
value.data, allow_nan=
False
, separators=(
","
,
":"
), sort_keys=
True
178
)
179
)
180
181
182
class
StringSemantics
(
PropertySemantics
):
183
__handled_types__ = (
"std::string"
,)
184
185
def
store
(self, value):
186
if
not
isinstance(value, str):
187
raise
TypeError(
"cannot set property {} to {!r}"
.
format
(self.
name
, value))
188
return
value
189
190
191
class
BoolSemantics
(
PropertySemantics
):
192
__handled_types__ = (
"bool"
,)
193
194
def
store
(self, value):
195
return
bool(value)
196
197
198
class
FloatSemantics
(
PropertySemantics
):
199
__handled_types__ = (
"float"
,
"double"
)
200
201
def
store
(self, value):
202
from
numbers
import
Number
203
204
if
not
isinstance(value, Number):
205
raise
TypeError(
206
"number expected, got {!r} in assignment to {}"
.
format
(value, self.
name
)
207
)
208
return
float(value)
209
210
211
class
IntSemantics
(
PropertySemantics
):
212
# dictionary generated with tools/print_limits.cpp
213
INT_RANGES = {
214
"signed char"
: (-128, 127),
215
"short"
: (-32768, 32767),
216
"int"
: (-2147483648, 2147483647),
217
"long"
: (
218
(-9223372036854775808, 9223372036854775807)
219
if
is_64bits
220
else
(-2147483648, 2147483647)
221
),
222
"long long"
: (-9223372036854775808, 9223372036854775807),
223
"unsigned char"
: (0, 255),
224
"unsigned short"
: (0, 65535),
225
"unsigned int"
: (0, 4294967295),
226
"unsigned long"
: (0, 18446744073709551615
if
is_64bits
else
4294967295),
227
"unsigned long long"
: (0, 18446744073709551615),
228
}
229
230
__handled_types__ = tuple(INT_RANGES)
231
232
def
store
(self, value):
233
from
numbers
import
Number
234
235
if
not
isinstance(value, Number):
236
raise
TypeError(
237
"number expected, got {!r} in assignment to {}"
.
format
(value, self.
name
)
238
)
239
v = int(value)
240
if
v != value:
241
_log.warning(
"converted %s to %d in assignment to %s"
, value, v, self.
name
)
242
min_value, max_value = self.
INT_RANGES
[self.
cpp_type
]
243
if
v < min_value
or
v > max_value:
244
raise
ValueError(
245
"value {} outside limits for {!r} {}"
.
format
(
246
v, self.
cpp_type
, self.
INT_RANGES
[self.
cpp_type
]
247
)
248
)
249
return
v
250
251
252
_IDENTIFIER_RE =
r"[a-zA-Z_][a-zA-Z0-9_]*"
253
_NS_IDENT_RE =
r"{ident}(::{ident})*"
.
format
(ident=_IDENTIFIER_RE)
254
_COMMA_SEPARATION_RE =
r"{exp}(,{exp})*"
255
256
257
class
ComponentSemantics
(
PropertySemantics
):
258
__handled_types__ = (
259
"Algorithm"
,
260
"Auditor"
,
261
re.compile(
262
r"AlgTool(:{})?$"
.
format
(_COMMA_SEPARATION_RE.format(exp=_NS_IDENT_RE))
263
),
264
re.compile(
265
r"Service(:{})?$"
.
format
(_COMMA_SEPARATION_RE.format(exp=_NS_IDENT_RE))
266
),
267
)
268
269
def
__init__
(self, cpp_type):
270
super(ComponentSemantics, self).
__init__
(cpp_type)
271
if
":"
in
cpp_type:
272
self.
cpp_type
, self.
interfaces
= cpp_type.split(
":"
, 1)
273
self.
interfaces
= set(self.
interfaces
.split(
","
))
274
else
:
275
self.
cpp_type
= cpp_type
276
self.
interfaces
= set()
277
278
def
store
(self, value):
279
if
isinstance(value, Configurable):
280
value.name
# make sure the configurable has a name
281
elif
isinstance(value, str):
282
# try to map the sring to an existing Configurable
283
if
value
in
Configurable.instances:
284
value = Configurable.instances[value]
285
else
:
286
# or create one from type and name
287
if
"/"
in
value:
288
t, n = value.split(
"/"
)
289
else
:
290
t = n = value
291
value = Configurables.getByType(t).getInstance(n)
292
else
:
293
raise
TypeError(
294
"cannot assign {!r} to {!r}, requested string or {!r}"
.
format
(
295
value, self.
name
, self.
cpp_type
296
)
297
)
298
if
value.__component_type__ != self.
cpp_type
:
299
raise
TypeError(
300
"wrong type for {!r}: expected {!r}, got {!r}"
.
format
(
301
self.
name
, self.
cpp_type
, value.__component_type__
302
)
303
)
304
try
:
305
# if no interface is declared we cannot check
306
if
value.__interfaces__:
307
if
not
self.
interfaces
.issubset(value.__interfaces__):
308
raise
TypeError(
309
"wrong interfaces for {!r}: required {}"
.
format
(
310
self.
name
, list(self.
interfaces
)
311
)
312
)
313
except
AttributeError:
314
pass
# no interfaces declared by the configrable, cannot check
315
return
value
316
317
def
default
(self, value):
318
return
self.
store
(value)
319
320
321
class
ComponentHandleSemantics
(
PropertySemantics
):
322
"""
323
Semantics for component (tool, service) handles. On access, it will create the
324
corresponding Configurable instance and store it in the property.
325
"""
326
327
__handled_types__ = (
"PrivateToolHandle"
,
"PublicToolHandle"
,
"ServiceHandle"
)
328
329
def
__init__
(self, cpp_type):
330
super().
__init__
(cpp_type)
331
self.
handle_type
= getattr(
GaudiKernel.GaudiHandles
, self.
cpp_type
)
332
333
def
store
(self, value):
334
# Configurable: store if correct type
335
if
(
336
isinstance(value, Configurable)
337
and
value.getGaudiType() == self.
handle_type
.componentType
338
):
339
return
value
340
341
# Handle: create Configurable
342
elif
isinstance(value, GaudiHandle):
343
return
(
344
Configurables.getByType(value.getType()).getInstance(value.getName())
345
if
value.typeAndName
346
else
self.
handle_type
()
# empty handle
347
)
348
349
# Empty: empty Handle
350
elif
value
is
None
or
value ==
""
:
351
return
self.
handle_type
()
352
353
# String: create Configurable
354
elif
isinstance(value, str):
355
tn = value.split(
"/"
, maxsplit=1)
# type[/name]
356
name = tn[1]
if
len(tn) == 2
else
tn[0]
357
return
Configurables.getByType(tn[0]).getInstance(name)
358
359
raise
TypeError(f
"cannot assign {value!r} ({type(value)}) to {self.name}"
)
360
361
def
default
(self, value):
362
return
self.
store
(value)
363
364
def
merge
(self, b, a):
365
return
a.merge(b)
366
367
368
class
_GaudiHandleArrayOptionValue
(list):
369
def
__opt_repr__
(self):
370
return
"["
+
","
.join(map(repr, self)) +
"]"
371
372
373
class
GaudiHandleArraySemantics
(
DefaultSemantics
):
374
"""Semantics for GaudiHandleArrays."""
375
376
__handled_types__ = (
377
"PrivateToolHandleArray"
,
378
"PublicToolHandleArray"
,
379
"ServiceHandleArray"
,
380
)
381
382
def
__init__
(self, cpp_type):
383
super().
__init__
(cpp_type)
384
self.
handle_type
= getattr(
GaudiKernel.GaudiHandles
, self.
cpp_type
)
385
386
def
store
(self, value):
387
# flag that the value was explicitly set (see DefaultSemantics)
388
self.
_is_set
=
True
389
390
# Create HandleArray from value if needed (it does all the type checking)
391
if
not
isinstance(value, self.
handle_type
):
392
value = self.
handle_type
(value)
393
return
value
394
395
def
opt_value
(self, value):
396
return
_GaudiHandleArrayOptionValue
(
397
handle.toStringProperty()
for
handle
in
value
398
)
399
400
def
merge
(self, b, a):
401
for
comp
in
b:
402
try
:
403
# If a component with that name exists in a, we merge it
404
a.__getitem__(comp.getName()).
merge
(comp)
405
except
IndexError:
406
# Otherwise append it
407
a.append(comp)
408
return
a
409
410
411
class
DataHandleSemantics
(
PropertySemantics
):
412
"""
413
Semantics for data handles.
414
"""
415
416
__handled_types__ = (re.compile(
r"DataObject(Read|Write)Handle<.*>$"
),)
417
418
def
__init__
(self, cpp_type):
419
super().
__init__
(cpp_type)
420
self.
_type
= next(
extract_template_args
(cpp_type))
421
self.
_isCond
=
False
# no specific conditions handle in Gaudi yet
422
423
if
cpp_type.startswith(
"DataObjectReadHandle"
):
424
self.
_mode
=
"R"
425
elif
cpp_type.startswith(
"DataObjectWriteHandle"
):
426
self.
_mode
=
"W"
427
else
:
428
raise
TypeError(f
"C++ type {cpp_type} not supported"
)
429
430
def
store
(self, value):
431
if
isinstance(value, DataHandle):
432
v = value.Path
433
elif
isinstance(value, str):
434
v = value
435
else
:
436
raise
TypeError(
437
f
"cannot assign {value!r} ({type(value)}) to {self.name}"
438
", expected string or DataHandle"
439
)
440
return
DataHandle
(v, self.
_mode
, self.
_type
, self.
_isCond
)
441
442
def
opt_value
(self, value):
443
return
value.Path
444
445
446
def
extract_template_args
(cpp_type):
447
"""
448
Return an iterator over the list of template arguments in a C++ type
449
string.
450
451
>>> t = 'map<string, vector<int, allocator<int> >, allocator<v<i>, a<i>> >'
452
>>> list(extract_template_args(t))
453
['string', 'vector<int, allocator<int> >', 'allocator<v<i>, a<i>>']
454
>>> list(extract_template_args('int'))
455
[]
456
"""
457
template_level = 0
458
arg_start = -1
459
for
p, c
in
enumerate(cpp_type):
460
if
c ==
","
:
461
if
template_level == 1:
462
yield
cpp_type[arg_start:p].strip()
463
arg_start = p + 1
464
elif
c ==
"<"
:
465
template_level += 1
466
if
template_level == 1:
467
arg_start = p + 1
468
elif
c ==
">"
:
469
template_level -= 1
470
if
template_level == 0:
471
yield
cpp_type[arg_start:p].strip()
472
473
474
class
_ListHelper
(MutableSequence):
475
def
__init__
(self, semantics):
476
self.
value_semantics
= semantics
477
self.
default
=
None
478
self.
_data
= []
479
self.
is_dirty
=
False
480
481
@property
482
def
data
(self):
483
return
self.
_data
if
self.
is_dirty
else
self.
default
484
485
def
__len__
(self):
486
return
len(self.
data
)
487
488
def
__getitem__
(self, key):
489
return
self.
value_semantics
.load(self.
data
.
__getitem__
(key))
490
491
def
__setitem__
(self, key, value):
492
self.
is_dirty
=
True
493
self.
data
.
__setitem__
(key, self.
value_semantics
.store(value))
494
495
def
__delitem__
(self, key):
496
if
not
self.
is_dirty
:
497
raise
RuntimeError(
"cannot remove elements from the default value"
)
498
self.
data
.
__delitem__
(key)
499
500
def
__eq__
(self, other):
501
return
self.
data
== other
502
503
def
insert
(self, key, value):
504
self.
is_dirty
=
True
505
self.
data
.
insert
(key, self.
value_semantics
.store(value))
506
507
def
append
(self, value):
508
self.
is_dirty
=
True
509
self.
data
.
append
(self.
value_semantics
.store(value))
510
511
def
extend
(self, iterable):
512
self.
is_dirty
=
True
513
self.
data
.
extend
(self.
value_semantics
.store(value)
for
value
in
iterable)
514
515
def
opt_value
(self):
516
return
[self.
value_semantics
.
opt_value
(item)
for
item
in
self.
data
]
517
518
def
__repr__
(self):
519
return
repr(self.
data
)
520
521
522
class
SequenceSemantics
(
PropertySemantics
):
523
__handled_types__ = (re.compile(
r"(std::)?(vector|list)<.*>$"
),)
524
525
def
__init__
(self, cpp_type, valueSem=None):
526
super(SequenceSemantics, self).
__init__
(cpp_type)
527
self.
value_semantics
= valueSem
or
getSemanticsFor
(
528
list(
extract_template_args
(cpp_type))[0]
529
)
530
531
@property
532
def
name
(self):
533
return
self.
_name
534
535
@name.setter
536
def
name
(self, value):
537
self.
_name
= value
538
self.
value_semantics
.name =
"{} element"
.
format
(self.
_name
)
539
540
def
store
(self, value):
541
if
not
isinstance(value, (list, _ListHelper, tuple)):
542
raise
TypeError(
543
"list or tuple expected, got {!r} in assignment to {}"
.
format
(
544
value, self.
name
545
)
546
)
547
new_value =
_ListHelper
(self.
value_semantics
)
548
new_value.extend(value)
549
return
new_value
550
551
def
default
(self, value):
552
new_value =
_ListHelper
(self.
value_semantics
)
553
new_value.default = value
554
return
new_value
555
556
def
opt_value
(self, value):
557
"""
558
Option string version of value.
559
"""
560
if
not
isinstance(value, _ListHelper):
561
value = self.
default
(value)
562
return
value.opt_value()
563
564
565
class
DataHandleVectorSemantics
(
SequenceSemantics
):
566
"""Sequence semantics whose elements are data handles."""
567
568
__handled_types__ = (
569
re.compile(
r"Gaudi::DataHandleVector<DataObject(Read|Write)Handle,.*>$"
),
570
)
571
572
def
__init__
(self, cpp_type):
573
if
not
self.
__handled_types__
[0].match(cpp_type):
574
raise
TypeError(f
"C++ type {cpp_type!r} not supported"
)
575
handle_type, value_type =
extract_template_args
(cpp_type)
576
super().
__init__
(
577
cpp_type, valueSem=
DataHandleSemantics
(f
"{handle_type}<{value_type}>"
)
578
)
579
580
def
store
(self, value):
581
if
isinstance(value, DataHandleVector):
582
value = value.paths()
583
handles = super().
store
(value)
584
return
DataHandleVector
(
585
[handle.Path
for
handle
in
handles],
586
self.
value_semantics
._mode,
587
self.
value_semantics
._type,
588
self.
value_semantics
._isCond,
589
)
590
591
def
default
(self, value):
592
return
self.
store
(value)
593
594
def
opt_value
(self, value):
595
return
value.paths()
596
597
def
merge
(self, b, a):
598
paths = a.paths()
599
for
handle
in
b:
600
path = self.
value_semantics
.
store
(handle).Path
601
if
path
not
in
paths:
602
paths.append(path)
603
return
a
604
605
606
class
_SetHelper
(MutableSet):
607
def
__init__
(self, semantics):
608
self.
value_semantics
= semantics
609
self.
default
= set()
# cannot use None due to the way __ior__ is implemented
610
self.
_data
= set()
611
self.
is_dirty
=
False
612
613
# Aliases to match builtin `set`
614
union = MutableSet.__ior__
615
update = MutableSet.__ior__
616
intersection = MutableSet.__iand__
617
difference = MutableSet.__isub__
618
symmetric_difference = MutableSet.__ixor__
619
620
@property
621
def
data
(self):
622
return
self.
_data
if
self.
is_dirty
else
self.
default
623
624
def
__len__
(self):
625
return
len(self.
data
)
626
627
def
__contains__
(self, value):
628
return
self.
value_semantics
.store(value)
in
self.
data
629
630
def
__eq__
(self, other):
631
return
self.
data
== other
632
633
def
__iter__
(self):
634
for
value
in
self.
data
:
635
yield
self.
value_semantics
.load(value)
636
637
def
add
(self, value):
638
self.
is_dirty
=
True
639
self.
data
.
add
(self.
value_semantics
.store(value))
640
641
def
discard
(self, value):
642
if
not
self.
is_dirty
:
643
raise
RuntimeError(
"cannot remove elements from the default value"
)
644
self.
data
.
discard
(value)
645
646
def
pop
(self):
647
if
not
self.
is_dirty
:
648
raise
RuntimeError(
"cannot remove elements from the default value"
)
649
return
self.
data
.
pop
()
650
651
def
opt_value
(self):
652
return
set(self.
value_semantics
.
opt_value
(item)
for
item
in
self.
data
)
653
654
def
__repr__
(self):
655
if
self.
data
:
656
# sort into list but print as set to get reproducible repr
657
return
"{"
+ repr(sorted(self.
data
))[1:-1] +
"}"
658
else
:
659
return
"set()"
660
661
662
class
SetSemantics
(
PropertySemantics
):
663
"""Merge semantics for (unordered) sets."""
664
665
__handled_types__ = (re.compile(
r"(std::)?unordered_set<.*>$"
),)
666
667
def
__init__
(self, cpp_type, valueSem=None):
668
super(SetSemantics, self).
__init__
(cpp_type)
669
self.
value_semantics
= valueSem
or
getSemanticsFor
(
670
list(
extract_template_args
(cpp_type))[0]
671
)
672
673
@property
674
def
name
(self):
675
return
self.
_name
676
677
@name.setter
678
def
name
(self, value):
679
self.
_name
= value
680
self.
value_semantics
.name =
"{} element"
.
format
(self.
_name
)
681
682
def
store
(self, value):
683
# We support assignment from list for backwards compatibility
684
if
not
isinstance(value, (set, _SetHelper, list, _ListHelper)):
685
raise
TypeError(
686
"set expected, got {!r} in assignment to {}"
.
format
(value, self.
name
)
687
)
688
689
new_value =
_SetHelper
(self.
value_semantics
)
690
new_value |= value
691
return
new_value
692
693
def
default
(self, value):
694
new_value =
_SetHelper
(self.
value_semantics
)
695
new_value.default = value
696
return
new_value
697
698
def
opt_value
(self, value):
699
"""
700
Option string version of value.
701
"""
702
if
not
isinstance(value, _SetHelper):
703
value = self.
default
(value)
704
return
value.opt_value()
705
706
def
merge
(self, bb, aa):
707
aa |= bb
708
return
aa
709
710
711
class
OrderedSetSemantics
(
SequenceSemantics
):
712
"""
713
Extend the sequence-semantics with a merge-method to behave like a
714
OrderedSet: Values are unique but the order is maintained.
715
Use 'OrderedSet<T>' as fifth parameter of the Gaudi::Property<T> constructor
716
to invoke this merging method. Also applies to std::set.
717
"""
718
719
__handled_types__ = (
720
re.compile(
r"(std::)?set<.*>$"
),
721
re.compile(
r"^OrderedSet<.*>$"
),
722
)
723
724
def
__init__
(self, cpp_type):
725
super(OrderedSetSemantics, self).
__init__
(cpp_type)
726
727
def
merge
(self, bb, aa):
728
for
b
in
bb:
729
if
b
not
in
aa:
730
aa.append(b)
731
return
aa
732
733
734
class
_DictHelper
(MutableMapping):
735
def
__init__
(self, key_semantics, value_semantics):
736
self.
key_semantics
= key_semantics
737
self.
value_semantics
= value_semantics
738
self.
default
=
None
739
self.
_data
= {}
740
self.
is_dirty
=
False
741
742
@property
743
def
data
(self):
744
return
self.
_data
if
self.
is_dirty
else
self.
default
745
746
def
__len__
(self):
747
return
len(self.
data
)
748
749
def
__getitem__
(self, key):
750
return
self.
value_semantics
.load(
751
self.
data
.
__getitem__
(self.
key_semantics
.store(key))
752
)
753
754
def
__setitem__
(self, key, value):
755
self.
is_dirty
=
True
756
self.
data
.
__setitem__
(
757
self.
key_semantics
.store(key), self.
value_semantics
.store(value)
758
)
759
760
def
__delitem__
(self, key):
761
if
not
self.
is_dirty
:
762
raise
RuntimeError(
"cannot remove elements from the default value"
)
763
self.
data
.
__delitem__
(self.
key_semantics
.store(key))
764
765
def
__iter__
(self):
766
for
key
in
self.
data
:
767
yield
self.
key_semantics
.load(key)
768
769
def
keys
(self):
770
return
list(self)
771
772
def
items
(self):
773
for
key, value
in
self.
data
.
items
():
774
yield
(self.
key_semantics
.load(key), self.
value_semantics
.load(value))
775
776
def
values
(self):
777
for
value
in
self.
data
.
values
():
778
yield
self.
value_semantics
.load(value)
779
780
def
__contains__
(self, key):
781
return
self.
key_semantics
.store(key)
in
self.
data
782
783
def
get
(self, key, default=None):
784
key = self.
key_semantics
.store(key)
785
if
key
in
self.
data
:
786
return
self.
value_semantics
.load(self.
data
[key])
787
return
default
788
789
# __contains__, , get, __eq__, __ne__
790
# popitem, clear, setdefault
791
792
def
update
(self, otherMap):
793
self.
is_dirty
=
True
794
for
key, value
in
otherMap.items():
795
self.
data
[self.
key_semantics
.store(key)] = self.
value_semantics
.store(value)
796
797
def
opt_value
(self):
798
return
{
799
self.
key_semantics
.
opt_value
(key): self.
value_semantics
.
opt_value
(value)
800
for
key, value
in
self.
data
.
items
()
801
}
802
803
def
__repr__
(self):
804
return
repr(self.
data
)
805
806
807
class
MappingSemantics
(
PropertySemantics
):
808
__handled_types__ = (re.compile(
r"(std::)?(unordered_)?map<.*>$"
),)
809
810
def
__init__
(self, cpp_type):
811
super(MappingSemantics, self).
__init__
(cpp_type)
812
template_args = list(
extract_template_args
(cpp_type))
813
self.
key_semantics
=
getSemanticsFor
(template_args[0])
814
self.
value_semantics
=
getSemanticsFor
(template_args[1])
815
816
@property
817
def
name
(self):
818
return
self.
_name
819
820
@name.setter
821
def
name
(self, value):
822
self.
_name
= value
823
self.
key_semantics
.name =
"{} key"
.
format
(self.
_name
)
824
self.
value_semantics
.name =
"{} value"
.
format
(self.
_name
)
825
826
def
store
(self, value):
827
# No explicit type checking as anything else than dict fails in update call
828
new_value =
_DictHelper
(self.
key_semantics
, self.
value_semantics
)
829
new_value.update(value)
830
return
new_value
831
832
def
default
(self, value):
833
new_value =
_DictHelper
(self.
key_semantics
, self.
value_semantics
)
834
new_value.default = value
835
return
new_value
836
837
def
opt_value
(self, value):
838
"""
839
Option string version of value.
840
"""
841
if
not
isinstance(value, _DictHelper):
842
value = self.
default
(value)
843
return
value.opt_value()
844
845
def
merge
(self, a, b):
846
"""Merge two maps. Throw ValueError if there are conflicting key/value pairs."""
847
848
# Optimization for most common case
849
if
a == b:
850
return
a
851
852
for
k, v
in
b.items():
853
try
:
854
va = a[k]
855
except
KeyError:
856
a[k] = v
857
else
:
858
if
va != v:
859
raise
ValueError(
860
f
"conflicting values in map for key {k}: {v} and {va}"
861
)
862
return
a
863
864
865
SEMANTICS = [
866
c
867
for
c
in
globals().values()
868
if
isinstance(c, type)
869
and
issubclass(c, PropertySemantics)
870
and
c
not
in
(PropertySemantics, DefaultSemantics)
871
]
872
873
874
def
getSemanticsFor
(cpp_type, strict=False):
875
"""Return semantics for given type. If no type-specific semantics can be found
876
return DefaultSemantics. In strict mode, raise a TypeError instead.
877
"""
878
879
for
semantics
in
SEMANTICS:
880
try
:
881
return
semantics(cpp_type)
882
except
TypeError:
883
pass
884
885
if
strict:
886
raise
TypeError(f
"No semantics found for {cpp_type}"
)
887
888
return
DefaultSemantics
(cpp_type)
format
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition
MsgStream.cpp:93
GaudiConfig2.semantics._DictHelper
Definition
semantics.py:734
GaudiConfig2.semantics._DictHelper.__repr__
__repr__(self)
Definition
semantics.py:803
GaudiConfig2.semantics._DictHelper.__iter__
__iter__(self)
Definition
semantics.py:765
GaudiConfig2.semantics._DictHelper.keys
keys(self)
Definition
semantics.py:769
GaudiConfig2.semantics._DictHelper.__setitem__
__setitem__(self, key, value)
Definition
semantics.py:754
GaudiConfig2.semantics._DictHelper.values
values(self)
Definition
semantics.py:776
GaudiConfig2.semantics._DictHelper.is_dirty
bool is_dirty
Definition
semantics.py:740
GaudiConfig2.semantics._DictHelper.default
default
Definition
semantics.py:738
GaudiConfig2.semantics._DictHelper.items
items(self)
Definition
semantics.py:772
GaudiConfig2.semantics._DictHelper.key_semantics
key_semantics
Definition
semantics.py:736
GaudiConfig2.semantics._DictHelper.__delitem__
__delitem__(self, key)
Definition
semantics.py:760
GaudiConfig2.semantics._DictHelper.data
data
Definition
semantics.py:747
GaudiConfig2.semantics._DictHelper.__len__
__len__(self)
Definition
semantics.py:746
GaudiConfig2.semantics._DictHelper.__contains__
__contains__(self, key)
Definition
semantics.py:780
GaudiConfig2.semantics._DictHelper.__init__
__init__(self, key_semantics, value_semantics)
Definition
semantics.py:735
GaudiConfig2.semantics._DictHelper.opt_value
opt_value(self)
Definition
semantics.py:797
GaudiConfig2.semantics._DictHelper.value_semantics
value_semantics
Definition
semantics.py:737
GaudiConfig2.semantics._DictHelper._data
dict _data
Definition
semantics.py:739
GaudiConfig2.semantics._DictHelper.get
get(self, key, default=None)
Definition
semantics.py:783
GaudiConfig2.semantics._DictHelper.update
update(self, otherMap)
Definition
semantics.py:792
GaudiConfig2.semantics._DictHelper.__getitem__
__getitem__(self, key)
Definition
semantics.py:749
GaudiConfig2.semantics._GaudiHandleArrayOptionValue
Definition
semantics.py:368
GaudiConfig2.semantics._GaudiHandleArrayOptionValue.__opt_repr__
__opt_repr__(self)
Definition
semantics.py:369
GaudiConfig2.semantics._JSONOption
Definition
semantics.py:144
GaudiConfig2.semantics._JSONOption.__opt_repr__
__opt_repr__(self)
Definition
semantics.py:145
GaudiConfig2.semantics._JSONValue
Definition
semantics.py:134
GaudiConfig2.semantics._JSONValue.__eq__
__eq__(self, other)
Definition
semantics.py:140
GaudiConfig2.semantics._JSONValue.__init__
__init__(self, data, explicitly_set)
Definition
semantics.py:135
GaudiConfig2.semantics._JSONValue.explicitly_set
explicitly_set
Definition
semantics.py:138
GaudiConfig2.semantics._JSONValue.default
default
Definition
semantics.py:137
GaudiConfig2.semantics._JSONValue.data
data
Definition
semantics.py:136
GaudiConfig2.semantics._ListHelper
Definition
semantics.py:474
GaudiConfig2.semantics._ListHelper.__getitem__
__getitem__(self, key)
Definition
semantics.py:488
GaudiConfig2.semantics._ListHelper.extend
extend(self, iterable)
Definition
semantics.py:511
GaudiConfig2.semantics._ListHelper.value_semantics
value_semantics
Definition
semantics.py:476
GaudiConfig2.semantics._ListHelper.is_dirty
bool is_dirty
Definition
semantics.py:479
GaudiConfig2.semantics._ListHelper.default
default
Definition
semantics.py:477
GaudiConfig2.semantics._ListHelper.__len__
__len__(self)
Definition
semantics.py:485
GaudiConfig2.semantics._ListHelper.__eq__
__eq__(self, other)
Definition
semantics.py:500
GaudiConfig2.semantics._ListHelper.data
data
Definition
semantics.py:486
GaudiConfig2.semantics._ListHelper.__delitem__
__delitem__(self, key)
Definition
semantics.py:495
GaudiConfig2.semantics._ListHelper.__init__
__init__(self, semantics)
Definition
semantics.py:475
GaudiConfig2.semantics._ListHelper.append
append(self, value)
Definition
semantics.py:507
GaudiConfig2.semantics._ListHelper.opt_value
opt_value(self)
Definition
semantics.py:515
GaudiConfig2.semantics._ListHelper.__setitem__
__setitem__(self, key, value)
Definition
semantics.py:491
GaudiConfig2.semantics._ListHelper.insert
insert(self, key, value)
Definition
semantics.py:503
GaudiConfig2.semantics._ListHelper._data
list _data
Definition
semantics.py:478
GaudiConfig2.semantics._ListHelper.__repr__
__repr__(self)
Definition
semantics.py:518
GaudiConfig2.semantics._SetHelper
Definition
semantics.py:606
GaudiConfig2.semantics._SetHelper.default
default
Definition
semantics.py:609
GaudiConfig2.semantics._SetHelper.data
data
Definition
semantics.py:625
GaudiConfig2.semantics._SetHelper.add
add(self, value)
Definition
semantics.py:637
GaudiConfig2.semantics._SetHelper.__len__
__len__(self)
Definition
semantics.py:624
GaudiConfig2.semantics._SetHelper._data
_data
Definition
semantics.py:610
GaudiConfig2.semantics._SetHelper.__eq__
__eq__(self, other)
Definition
semantics.py:630
GaudiConfig2.semantics._SetHelper.pop
pop(self)
Definition
semantics.py:646
GaudiConfig2.semantics._SetHelper.is_dirty
bool is_dirty
Definition
semantics.py:611
GaudiConfig2.semantics._SetHelper.discard
discard(self, value)
Definition
semantics.py:641
GaudiConfig2.semantics._SetHelper.__repr__
__repr__(self)
Definition
semantics.py:654
GaudiConfig2.semantics._SetHelper.__contains__
__contains__(self, value)
Definition
semantics.py:627
GaudiConfig2.semantics._SetHelper.__init__
__init__(self, semantics)
Definition
semantics.py:607
GaudiConfig2.semantics._SetHelper.value_semantics
value_semantics
Definition
semantics.py:608
GaudiConfig2.semantics._SetHelper.__iter__
__iter__(self)
Definition
semantics.py:633
GaudiConfig2.semantics._SetHelper.opt_value
opt_value(self)
Definition
semantics.py:651
GaudiConfig2.semantics.BoolSemantics
Definition
semantics.py:191
GaudiConfig2.semantics.BoolSemantics.store
store(self, value)
Definition
semantics.py:194
GaudiConfig2.semantics.ComponentHandleSemantics
Definition
semantics.py:321
GaudiConfig2.semantics.ComponentHandleSemantics.store
store(self, value)
Definition
semantics.py:333
GaudiConfig2.semantics.ComponentHandleSemantics.merge
merge(self, b, a)
Definition
semantics.py:364
GaudiConfig2.semantics.ComponentHandleSemantics.default
default(self, value)
Definition
semantics.py:361
GaudiConfig2.semantics.ComponentHandleSemantics.handle_type
handle_type
Definition
semantics.py:331
GaudiConfig2.semantics.ComponentHandleSemantics.__init__
__init__(self, cpp_type)
Definition
semantics.py:329
GaudiConfig2.semantics.ComponentSemantics
Definition
semantics.py:257
GaudiConfig2.semantics.ComponentSemantics.__init__
__init__(self, cpp_type)
Definition
semantics.py:269
GaudiConfig2.semantics.ComponentSemantics.store
store(self, value)
Definition
semantics.py:278
GaudiConfig2.semantics.ComponentSemantics.default
default(self, value)
Definition
semantics.py:317
GaudiConfig2.semantics.ComponentSemantics.interfaces
interfaces
Definition
semantics.py:272
GaudiConfig2.semantics.DataHandleSemantics
Definition
semantics.py:411
GaudiConfig2.semantics.DataHandleSemantics._isCond
bool _isCond
Definition
semantics.py:421
GaudiConfig2.semantics.DataHandleSemantics._mode
str _mode
Definition
semantics.py:424
GaudiConfig2.semantics.DataHandleSemantics.store
store(self, value)
Definition
semantics.py:430
GaudiConfig2.semantics.DataHandleSemantics._type
_type
Definition
semantics.py:420
GaudiConfig2.semantics.DataHandleSemantics.__init__
__init__(self, cpp_type)
Definition
semantics.py:418
GaudiConfig2.semantics.DataHandleSemantics.opt_value
opt_value(self, value)
Definition
semantics.py:442
GaudiConfig2.semantics.DataHandleVectorSemantics
Definition
semantics.py:565
GaudiConfig2.semantics.DataHandleVectorSemantics.merge
merge(self, b, a)
Definition
semantics.py:597
GaudiConfig2.semantics.DataHandleVectorSemantics.store
store(self, value)
Definition
semantics.py:580
GaudiConfig2.semantics.DataHandleVectorSemantics.__init__
__init__(self, cpp_type)
Definition
semantics.py:572
GaudiConfig2.semantics.DataHandleVectorSemantics.default
default(self, value)
Definition
semantics.py:591
GaudiConfig2.semantics.DataHandleVectorSemantics.opt_value
opt_value(self, value)
Definition
semantics.py:594
GaudiConfig2.semantics.DefaultSemantics
Definition
semantics.py:101
GaudiConfig2.semantics.DefaultSemantics.default
default(self, value)
Definition
semantics.py:112
GaudiConfig2.semantics.DefaultSemantics.is_set
is_set(self, value)
Definition
semantics.py:123
GaudiConfig2.semantics.DefaultSemantics._default
_default
Definition
semantics.py:114
GaudiConfig2.semantics.DefaultSemantics._is_set
bool _is_set
Definition
semantics.py:115
GaudiConfig2.semantics.DefaultSemantics.store
store(self, value)
Definition
semantics.py:118
GaudiConfig2.semantics.FloatSemantics
Definition
semantics.py:198
GaudiConfig2.semantics.FloatSemantics.store
store(self, value)
Definition
semantics.py:201
GaudiConfig2.semantics.GaudiHandleArraySemantics
Definition
semantics.py:373
GaudiConfig2.semantics.GaudiHandleArraySemantics.opt_value
opt_value(self, value)
Definition
semantics.py:395
GaudiConfig2.semantics.GaudiHandleArraySemantics.merge
merge(self, b, a)
Definition
semantics.py:400
GaudiConfig2.semantics.GaudiHandleArraySemantics.store
store(self, value)
Definition
semantics.py:386
GaudiConfig2.semantics.GaudiHandleArraySemantics.__init__
__init__(self, cpp_type)
Definition
semantics.py:382
GaudiConfig2.semantics.GaudiHandleArraySemantics.handle_type
handle_type
Definition
semantics.py:384
GaudiConfig2.semantics.IntSemantics
Definition
semantics.py:211
GaudiConfig2.semantics.IntSemantics.INT_RANGES
dict INT_RANGES
Definition
semantics.py:213
GaudiConfig2.semantics.IntSemantics.store
store(self, value)
Definition
semantics.py:232
GaudiConfig2.semantics.JSONSemantics
Definition
semantics.py:149
GaudiConfig2.semantics.JSONSemantics.opt_value
opt_value(self, value)
Definition
semantics.py:172
GaudiConfig2.semantics.JSONSemantics.load
load(self, value)
Definition
semantics.py:163
GaudiConfig2.semantics.JSONSemantics.store
store(self, value)
Definition
semantics.py:166
GaudiConfig2.semantics.JSONSemantics.is_set
is_set(self, value)
Definition
semantics.py:169
GaudiConfig2.semantics.JSONSemantics.default
default(self, value)
Definition
semantics.py:159
GaudiConfig2.semantics.JSONSemantics._normalize
_normalize(value)
Definition
semantics.py:156
GaudiConfig2.semantics.MappingSemantics
Definition
semantics.py:807
GaudiConfig2.semantics.MappingSemantics.merge
merge(self, a, b)
Definition
semantics.py:845
GaudiConfig2.semantics.MappingSemantics.name
name(self)
Definition
semantics.py:817
GaudiConfig2.semantics.MappingSemantics.key_semantics
key_semantics
Definition
semantics.py:813
GaudiConfig2.semantics.MappingSemantics.__init__
__init__(self, cpp_type)
Definition
semantics.py:810
GaudiConfig2.semantics.MappingSemantics.opt_value
opt_value(self, value)
Definition
semantics.py:837
GaudiConfig2.semantics.MappingSemantics.value_semantics
value_semantics
Definition
semantics.py:814
GaudiConfig2.semantics.MappingSemantics.store
store(self, value)
Definition
semantics.py:826
GaudiConfig2.semantics.MappingSemantics.default
default(self, value)
Definition
semantics.py:832
GaudiConfig2.semantics.OrderedSetSemantics
Definition
semantics.py:711
GaudiConfig2.semantics.OrderedSetSemantics.merge
merge(self, bb, aa)
Definition
semantics.py:727
GaudiConfig2.semantics.OrderedSetSemantics.__init__
__init__(self, cpp_type)
Definition
semantics.py:724
GaudiConfig2.semantics.PropertySemantics
Definition
semantics.py:28
GaudiConfig2.semantics.PropertySemantics._cpp_type
_cpp_type
Definition
semantics.py:60
GaudiConfig2.semantics.PropertySemantics.name
name(self)
Definition
semantics.py:42
GaudiConfig2.semantics.PropertySemantics.load
load(self, value)
Definition
semantics.py:62
GaudiConfig2.semantics.PropertySemantics.opt_value
opt_value(self, value)
Definition
semantics.py:80
GaudiConfig2.semantics.PropertySemantics.__init__
__init__(self, cpp_type)
Definition
semantics.py:37
GaudiConfig2.semantics.PropertySemantics.__handled_types__
tuple __handled_types__
Definition
semantics.py:35
GaudiConfig2.semantics.PropertySemantics.is_set
is_set(self, value)
Definition
semantics.py:74
GaudiConfig2.semantics.PropertySemantics._name
_name
Definition
semantics.py:38
GaudiConfig2.semantics.PropertySemantics.cpp_type
cpp_type
Definition
semantics.py:39
GaudiConfig2.semantics.PropertySemantics.merge
merge(self, a, b)
Definition
semantics.py:88
GaudiConfig2.semantics.PropertySemantics.store
store(self, value)
Definition
semantics.py:68
GaudiConfig2.semantics.SequenceSemantics
Definition
semantics.py:522
GaudiConfig2.semantics.SequenceSemantics.opt_value
opt_value(self, value)
Definition
semantics.py:556
GaudiConfig2.semantics.SequenceSemantics.value_semantics
value_semantics
Definition
semantics.py:527
GaudiConfig2.semantics.SequenceSemantics.default
default(self, value)
Definition
semantics.py:551
GaudiConfig2.semantics.SequenceSemantics.store
store(self, value)
Definition
semantics.py:540
GaudiConfig2.semantics.SequenceSemantics.__init__
__init__(self, cpp_type, valueSem=None)
Definition
semantics.py:525
GaudiConfig2.semantics.SequenceSemantics.name
name(self)
Definition
semantics.py:532
GaudiConfig2.semantics.SetSemantics
Definition
semantics.py:662
GaudiConfig2.semantics.SetSemantics.merge
merge(self, bb, aa)
Definition
semantics.py:706
GaudiConfig2.semantics.SetSemantics.store
store(self, value)
Definition
semantics.py:682
GaudiConfig2.semantics.SetSemantics.value_semantics
value_semantics
Definition
semantics.py:669
GaudiConfig2.semantics.SetSemantics.opt_value
opt_value(self, value)
Definition
semantics.py:698
GaudiConfig2.semantics.SetSemantics.default
default(self, value)
Definition
semantics.py:693
GaudiConfig2.semantics.SetSemantics.__init__
__init__(self, cpp_type, valueSem=None)
Definition
semantics.py:667
GaudiConfig2.semantics.StringSemantics
Definition
semantics.py:182
GaudiConfig2.semantics.StringSemantics.store
store(self, value)
Definition
semantics.py:185
GaudiKernel.DataHandle.DataHandle
Definition
DataHandle.py:14
GaudiKernel.DataHandle.DataHandleVector
Definition
DataHandle.py:81
GaudiConfig2.semantics.getSemanticsFor
getSemanticsFor(cpp_type, strict=False)
Definition
semantics.py:874
GaudiConfig2.semantics.extract_template_args
extract_template_args(cpp_type)
Definition
semantics.py:446
GaudiKernel.DataHandle
Definition
DataHandle.py:1
GaudiKernel.GaudiHandles
Definition
GaudiHandles.py:1
GaudiConfiguration
python
GaudiConfig2
semantics.py
Generated on
for The Gaudi Framework by
1.17.0