ImmutableDict implementation doesn't call __setitem__

25 views Asked by At

In the code below I create a class ImmutableDict that appears to have a __setitem__ implementation that should throw an exception, but it doesn't. Why not?

from typing import Mapping, TypeVar

KT = TypeVar('KT')
VT_co = TypeVar('VT_co', covariant=True)

class Immutable:
    def __init__(self, *args, **kwargs):
        super(Immutable, self).__init__(*args, **kwargs)
        # set them all to self.raise_immutable
        self.__setitem__ = self.__delitem__ = self.setdefault = self.update = self.pop = self.popitem = self.clear = self.raise_immutable

    def raise_immutable(self, *args, **kwargs):
        clsname = self.__class__.__name__
        raise TypeError(f"{clsname} objects are immutable")

    def __repr__(self):
        clsname = self.__class__.__name__
        content = super(Immutable, self).__repr__()
        return f"{clsname}({content}"

class ImmutableDict(Immutable, dict, Mapping[KT, VT_co]):
    def __hash__(self):
        return hash(tuple(self.items()))

i = ImmutableDict({'a':1})
print(i)  # ImmutableDict({'a': 1})
print(i.__setitem__)  # <bound method Immutable.raise_immutable of ImmutableDict({'a': 1})>
# i.__setitem__('b', 2)  # this throws an exception as desired
i['b'] = 2  # but yet this works?
print(i)  # ImmutableDict({'a': 1, 'b': 2})
0

There are 0 answers