-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Open
Labels
bugmypy got something wrongmypy got something wrongtopic-protocolstopic-reachabilityDetecting unreachable codeDetecting unreachable codetopic-type-narrowingConditional type narrowing / binderConditional type narrowing / binder
Description
Bug Report
If Y is a runtime-checkable protocol which is not implemented by the class X, then mypy will erroneously consider the print statement in the following to be unreachable:
def f(x: Optional[X]) -> None:
if isinstance(x, Y):
print(x.bar())This is incorrect, because x may be an object created from a subclass of X which does implement Y.
If x is annotated as X (not Optional[X]), then mypy behaves correctly.
To Reproduce
Save the following source code to a file (called foo.py below).
from typing import Optional, Protocol, runtime_checkable
from typing_extensions import reveal_type
class X:
def foo(self) -> int:
...
@runtime_checkable
class Y(Protocol):
def bar(self) -> int:
...
class Z(X):
def foo(self) -> int:
return 5
def bar(self) -> int:
return 6
def f(x: Optional[X]) -> None:
reveal_type(x)
if isinstance(x, Y):
reveal_type(x)
print(x.bar())
def g(x: X) -> None:
reveal_type(x)
if isinstance(x, Y):
reveal_type(x)
print(x.bar())
f(Z())
g(Z())Run mypy on it with --warn-unreachable
Expected Behavior
> mypy --warn-unreachable foo.py
foo.py:25: note: Revealed type is "Union[foo.X, None]"
foo.py:27: note: Revealed type is "foo.<subclass of "X" and "Y">1"
foo.py:32: note: Revealed type is "foo.X"
foo.py:34: note: Revealed type is "foo.<subclass of "X" and "Y">1"
Success: no issues found in 1 source file
Actual Behavior
> mypy --warn-unreachable foo.py
foo.py:25: note: Revealed type is "Union[foo.X, None]"
foo.py:27: error: Statement is unreachable
foo.py:32: note: Revealed type is "foo.X"
foo.py:34: note: Revealed type is "foo.<subclass of "X" and "Y">1"
Found 1 error in 1 file (checked 1 source file)
(Running the script demonstrates that there is no actual unreachable code at runtime.)
Your Environment
- Mypy version used:
mypy 0.950 (compiled: yes) - Mypy command-line flags:
--warn-unreachable - Mypy configuration options from
mypy.ini(and other config files): None - Python version used:
Python 3.10.4 - Operating system and version:
Edition Windows 10 Business
Version 21H1
Installed on 2.8.2021
OS build 19043.1706
Experience Windows Feature Experience Pack 120.2212.4170.0
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugmypy got something wrongmypy got something wrongtopic-protocolstopic-reachabilityDetecting unreachable codeDetecting unreachable codetopic-type-narrowingConditional type narrowing / binderConditional type narrowing / binder