Open
Description
Bug Report
Mypy is unable to narrow the type of a tagged union when deconstructing it using a match
statement.
To Reproduce
from typing import Literal, TypeAlias
Expr: TypeAlias = (
tuple[Literal["const"], int] | tuple[Literal["add"], tuple["Expr", "Expr"]]
)
# OK
def eval(e: Expr) -> int:
if e[0] == "const":
return e[1]
else:
e1, e2 = e[1]
return eval(e1) + eval(e2)
# Rejected by mypy (see errors below)
def eval2(e: Expr) -> int:
match e:
case ("const", x):
return x
case ("add", (e1, e2)):
return eval2(e1) + eval2(e2)
Expected Behavior
Both eval
and eval2
should typecheck.
Actual Behavior
Function eval
typechecks but eval2
does not.
main.py:19: error: Missing return statement [return]
main.py:22: error: Incompatible return value type (got "object", expected "int") [return-value]
main.py:24: error: Argument 1 to "eval2" has incompatible type "object"; expected "Expr" [arg-type]
Found 3 errors in 1 file (checked 1 source file)
Your Environment
- Mypy version used: 1.2.0
- Mypy command-line flags: none
- Mypy configuration options from
mypy.ini
(and other config files): none - Python version used: 3.11