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)