Description
Various stdlib classes are treated as protocols by type checkers, but are actually ABCs at runtime (for performance reasons). Examples include contextlib.AbstractContextManager
and collections.abc.Iterable
. These classes are special-cased in typing.py
to allow for multiple inheritance with typing.Protocol
, so that the interface can be extended:
>>> from contextlib import AbstractContextManager
>>> from typing import Protocol
>>> class Foo(AbstractContextManager, Protocol):
... def extra_method(self) -> None: ...
...
>>>
collections.abc.Buffer
is a new-in-3.12 class that, like AbstractContextManager
and Iterable
, is an ABC at runtime but will be treated by type checkers as if it were a Protocol
. However, multiple inheritance with collections.abc.Buffer
and typing.Protocol
currently fails:
>>> class Bar(Buffer, Protocol):
... def extra_method(self) -> None: ...
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\alexw\coding\cpython\Lib\abc.py", line 106, in __new__
cls = super().__new__(mcls, name, bases, namespace, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\alexw\coding\cpython\Lib\typing.py", line 1916, in __init_subclass__
raise TypeError('Protocols can only inherit from other'
TypeError: Protocols can only inherit from other protocols, got <class 'collections.abc.Buffer'>
I think Buffer
should be special-cased in the same way as Buffer
and Iterable
. It needs to be added to this mapping, I think:
Lines 1740 to 1746 in ddb1485
Cc. @JelleZijlstra for PEP-688