Skip to content

match-case does not work correctly with Literals vs Enums #20142

Description

@randolf-scholz
fromenumimportStrEnumfromtypingimportLiteral, assert_never, reveal_typeclassColor(StrEnum):
RED="r"GREEN="g"BLUE="b"deftest_literal_as_enum(x: Literal["g"] ="g") ->None:
matchx:
caseColor.RED:
assert_never(x)
caseColor.GREEN:
reveal_type(x)
caseColor.BLUE:
assert_never(x)
case _:
assert_never(x)
deftest_enum_as_litearl(y: Literal[Color.BLUE] =Color.BLUE) ->None:
matchy:
case"r":
assert_never(y)
case"g":
assert_never(y)
case"b":
reveal_type(y)
case _:
assert_never(y)
test_literal_as_enum() # selects green branch at runtimtest_enum_as_litearl() # selects blue branch at runtime

Expected no errors, but mypy-playground reports

main.py:14: error: Statement is unreachable [unreachable]
main.py:18: error: Argument 1 to "assert_never" has incompatible type "Literal['g']"; expected "Never" [arg-type]
main.py:27: error: Statement is unreachable [unreachable]
main.py:29: error: Argument 1 to "assert_never" has incompatible type "Literal[Color.BLUE]"; expected "Never" [arg-type]

Related: https://discuss.python.org/t/amend-pep-586-to-make-enum-values-subtypes-of-literal/59456
Also: #16327, #17162, #19616 (but none of these is specifically about match-case)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions