Closed
Description
Bug Report
Type narrowing does not work correctly in function bodies. Even if the type is narrowed down in the context in which a function or a lambda is defined, that narrowing seems to be 'forgotten' within the function body.
To Reproduce
x: int | None = 1
# Either of these two type checks produces identical results:
if isinstance(x, int):
# if x is not None:
# Revealed type is "builtins.int"
reveal_type(x)
def f() -> int:
# Revealed type is "Union[builtins.int, None]"
reveal_type(x)
# error: Unsupported operand types for + ("None" and "int") [operator]
# note: Left operand is of type "int | None"
# return x + 2
# No errors here:
return 1 + 2
# error: Unsupported operand types for + ("None" and "int") [operator]
# note: Left operand is of type "int | None"
# (lambda: x + 2)()
# No errors here:
(lambda: 1 + 2)()
# However, defining a lambda without calling it does not cause errors:
l = lambda: x + 2
Gist URL: https://gist.github.com/mypy-play/41141b62a73edc56b6561088adea8ebf
Playground URL: https://mypy-play.net/?mypy=latest&python=3.11&flags=strict&gist=41141b62a73edc56b6561088adea8ebf
Expected Behavior
No errors in the lines where errors are actually reported. Type narrowing should make all of these expressions valid.
Actual Behavior
The errors given in the comments.
Your Environment
- Mypy version used: 1.5.1.
- Mypy command-line flags: tested with no flags and
--strict
. - Mypy configuration options from
mypy.ini
(and other config files): None. - Python version used: 3.11.