Open
Description
Bug Report
When using if-statements, the type is being properly narrowed depending on the conditions checked. mypy seems unable to do the same type of narrowing in a match statement
To Reproduce
https://mypy-play.net/?mypy=latest&python=3.12&gist=eb4da8b4996d740af15df17b231e0527
from typing import Literal, TypeAlias
Expr: TypeAlias = (
tuple[Literal['lit'], int] |
tuple[Literal['var'], str]
)
def square_lits(expr: Expr) -> Expr:
match expr:
case ('lit', x):
return ('lit', square(x))
case _:
return expr
def square(x: int) -> int:
return x * x
Here I get an error:
test.py:11: error: Argument 1 to "square" has incompatible type "int | str"; expected "int" [arg-type]
Found 1 error in 1 file (checked 1 source file)
While the following works fine:
https://mypy-play.net/?mypy=latest&python=3.12&gist=ab7f28a259a5bff450413ce2f2924e74
from typing import Literal, TypeAlias
Expr: TypeAlias = (
tuple[Literal['lit'], int] |
tuple[Literal['var'], str]
)
def square_lits(expr: Expr) -> Expr:
if expr[0] == 'lit':
return ('lit', square(expr[1]))
return expr
def square(x: int) -> int:
return x * x
Expected Behavior
Both examples should work fine without any typechecking errors
Actual Behavior
Mypy is not able to narrow the type in the match statement case like it is able to when using if-conditions
Your Environment
The mypy playground links (mypy version 1.11.0, Python version 3.12).
Related: