15 from collections.abc
import MutableMapping, MutableSequence
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 assignemnt 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, name)
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)<.*>$"),)
347 def __init__(self, cpp_type, name=None, valueSem=None):
348 super(SequenceSemantics, self).
__init__(cpp_type, name)
365 new_value.extend(value)
370 new_value.default = value
375 Option string version of value.
377 if not isinstance(value, _ListHelper):
379 return value.opt_value()
384 Extend the sequence-semantics with a merge-method to behave like a
385 OrderedSet: Values are unique but the order is maintained.
386 Use 'OrderedSet<T>' as fifth parameter of the Gaudi::Property<T> constructor
387 to invoke this merging method. Also applies to std::[unordered_]set.
390 __handled_types__ = (
391 re.compile(
r"(std::)?(unordered_)?set<.*>$"),
392 re.compile(
r"^OrderedSet<.*>$"),
396 super(OrderedSetSemantics, self).
__init__(cpp_type, name)
406 def __init__(self, key_semantics, value_semantics):
418 return len(self.
data)
433 raise RuntimeError(
"cannot remove elements from the default value")
437 for key
in self.
data:
454 def get(self, key, default=None):
465 for key, value
in otherMap.items():
475 return repr(self.
data)
479 __handled_types__ = (re.compile(
r"(std::)?(unordered_)?map<.*>$"),)
482 super(MappingSemantics, self).
__init__(cpp_type, name)
501 new_value.update(value)
506 new_value.default = value
511 Option string version of value.
513 if not isinstance(value, _DictHelper):
515 return value.opt_value()
520 for c
in globals().values()
521 if isinstance(c, type)
522 and issubclass(c, PropertySemantics)
523 and c
not in (PropertySemantics, DefaultSemantics)
528 for semantics
in SEMANTICS:
530 return semantics(cpp_type, name)