Skip to content

Exhaustiveness checking fails on non-trivial use of pattern matching #14833

Description

@ajasmin

Code using assert_never() to ensure exhaustive use of match-case yields a type error on many non-trivial cases.

mypy can only verify exhaustiveness when matching directly against a Union type or Enum value.

Though, proving the exhaustiveness of non-trivial matches may be beyond mypy domain. Here are a couple of examples for the sake of argument:

Matching on both [] and [x, *xs] on Sequence will not narrow the type

fromcollections.abcimportSequencefromtypingimportassert_neverdefmy_sum(s: Sequence[float]) ->float:
matchs:
case []:
return0case [num, *rest]:
returnnum+my_sum(rest)
case _ asu:
# error: Argument 1 to "assert_never" has incompatible type "Sequence[float]"; expected "NoReturn"returnassert_never(u)

Matching against all Enum values that a single-member wrapper class may contain

importdataclasses, enumfromtypingimportassert_never, finalclassE(enum.Enum):
A=enum.auto()
B=enum.auto()
@final@dataclasses.dataclass(frozen=True)classFoo:
x: Edefmatch_enum_attribute(f: Foo) ->None:
matchf:
caseFoo(E.A):
passcaseFoo(E.B):
passcase _ asr:
# error: Argument 1 to "assert_never" has incompatible type "Foo"; expected "NoReturn" [arg-type]assert_never(r)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions