Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions docs/source/literal_types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,73 @@ using ``isinstance()``:
This feature is sometimes called "sum types" or "discriminated union types"
in other programming languages.

Exhaustive checks
*****************

One may want to check that some code covers all possible ``Literal`` or ``Enum`` cases,
example:

.. code-block:: python

from typing import Literal

PossibleValues = Literal['one', 'two']

def validate(x: PossibleValues) -> bool:
if x == 'one':
return True
elif x == 'two':
return False
raise ValueError('Wrong values passed: {0}'.format(x))

assert validate('one') is True
assert validate('two') is False

In the code above it is really easy to make a mistake in the future:
by adding a new literal value to ``PossibleValues``,
but not adding its handler to ``validate`` function:

.. code-block:: python

PossibleValues = Literal['one', 'two', 'three']

Mypy won't catch that ``'three'`` is not covered.
However, if you want to have exhaustive check, you need to guard it properly:

.. code-block:: python

from typing import Literal, NoReturn

PossibleValues = Literal['one', 'two']

def assert_never(value: NoReturn) -> NoReturn:
# This also works in runtime as well:
assert False, 'This code should never be reached, got: {0}'.format(value)

def validate(x: PossibleValues) -> bool:
if x == 'one':
return True
elif x == 'two':
return False
assert_never(x)

In this case, when adding new values to ``PossibleValues``:

.. code-block:: python

PossibleValues = Literal['one', 'two', 'three']

Mypy will cover you:

.. code-block:: python

def validate(x: PossibleValues) -> bool:
if x == 'one':
return True
elif x == 'two':
return False
assert_never(x) # E: Argument 1 to "assert_never" has incompatible type "Literal['three']"; expected "NoReturn"

Limitations
***********

Expand Down