11 from __future__
import absolute_import
19 from collections.abc
import MutableMapping, MutableSequence
22 from collections
import MutableMapping, MutableSequence
24 if sys.version_info >= (3,):
27 _log = logging.getLogger(__name__)
28 is_64bits = sys.maxsize > 2**32
33 Basic property semantics implementation, with no validation/transformation.
35 Not to be used directly for any actual property, use only specializations.
38 __handled_types__ = ()
51 h.match(value)
if hasattr(h,
"match")
else h == value
54 raise TypeError(
"C++ type {!r} not supported".
format(value))
59 Transformation for data when reading the property.
65 Validation/transformation of the data to be stored.
71 Allow overriding the definition of "is set" if we need helper types.
77 Option string version of value.
79 if hasattr(value,
"__opt_value__"):
80 return value.__opt_value__()
87 Used when merging two Configurable instances, by default just ensure
88 the two values do not conflict, but it can be overridden in
89 derived semantics to, for example, append to the two lists.
92 raise ValueError(
"cannot merge values %r and %r" % (a, b))
98 Special semantics that makes a deep copy of the default value on first access
99 and considers a property set if its value is different from the default.
101 This semantics is meant to be used whenever there is no specific semantic
102 (with proper change detection) implemented for a type.
105 __handled_types__ = (re.compile(
r".*"),)
111 return copy.deepcopy(value)
116 return super(DefaultSemantics, self).
store(value)
122 except AttributeError:
130 __handled_types__ = (
"std::string",)
133 if not isinstance(value, basestring):
134 raise ValueError(
"cannot set property {} to {!r}".
format(self.
name, value))
139 __handled_types__ = (
"bool",)
146 __handled_types__ = (
"float",
"double")
149 from numbers
import Number
151 if not isinstance(value, Number):
153 "number expected, got {!r} in assignemnt to {}".
format(value, self.
name)
161 "signed char": (-128, 127),
162 "short": (-32768, 32767),
163 "int": (-2147483648, 2147483647),
165 (-9223372036854775808, 9223372036854775807)
167 else (-2147483648, 2147483647)
169 "long long": (-9223372036854775808, 9223372036854775807),
170 "unsigned char": (0, 255),
171 "unsigned short": (0, 65535),
172 "unsigned int": (0, 4294967295),
173 "unsigned long": (0, 18446744073709551615
if is_64bits
else 4294967295),
174 "unsigned long long": (0, 18446744073709551615),
177 __handled_types__ = tuple(INT_RANGES)
180 from numbers
import Number
182 if not isinstance(value, Number):
184 "number expected, got {!r} in assignemnt to {}".
format(value, self.
name)
188 _log.warning(
"converted %s to %d in assignment to %s", value, v, self.
name)
190 if v < min_value
or v > max_value:
192 "value {} outside limits for {!r} {}".
format(
199 _IDENTIFIER_RE =
r"[a-zA-Z_][a-zA-Z0-9_]*"
200 _NS_IDENT_RE =
r"{ident}(::{ident})*".
format(ident=_IDENTIFIER_RE)
201 _COMMA_SEPARATION_RE =
r"{exp}(,{exp})*"
205 __handled_types__ = (
209 r"AlgTool(:{})?$".
format(_COMMA_SEPARATION_RE.format(exp=_NS_IDENT_RE))
212 r"Service(:{})?$".
format(_COMMA_SEPARATION_RE.format(exp=_NS_IDENT_RE))
217 super(ComponentSemantics, self).
__init__(cpp_type, name)
226 from .
import Configurable, Configurables
228 if isinstance(value, Configurable):
230 elif isinstance(value, basestring):
232 if value
in Configurable.instances:
233 value = Configurable.instances[value]
237 t, n = value.split(
"/")
240 value = Configurables.getByType(t).getInstance(n)
243 "cannot assign {!r} to {!r}, requested string or {!r}".
format(
247 if value.__component_type__ != self.
cpp_type:
249 "wrong type for {!r}: expected {!r}, got {!r}".
format(
255 if value.__interfaces__:
256 if not self.
interfaces.issubset(value.__interfaces__):
258 "wrong interfaces for {!r}: required {}".
format(
262 except AttributeError:
267 return self.
store(value)
272 Return an iterator over the list of template arguments in a C++ type
275 >>> t = 'map<string, vector<int, allocator<int> >, allocator<v<i>, a<i>> >'
276 >>> list(extract_template_args(t))
277 ['string', 'vector<int, allocator<int> >', 'allocator<v<i>, a<i>>']
278 >>> list(extract_template_args('int'))
283 for p, c
in enumerate(cpp_type):
285 if template_level == 1:
286 yield cpp_type[arg_start:p].strip()
290 if template_level == 1:
294 if template_level == 0:
295 yield cpp_type[arg_start:p].strip()
310 return len(self.
data)
321 raise RuntimeError(
"cannot remove elements from the default value")
328 return self.
data != other.data
346 return repr(self.
data)
350 __handled_types__ = (re.compile(
r"(std::)?(vector|list)<.*>$"),)
352 def __init__(self, cpp_type, name=None, valueSem=None):
353 super(SequenceSemantics, self).
__init__(cpp_type, name)
360 new_value.extend(value)
365 new_value.default = value
370 Option string version of value.
372 if not isinstance(value, _ListHelper):
374 return value.opt_value()
379 Extend the sequence-semantics with a merge-method to behave like a
380 OrderedSet: Values are unique but the order is maintained.
381 Use 'OrderedSet<T>' as fifth parameter of the Gaudi::Property<T> constructor
382 to invoke this merging method. Also applies to std::[unordered_]set.
385 __handled_types__ = (
386 re.compile(
r"(std::)?(unordered_)?set<.*>$"),
387 re.compile(
r"^OrderedSet<.*>$"),
391 super(OrderedSetSemantics, self).
__init__(cpp_type, name)
401 def __init__(self, key_semantics, value_semantics):
413 return len(self.
data)
428 raise RuntimeError(
"cannot remove elements from the default value")
432 for key
in self.
data:
449 def get(self, key, default=None):
460 for key, value
in otherMap.items():
470 return repr(self.
data)
474 __handled_types__ = (re.compile(
r"(std::)?(unordered_)?map<.*>$"),)
477 super(MappingSemantics, self).
__init__(cpp_type, name)
484 new_value.update(value)
489 new_value.default = value
494 Option string version of value.
496 if not isinstance(value, _DictHelper):
498 return value.opt_value()
503 for c
in globals().values()
504 if isinstance(c, type)
505 and issubclass(c, PropertySemantics)
506 and c
not in (PropertySemantics, DefaultSemantics)
511 for semantics
in SEMANTICS:
513 return semantics(cpp_type, name)