'Properly backporting generic collections

In Python 3.9 it is now possible to use collections.abc with generics, meaning code such as this is possible:

import collections.abc
from typing import TypeVar

T = TypeVar("T")


class MySequence(collections.abc.Sequence[T]):
    ...

In Python 3.8, however, this is not possible. Instead, one must use the typing module for generics. I'm wondering what the proper way to go about this is. Right now I'm doing the following:

import sys
from typing import TypeVar

T = TypeVar("T")

if sys.version_info < (3, 9):
    import collections.abc, typing

    class ABC_Sequence(collections.abc.Sequence, typing.Sequence[T]):
        pass

else:
    from collections.abc import Sequence as ABC_Sequence


class MySequence(ABC_Sequence[T]):
    ...

Is this the proper way to go about it?



Solution 1:[1]

It seems some linters such as mypy do not like the above code. In particular, mypy complains that duplicate base classes are used even though collections.abc.Sequence is not the same as typing.Sequence. It seems the correct fix is to actually subclass typing.Sequence for lower versions.

import collections.abc
import sys

if sys.version_info < (3, 9):
    from typing import Sequence
else:
    from collections.abc import Sequence


class MySequence(Sequence[T]):
    ...


# For `isinstance` checks at runtime.
if sys.version_info < (3, 9):
    collections.abc.Sequence.register(MySequence)

Sources

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

Source: Stack Overflow

Solution Source
Solution 1 Simply Beautiful Art