'Why is typing.Mapping not a Protocol?

As described here, some built-in generic types are Protocols. This means that as long as they implement certain methods, type-checkers will mark them as being compatible with the type:

If a class defines a suitable __iter__ method, mypy understands that it implements the iterable protocol and is compatible with Iterable[T].

So why is Mapping not a protocol?

It clearly feels like it should be one, as evidenced by this well up-voted SO answer:

typing.Mapping is an object which defines the __getitem__,__len__,__iter__ magic methods

If it were one, I could pass things which behave like mappings into function which require a mapping, but doing that is not allowed:

from typing import Mapping


class IntMapping:

    def __init__(self):
        self._int_map = {}

    def __repr__(self):
        return repr(self._int_map)

    def __setitem__(self, key: int, value: int):
        self._int_map[key] = value

    def __getitem__(self, key: int):
        return self._int_map[key]

    def __len__(self):
        return len(self._int_map)

    def __iter__(self):
        return iter(self._int_map)

    def __contains__(self, item: int):
        return item in self._int_map

    def keys(self):
        return self._int_map.keys()

    def items(self):
        return self._int_map.items()

    def values(self):
        return self._int_map.values()

    def get(self, key: int, default: int) -> int:
        return self._int_map.get(key, default)

    def __eq__(self, other):
        return self == other

    def __ne__(self, other):
        return self != other


x: Mapping = IntMapping()  # Type checkers don't like this

Shout-out to this answer for pointing me to the link about protocols)



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source