I have tried the obvious way to check my protocol:
from typing import Any, Protocol, runtime_checkable
@runtime_checkable
class SupportsComparison(Protocol):
def __eq__(self, other: Any) -> bool:
...
issubclass(int, SupportsComparison)
Unfortunately the issubclass()
call ends with an exception (Python 3.10.6 in Ubuntu 22.04):
$ python3.10 protocol_test.py
Traceback (most recent call last):
File "protocol_test.py", line 8, in <module>
issubclass(object, SupportsComparison)
File "/usr/lib/python3.10/abc.py", line 123, in __subclasscheck__
return _abc_subclasscheck(cls, subclass)
File "/usr/lib/python3.10/typing.py", line 1570, in _proto_hook
raise TypeError("Protocols with non-method members"
TypeError: Protocols with non-method members don't support issubclass()
As you can see I added no non-method members to SupportsComparison
. Is this a bug in the standard library?
From the documentation:
A class that overrides
__eq__()
and does not define__hash__()
will have its__hash__()
implicitly set toNone
.
Therefore, in your case, you have the implicit non-method member SupportsComparison.__hash__ = None
. You can fix it by declaring __hash__
explicitly:
from typing import Any, Protocol, runtime_checkable
@runtime_checkable
class SupportsComparison(Protocol):
def __eq__(self, other: Any) -> bool:
...
def __hash__(self) -> int:
...
issubclass(int, SupportsComparison)