@@ -289,6 +289,73 @@ using ``isinstance()``:
289
289
This feature is sometimes called "sum types" or "discriminated union types"
290
290
in other programming languages.
291
291
292
+ Exhaustive checks
293
+ *****************
294
+
295
+ One may want to check that some code covers all possible ``Literal `` or ``Enum `` cases,
296
+ example:
297
+
298
+ .. code-block :: python
299
+
300
+ from typing import Literal
301
+
302
+ PossibleValues = Literal[' one' , ' two' ]
303
+
304
+ def validate (x : PossibleValues) -> bool :
305
+ if x == ' one' :
306
+ return True
307
+ elif x == ' two' :
308
+ return False
309
+ raise ValueError (' Wrong values passed: {0} ' .format(x))
310
+
311
+ assert validate(' one' ) is True
312
+ assert validate(' two' ) is False
313
+
314
+ In the code above it is really easy to make a mistake in the future:
315
+ by adding a new literal value to ``PossibleValues ``,
316
+ but not adding its handler to ``validate `` function:
317
+
318
+ .. code-block :: python
319
+
320
+ PossibleValues = Literal[' one' , ' two' , ' three' ]
321
+
322
+ Mypy won't catch that ``'three' `` is not covered.
323
+ However, if you want to have exhaustive check, you need to guard it properly:
324
+
325
+ .. code-block :: python
326
+
327
+ from typing import Literal, NoReturn
328
+
329
+ PossibleValues = Literal[' one' , ' two' ]
330
+
331
+ def assert_never (value : NoReturn) -> NoReturn:
332
+ # This also works in runtime as well:
333
+ assert False , ' This code should never be reached, got: {0} ' .format(value)
334
+
335
+ def validate (x : PossibleValues) -> bool :
336
+ if x == ' one' :
337
+ return True
338
+ elif x == ' two' :
339
+ return False
340
+ assert_never(x)
341
+
342
+ In this case, when adding new values to ``PossibleValues ``:
343
+
344
+ .. code-block :: python
345
+
346
+ PossibleValues = Literal[' one' , ' two' , ' three' ]
347
+
348
+ Mypy will cover you:
349
+
350
+ .. code-block :: python
351
+
352
+ def validate (x : PossibleValues) -> bool :
353
+ if x == ' one' :
354
+ return True
355
+ elif x == ' two' :
356
+ return False
357
+ assert_never(x) # E: Argument 1 to "assert_never" has incompatible type "Literal['three']"; expected "NoReturn"
358
+
292
359
Limitations
293
360
***********
294
361
0 commit comments