User defined generic types and collections.abc

Martí Congost marticongost at gmail.com
Tue Oct 13 06:17:41 EDT 2015


I have a package that defines a variety of collections based on the ABCs
provided by collections.abc (Mapping, Sequence, etc). I wanted to take
advantage of the type hinting facilities introduced in Python 3.5, and I'm
having doubts as to what would be the best way to go about it.

Lets take one of these classes as an exemple; until now, I had something
resembling this:

  from collections.abc import Mapping

  class MyMapping(Mapping):
    ...

To turn this into a generic type, the documentation (
https://www.python.org/dev/peps/pep-0484/#arbitrary-generic-types-as-base-classes)
would seem to suggest doing something like this:

  from typing import Generic, Hashable, TypeVar, Mapping

  K = TypeVar("K", bound=Hashable)
  V = TypeVar("V")

  class MyMapping(Mapping[K, V]):
      ...

But this poses two problems:

- The class looses all the mixin methods from collections.abc.Mapping. I
could deal with this by implementing them myself, but that would defeat
part of the purpose of using ABCs in the first place.

- isinstance(MyMapping(), collections.abc.Mapping) returns False. Also,
trying to call collections.abc.Mapping.register(MyMapping) to work around
this raises a RuntimeError ("Refusing to create an inheritance cycle").

My first attempt to solve these problems was to go back to extending
collections.abc.Mapping:

  from typing import Generic, Hashable, TypeVar
  from collections.abc import Mapping

  K = TypeVar("K", bound=Hashable)
  V = TypeVar("V")

  class MyMapping(Mapping[K, V]):
      ...

But that doesn't work, as collections.abc.Mapping is not a generic type and
does not support the subscription operator. So I tried this:

from typing import Generic, Hashable, TypeVar, Mapping
from collections.abc import Mapping as MappingABC

  K = TypeVar("K", bound=Hashable)
  V = TypeVar("V")

  class MyMapping(MappingABC, Mapping[K, V]):
      ...

But this smells fishy. The imports and aliasing are cumbersome, the
resulting class has a tortuous MRO, and the mix-in methods provided by the
ABC won't have typing information...

So what is the preferred way to declare a custom generic type based on a
collection ABC?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20151013/83ca3ab3/attachment.html>


More information about the Python-list mailing list