-
-
Notifications
You must be signed in to change notification settings - Fork 34.3k
Cannot use multiple inheritance with collections.abc.Buffer and typing.Protocol #104797
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
| _PROTO_ALLOWLIST = { | |
| 'collections.abc': [ | |
| 'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable', | |
| 'Hashable', 'Sized', 'Container', 'Collection', 'Reversible', | |
| ], | |
| 'contextlib': ['AbstractContextManager', 'AbstractAsyncContextManager'], | |
| } |
Cc. @JelleZijlstra for PEP-688