4 - Exhaustiveness checking with mypy
This technique is handy if there’s logic which should explicitly handle all possible values of an enumeration. With the example, mypy would kindly hint that BLUE is unhandled:
example.py 17: error: Argument 1 to "assert_never" has incompatible type "Literal[Color.BLUE]"; expected "NoReturn"
In addition to Enums, works great with e.g. Unions and Literals!
Read more
This is a widely known trick but I assume the original credits belong to https://github.com/python/mypy/issues/5818.
More on the topic in the mypy docs: https://mypy.readthedocs.io/en/stable/literal_types.html#exhaustiveness-checks
The code
from enum import Enum
from typing import NoReturn
class Color(Enum):
RED = "RED"
GREEN = "GREEN"
BLUE = "BLUE" # I just added this
def handle_color(color: Color) -> None:
if color is Color.RED:
...
elif color is Color.GREEN:
...
else:
assert_never(color)
def assert_never(value: NoReturn) -> NoReturn:
assert False, f"Unknown value: {value}"