-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Reachability check seems to consider isinstance(obj, Hashable) as always True #11799
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The problem is that reveal_type(object.__hash__) # N: Revealed type is "def (self: builtins.object) -> builtins.int" We had this problem and discussion several times before. |
We already have |
I don't know how we can represent this idea in types, but: some But, on the other hand, we know that |
But mypy already correctly errors when a subclass of a class that fulfills a protocol doesn't fulfill it: from typing import Protocol
class X(Protocol):
def foo(self, a: int) -> str:
pass
class A:
def foo(self, a: int) -> str:
return ""
class B(A):
def foo(self) -> str: # type: ignore[override]
return ""
a: X = A()
b: X = B() # E: Incompatible types in assignment (expression has type "B", variable has type "X") Why is |
Looks like we have a bug in mypy 🤔
I will look into it. |
I hope that #11802 will fix it! 🙏 |
When this piece of code was checked: ```python from typing import Awaitable, Hashable, Union, Tuple, List obj: Union[Tuple[int], List[int]] if isinstance(obj, Hashable): reveal_type(obj) ``` Mypy revealed that `Hashable` is `() -> object`. It happened, because [`is_subtype(explicit_type, default_ret_type, ignore_type_params=True)`](https://github.com/python/mypy/blob/56684e43a14e3782409c47e99bb47191d631a3de/mypy/typeops.py#L130) was `True`, where `explicit_type=object` and `default_ret_type=Hashable`. It happened because `object` has `__hash__` method. The only thing that popped out of my head is to simply exclude protocols from this condition. I guess that we might double check protocols with `__new__` and `__init__` to be sure. But, I am not able to think of proper test cases for this. Any ideas? Or is my single test good enough? I am adding `pythoneval` test, because of the complexity in how `Hashable` is defined and analyzed in real life. Closes #11799
Running
mypy --warn-unreachable
(version 0.920) against the following snippet gives a false "unreachable statement" error.We can even exchange the
Union
annotation for a single unhashable type likeList
orDict
, and still get the same unreachable error. Looks likeisinstance(obj, Hashable)
is just consideredTrue
for any type.Is this a mypy bug? Can we add some hints into the example code so that mypy would figure out correct reachability?
The text was updated successfully, but these errors were encountered: