Python Type Hints - How to use Mypy’s unreachable code detection2021-05-19
I recently discovered Mypy has a secondary function as an unreachable code detector. This feature is a great way to highlight places bugs may be hiding, as code paths that can’t possibly run normally show a logical error.
We can activate this feature by setting the
warn_unreachable option to
Contra to the name, the option makes Mypy log an error for each unreachable statement or clause.
We can set the option in a
setup.cfg like so:
We can also pass
--warn-unreachable on the command line.
Mypy can discover many kinds of unreachable code. For example, take this function with two return statements:
When we run Mypy on this file, it highlights line 3 as unreachable:
Fixing requires us to investigate.
return lines could have arisen from a bad merge of two branches.
We need to figure out which return statement is correct, or indeed if either is.
Mypy’s reachability detection is fine-grained and can highlight just one clause on a line. For example take this code:
isinstance() clause in the
if is always
True, so the
x < y clause is unreachable.
Mypy highlights it as such:
Such unreachable clauses can arise through refactoring - perhaps the type of
x has changed from
int | None to
int and the
isinstance() check is no longer required.
Another case that Mypy can detect is when we check for a type that the variable’s hints say it may not be. For example:
Mypy tells us this
if clause is unreachable:
This will require another investigation.
Either the variable is missing the option to be
None in its type hint, or this
if clause can be removed.
Mypy’s unreachable code detection is not perfect. The checks are based on types, not values, so they cannot detect duplicated checks on values that are obvious to the human eye. For example:
elif can never be true as the value
0 has already been handled, but Mypy does not highlight this.
The best defence against all unreachable code remains 100% code coverage. (Yes, seriously 100%!). But Mypy’s reachability detection can be a fast way of checking your code for potential bugs before engaging in more costly testing.
May all your code be found reachable,
Want better tests? Check out my book Speed Up Your Django Tests which teaches you to write faster, more accurate tests.
One summary email a week, no spam, I pinky promise.
- Python Type Hints - Duck typing with Protocol
- Python Type Hints - How to Narrow Types with isinstance(), assert, and Literal
- Python Type Hints - How to Debug Types With reveal_type()
Tags: mypy, python
© 2021 All rights reserved.