Skip to the solution
MediumDSA11 min read

How do you enforce match/case exhaustiveness in Python?

354 views

The problem

Question presented to candidate: "You have a match over an order-status enum. Next month someone adds a new status. How do you make sure every match that should handle it gets flagged, instead of silently doing nothing?"

What a strong answer should cover:

  • Python does not check exhaustiveness at runtime: when no case matches, the match does nothing and a function falls off the end returning None.
  • The runtime safety net: a final case _: that raises; typing.assert_never(x) (3.11+) does that and also raises AssertionError even under python -O.
  • The static check: with assert_never(x) in the default branch, mypy and pyright narrow x case by case and report the leftover type (for example Literal[Status.REFUNDED]) when a case is missing.
  • Checkers can also flag a missing case without assert_never: mypy's opt-in --enable-error-code exhaustive-match (mypy 1.17+) and pyright's reportMatchNotExhaustive (on in strict mode).
  • It only works over closed types: enums, Literal[...], bool, and unions of classes. A bare object, str or int can never be exhausted.
  • A test that iterates Enum members or typing.get_args(Union) catches gaps in projects without a checker in CI.

Clarifying questions expected:

  • Does the project run mypy or pyright in CI, and in which mode?
  • Is the value a closed set (enum, Literal, union of classes), or arbitrary input that needs a real default?

Code / implementation expected: Yes β€” a match ending in case _: assert_never(x) plus the checker error it produces.

  • match
  • exhaustiveness

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

11 min read Β· 11 sections

Run the code

Edit the code and run it here. Each console line with an expected value becomes a test.

PythonSilent miss, loud default, assert_never and a test that walks the enum
PythonExhaustive matching over a union of dataclasses and a Literal

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 97 of 139 in Python

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Python questions
Up nextMedium

What is the late-binding closure pitfall in loops?

Continue