-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Closed as not planned
Labels
bugmypy got something wrongmypy got something wrong
Description
Bug Report
Type narrowing implemented using TypeGuard doesn't appear to propagate information to other branches, unlike with builtin type narrowing like isinstance
.
To Reproduce
from typing import TypeGuard, Any
def is_int(val: Any) -> TypeGuard[int]:
return isinstance(val, int)
def my_function_1(value: str | int) -> str:
if isinstance(value, str):
return value + " hello"
else:
return str(value + 1)
def my_function_2(value: str | int) -> str:
if isinstance(value, int):
return str(value + 1)
else:
return value + " hello"
def my_function_3(value: str | int) -> str:
if is_int(value):
return str(value + 1)
else:
return value + " hello"
Playground link: https://mypy-play.net/?mypy=master&python=3.10&gist=69794cff9fc522309d8ac034d7d595f4
Expected Behavior
I expected my_function_3
to report no errors, just like my_function_1
and my_function_2
. In both those cases, mypy is able to deduce that in the "other" branch, there is only one possible type.
Actual Behavior
mypy reports:
main.py:27: error: Incompatible return value type (got "Union[str, int]", expected "str") [return-value]
main.py:27: error: Unsupported operand types for + ("int" and "str") [operator]
main.py:27: note: Left operand is of type "Union[str, int]"
Found 2 errors in 1 file (checked 1 source file)
That is, while it can deduce that value + 1
has no errors in the is_int()
branch, which shows the type guard is "working", it can't deduce that value
cannot be int
in the other branch.
Tested against 0.982 and master, Python 3.10
Metadata
Metadata
Assignees
Labels
bugmypy got something wrongmypy got something wrong