How to correctly implement the mapping protocol in Python?

The collections.abc module defines the interfaces for things like Mapping, Sequence, and so on.

By inheriting from the abstract base classes in that module, you get default implementations of some of the methods. So to be considered a Mapping, your class definition should look something like this:

class MyMapping(collections.abc.Mapping):
    def __getitem__(self, key):
        pass
    def __iter__(self):
        pass
    def __len__(self):
        pass

Inheriting from Mapping will get you ‘free’ implementations of most of dict‘s useful methods:

  • __contains__
  • keys
  • items
  • values
  • get
  • __eq__
  • __ne__

If these default method implementations are inefficient with your custom data structure, you can always override them with your own versions.


To be considered a MutableMapping, your class’s interface should look like this:

class MyMutableMapping(collections.abc.MutableMapping):
    def __getitem__(self, key):
        pass
    def __setitem__(self, key, item):
        pass
    def __delitem__(self, key):
        pass
    def __iter__(self):
        pass
    def __len__(self):
        pass

Inheriting from MutableMapping gets you ‘free’ definitions of all of Mapping‘s methods, plus:

  • pop
  • popitem
  • clear
  • update
  • setdefault

If you’re ‘rolling your own’ from scratch and don’t want to use an abstract base class, you should probably try to define all of the above methods, if you want your class to be strictly Liskov-substitutable for dict.

Leave a Comment