__delitem__ = __setitem__ = __setattr__ = _immutable
clear = pop = popitem = setdefault = update = _immutable
+
cdef class immutabledict(dict):
def __repr__(self):
return f"immutabledict({dict.__repr__(self)})"
_immutable_fn(self)
def __or__(self, other):
- return immutabledict(super().__or__(other))
+ return immutabledict(dict.__or__(self, other))
def __ror__(self, other):
- return immutabledict(super().__ror__(other))
+ # NOTE: this is used only in cython 3.x;
+ # version 0.x will call __or__ with args inversed
+ return immutabledict(dict.__ror__(self, other))
from typing import Union
_T = TypeVar("_T", bound=Any)
+_S = TypeVar("_S", bound=Any)
_KT = TypeVar("_KT", bound=Any)
_VT = TypeVar("_VT", bound=Any)
def __repr__(self) -> str:
return "immutabledict(%s)" % dict.__repr__(self)
+ # PEP 584
+ def __ior__(self, __value: Any) -> NoReturn: # type: ignore
+ self._readonly()
-_S = TypeVar("_S", bound=Any)
+ def __or__( # type: ignore[override]
+ self, __value: Mapping[_KT, _VT]
+ ) -> immutabledict[_KT, _VT]:
+ return immutabledict(super().__or__(__value))
+
+ def __ror__( # type: ignore[override]
+ self, __value: Mapping[_KT, _VT]
+ ) -> immutabledict[_KT, _VT]:
+ return immutabledict(super().__ror__(__value))
class OrderedSet(Set[_T]):
i2 = util.immutabledict({"a": 42, 42: "a"})
eq_(str(i2), "immutabledict({'a': 42, 42: 'a'})")
+ @testing.requires.python39
+ def test_pep584(self):
+ i = util.immutabledict({"a": 2})
+ with expect_raises_message(TypeError, "object is immutable"):
+ i |= {"b": 42}
+ eq_(i, {"a": 2})
+
+ i2 = i | {"x": 3}
+ eq_(i, {"a": 2})
+ eq_(i2, {"a": 2, "x": 3})
+ is_true(isinstance(i2, util.immutabledict))
+
+ i2 = {"x": 3} | i2
+ eq_(i, {"a": 2})
+ eq_(i2, {"a": 2, "x": 3})
+ is_true(isinstance(i2, util.immutabledict))
+
class ImmutableTest(fixtures.TestBase):
@combinations(util.immutabledict({1: 2, 3: 4}), util.FacadeDict({2: 3}))