Skip to content

Unable to narrow the type of a tagged union when using a match statement #15190

Description

@jonathan-laurent

Bug Report

Mypy is unable to narrow the type of a tagged union when deconstructing it using a match statement.

To Reproduce

fromtypingimportLiteral, TypeAliasExpr: TypeAlias= (
tuple[Literal["const"], int] |tuple[Literal["add"], tuple["Expr", "Expr"]]
)
# OKdefeval(e: Expr) ->int:
ife[0] =="const":
returne[1]
else:
e1, e2=e[1]
returneval(e1) +eval(e2)
# Rejected by mypy (see errors below)defeval2(e: Expr) ->int:
matche:
case ("const", x):
returnxcase ("add", (e1, e2)):
returneval2(e1) +eval2(e2)

Expected Behavior

Both eval and eval2 should typecheck.

Actual Behavior

Function eval typechecks but eval2 does not.

Mypy playground link

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions