There’s actually a problem I came across where all the type checkers fail to agree with runtime: match-case with a value pattern.
from enum import StrEnum
from typing import Literal, assert_never, reveal_type
class Color(StrEnum):
RED = "r"
GREEN = "g"
BLUE = "b"
def test_literal_as_enum(x: Literal["g"] = "g") -> None:
match x:
case Color.RED:
assert_never(x)
case Color.GREEN:
reveal_type(x)
case Color.BLUE:
assert_never(x)
case _:
assert_never(x)
def test_enum_as_litearl(y: Literal[Color.BLUE] = Color.BLUE) -> None:
match y:
case "r":
assert_never(y)
case "g":
assert_never(y)
case "b":
reveal_type(y)
case _:
assert_never(y)
test_literal_as_enum()
test_enum_as_litearl()
At runtime, this will select the green branch for the first match-case, and the blue branch for the second match-case. But the type checkers all fail:
mypythinks the runtime branches are unreachablepyrightthinks the runtime branches are unreachablepyreflythinks the runtime branches are unreachabletythinks the runtime branches are unreachablezubanaccepts the green branch in the first match-case, but thinks the blue branch is unreachable in the second match-case