15 from collections.abc
import MutableMapping, MutableSequence, MutableSet
17 _log = logging.getLogger(__name__)
18 is_64bits = sys.maxsize > 2**32
23 Basic property semantics implementation, with no validation/transformation.
25 Not to be used directly for any actual property, use only specializations.
28 __handled_types__ = ()
49 h.match(value)
if hasattr(h,
"match")
else h == value
52 raise TypeError(
"C++ type {!r} not supported".
format(value))
57 Transformation for data when reading the property.
63 Validation/transformation of the data to be stored.
69 Allow overriding the definition of "is set" if we need helper types.
75 Option string version of value.
77 if hasattr(value,
"__opt_value__"):
78 return value.__opt_value__()
85 Used when merging two Configurable instances, by default just ensure
86 the two values do not conflict, but it can be overridden in
87 derived semantics to, for example, append to the two lists.
90 raise ValueError(
"cannot merge values %r and %r" % (a, b))
96 Special semantics that makes a deep copy of the default value on first access
97 and considers a property set if its value is different from the default.
99 This semantics is meant to be used whenever there is no specific semantic
100 (with proper change detection) implemented for a type.
103 __handled_types__ = (re.compile(
r".*"),)
109 return copy.deepcopy(value)
114 return super(DefaultSemantics, self).
store(value)
120 except AttributeError:
128 __handled_types__ = (
"std::string",)
131 if not isinstance(value, str):
132 raise TypeError(
"cannot set property {} to {!r}".
format(self.
name, value))
137 __handled_types__ = (
"bool",)
144 __handled_types__ = (
"float",
"double")
147 from numbers
import Number
149 if not isinstance(value, Number):
151 "number expected, got {!r} in assignment to {}".
format(value, self.
name)
159 "signed char": (-128, 127),
160 "short": (-32768, 32767),
161 "int": (-2147483648, 2147483647),
163 (-9223372036854775808, 9223372036854775807)
165 else (-2147483648, 2147483647)
167 "long long": (-9223372036854775808, 9223372036854775807),
168 "unsigned char": (0, 255),
169 "unsigned short": (0, 65535),
170 "unsigned int": (0, 4294967295),
171 "unsigned long": (0, 18446744073709551615
if is_64bits
else 4294967295),
172 "unsigned long long": (0, 18446744073709551615),
175 __handled_types__ = tuple(INT_RANGES)
178 from numbers
import Number
180 if not isinstance(value, Number):
182 "number expected, got {!r} in assignment to {}".
format(value, self.
name)
186 _log.warning(
"converted %s to %d in assignment to %s", value, v, self.
name)
188 if v < min_value
or v > max_value:
190 "value {} outside limits for {!r} {}".
format(
197 _IDENTIFIER_RE =
r"[a-zA-Z_][a-zA-Z0-9_]*"
198 _NS_IDENT_RE =
r"{ident}(::{ident})*".
format(ident=_IDENTIFIER_RE)
199 _COMMA_SEPARATION_RE =
r"{exp}(,{exp})*"
203 __handled_types__ = (
207 r"AlgTool(:{})?$".
format(_COMMA_SEPARATION_RE.format(exp=_NS_IDENT_RE))
210 r"Service(:{})?$".
format(_COMMA_SEPARATION_RE.format(exp=_NS_IDENT_RE))
215 super(ComponentSemantics, self).
__init__(cpp_type)
224 from .
import Configurable, Configurables
226 if isinstance(value, Configurable):
228 elif isinstance(value, str):
230 if value
in Configurable.instances:
231 value = Configurable.instances[value]
235 t, n = value.split(
"/")
238 value = Configurables.getByType(t).getInstance(n)
241 "cannot assign {!r} to {!r}, requested string or {!r}".
format(
245 if value.__component_type__ != self.
cpp_type:
247 "wrong type for {!r}: expected {!r}, got {!r}".
format(
253 if value.__interfaces__:
254 if not self.
interfaces.issubset(value.__interfaces__):
256 "wrong interfaces for {!r}: required {}".
format(
260 except AttributeError:
265 return self.
store(value)
270 Return an iterator over the list of template arguments in a C++ type
273 >>> t = 'map<string, vector<int, allocator<int> >, allocator<v<i>, a<i>> >'
274 >>> list(extract_template_args(t))
275 ['string', 'vector<int, allocator<int> >', 'allocator<v<i>, a<i>>']
276 >>> list(extract_template_args('int'))
281 for p, c
in enumerate(cpp_type):
283 if template_level == 1:
284 yield cpp_type[arg_start:p].strip()
288 if template_level == 1:
292 if template_level == 0:
293 yield cpp_type[arg_start:p].strip()
308 return len(self.
data)
319 raise RuntimeError(
"cannot remove elements from the default value")
341 return repr(self.
data)
345 __handled_types__ = (re.compile(
r"(std::)?(vector|list)<.*>$"),)
348 super(SequenceSemantics, self).
__init__(cpp_type)
363 if not isinstance(value, (list, _ListHelper, tuple)):
365 "list or tuple expected, got {!r} in assignment to {}".
format(
370 new_value.extend(value)
375 new_value.default = value
380 Option string version of value.
382 if not isinstance(value, _ListHelper):
384 return value.opt_value()
395 union = MutableSet.__ior__
396 update = MutableSet.__ior__
397 intersection = MutableSet.__iand__
398 difference = MutableSet.__isub__
399 symmetric_difference = MutableSet.__ixor__
406 return len(self.
data)
415 for value
in self.
data:
424 raise RuntimeError(
"cannot remove elements from the default value")
429 raise RuntimeError(
"cannot remove elements from the default value")
438 return "{" + repr(sorted(self.
data))[1:-1] +
"}"
444 """Merge semantics for (unordered) sets."""
446 __handled_types__ = (re.compile(
r"(std::)?unordered_set<.*>$"),)
449 super(SetSemantics, self).
__init__(cpp_type)
465 if not isinstance(value, (set, _SetHelper, list, _ListHelper)):
467 "set expected, got {!r} in assignment to {}".
format(value, self.
name)
476 new_value.default = value
481 Option string version of value.
483 if not isinstance(value, _SetHelper):
485 return value.opt_value()
494 Extend the sequence-semantics with a merge-method to behave like a
495 OrderedSet: Values are unique but the order is maintained.
496 Use 'OrderedSet<T>' as fifth parameter of the Gaudi::Property<T> constructor
497 to invoke this merging method. Also applies to std::set.
500 __handled_types__ = (
501 re.compile(
r"(std::)?set<.*>$"),
502 re.compile(
r"^OrderedSet<.*>$"),
506 super(OrderedSetSemantics, self).
__init__(cpp_type)
516 def __init__(self, key_semantics, value_semantics):
528 return len(self.
data)
543 raise RuntimeError(
"cannot remove elements from the default value")
547 for key
in self.
data:
564 def get(self, key, default=None):
575 for key, value
in otherMap.items():
585 return repr(self.
data)
589 __handled_types__ = (re.compile(
r"(std::)?(unordered_)?map<.*>$"),)
592 super(MappingSemantics, self).
__init__(cpp_type)
610 new_value.update(value)
615 new_value.default = value
620 Option string version of value.
622 if not isinstance(value, _DictHelper):
624 return value.opt_value()
629 for c
in globals().values()
630 if isinstance(c, type)
631 and issubclass(c, PropertySemantics)
632 and c
not in (PropertySemantics, DefaultSemantics)
637 for semantics
in SEMANTICS:
639 return semantics(cpp_type)