typeshed
typeshed copied to clipboard
Explicitly mark subclasses of collections.abc protocols as abstract base classes
There are a few types in collection.abc
that subclass protocols but are not protocols themselves. For example Sequence
is a subclass of Collection
and Reversible
. It expects subclasses to implement __getitem__
and __len__
, the latter being a requirement of the Collection
protocol. I think that the stubs for these classes should explicitly subclass abc.ABC
so that typecheckers require implementation of all abstract methods when the @final
annotation is used.
Currently typecheckers disagree on how to handle these stubs. For this example mypy asks for __getitem__
and __len__
implementations and pyright throws no error:
from collections.abc import Sequence
from typing import final
@final
class Foo(Sequence[int]):
pass
bash-3.2$ mypy test.py
test.py:5: error: Final class test.Foo has abstract attributes "__getitem__", "__len__" [misc]
Found 1 error in 1 file (checked 1 source file)
bash-3.2$ pyright test.py
0 errors, 0 warnings, 0 informations
At runtime the types in collections.abc
are already abstract base classes:
>>> from collections.abc import Sequence
>>> Sequence.__class__
<class 'abc.ABCMeta'>
This sounds like something we would have tried before and didn't do for one reason or another. Possibly because we also mark some of the classes as protocols, and that might not interact well with ABCMeta
. That said, as we strive to follow the implementation if possible, I agree that this something we should at least try do to – or at least document in the stubs why we don't do it.
Exploratory PR welcome, unless someone else knows why didn't do it before.
There's a note in PEP-544 about this that to me sounds like marking all the non-protocol collection.abc
classes as ABCs in the stubs would be a good solution. I'll submit a PR doing that a little later today.
Subclassing a protocol class would not turn the subclass into a protocol unless it also has typing.Protocol as an explicit base class. Without this base, the class is “downgraded” to a regular ABC that cannot be used with structural subtyping.