22 __all__ = [
"GenericMap",
"MutableGenericMap"]
24 from collections.abc
import Mapping, MutableMapping
27 from ._typehandling
import GenericMapS, MutableGenericMapS
31 """An abstract `~collections.abc.Mapping` for use when sharing a
32 map between C++ and Python.
34 For compatibility with C++, ``GenericMap`` has the following
37 - all keys must be of the same type
38 - values must be built-in types or subclasses of
39 `lsst.afw.typehandling.Storable`. Almost any user-defined class in
40 C++ or Python can have `~lsst.afw.typehandling.Storable` as a mixin.
42 As a safety precaution, `~lsst.afw.typehandling.Storable` objects that are
43 added from C++ may be copied when you retrieve them from Python, making it
44 impossible to modify them in-place. This issue does not affect objects that
45 are added from Python, or objects that are always passed by
46 :cpp:class:`shared_ptr` in C++.
50 className =
type(self).__name__
51 return className +
"({" +
", ".join(
"%r: %r" % (key, value)
for key, value
in self.
items()) +
"})"
56 if len(self) != len(other):
59 for key, value
in self.
items():
61 if (value != other[key]):
69 values = Mapping.values
73 GenericMap.register(str, GenericMapS)
74 Mapping.register(GenericMapS)
78 """An abstract `~collections.abc.MutableMapping` for use when sharing a
79 map between C++ and Python.
81 For compatibility with C++, ``MutableGenericMap`` has the following
84 - all keys must be of the same type
85 - values must be built-in types or subclasses of
86 `lsst.afw.typehandling.Storable`. Almost any user-defined class in
87 C++ or Python can have `~lsst.afw.typehandling.Storable` as a mixin.
89 As a safety precaution, `~lsst.afw.typehandling.Storable` objects that are
90 added from C++ may be copied when you retrieve them from Python, making it
91 impossible to modify them in-place. This issue does not affect objects that
92 are added from Python, or objects that are always passed by
93 :cpp:class:`shared_ptr` in C++.
97 Key-type specializations of ``MutableGenericMap`` are available as, e.g.,
98 ``MutableGenericMap[str]``.
102 setdefault = MutableMapping.setdefault
103 update = MutableMapping.update
106 def pop(self, key, default=None):
112 if default
is not None:
118 MutableGenericMap.register(str, MutableGenericMapS)
119 MutableMapping.register(MutableGenericMapS)
123 """A metaclass for abstract mappings whose key type is implied by their
124 constructor arguments.
126 This metaclass requires that the mapping have a `dict`-like constructor,
127 i.e., it takes a mapping or an iterable of key-value pairs as its first
128 positional parameter.
130 This class differs from `~lsst.utils.TemplateMeta` only in that the dtype
131 (or equivalent) constructor keyword is optional. If it is omitted, the
132 class will attempt to infer it from the first argument.
136 if len(cls.TEMPLATE_PARAMS) != 1:
137 raise ValueError(
"AutoKeyMeta requires exactly one template parameter")
138 dtypeKey = cls.TEMPLATE_PARAMS[0]
139 dtype = kwargs.get(dtypeKey,
None)
142 if dtype
is None and len(args) >= 1:
144 if dtype
is not None:
145 kwargs[dtypeKey] = dtype
147 return super().
__call__(*args, **kwargs)
149 def _guessKeyType(cls, inputData):
150 """Try to infer the key type of a map from its input.
154 inputData : `~collections.abc.Mapping` or iterable of pairs
155 Any object that can be passed to a `dict`-like constructor. Keys
156 are assumed homogeneous (if not, a
157 `~lsst.afw.typehandling.GenericMap` constructor will raise
158 `TypeError` no matter what key type, if any, is provided).
163 The type of the keys in ``inputData``, or `None` if the type could
168 if isinstance(inputData, Mapping):
170 firstKey =
iter(inputData.keys()).__next__()
171 elif not isinstance(inputData, str):
174 firstKey =
iter(inputData).__next__()[0]
179 return type(firstKey)