Python Type Hints - How to Manage “type: ignore” Comments with Mypy
It seems inevitable that large projects need some
# type: ignore comments, to work around type checking in tricky cases. I’ve found Mypy has a few options to make such ignore comments more precise and manageable.
These options are:
show_error_codes, which tells Mypy to identify error messages with their codes, which you can then use in ignore comments. This on by default from Mypy 0.900.
enable_error_code = ['ignore-without-code'], which tells Mypy that all ignore comments need specific error codes.
warn_unused_ignores, which tells Mypy to log errors for unnecessary ignore comments.
You can activate these flags for a whole project in
pyproject.toml like so:
[tool.mypy] enable_error_code = [ "ignore-without-code" ] show_error_codes = True warn_unused_ignores = True
Let’s look at each flag in more detail.
This first flag helps you write focused ignore comments that only disable the checks we want to ignore. When
show_error_codes is enabled, Mypy identifies errors with both a messages and an error code. You can use these codes in ignore comments, reducing the risk of other errors being introduced on commented lines.
Take this example code:
x: int x: str
Mypy logs an error when you redefine the type of a variable like this. This is normally a reason to use a second variable, but let’s roll with it for this example.
Let’s run Mypy on this example, with
$ mypy example.py example.py:2: error: Name 'x' already defined on line 1 [no-redef] Found 1 error in 1 file (checked 1 source file)
The error message is followed by the error code in square brackets:
[no-redef]. We can use this bracketed error code in an ignore comment to silence only that error:
x: int x: str # type: ignore [no-redef]
Running Mypy now shows no errors:
$ mypy --show-error-codes example.py Success: no issues found in 1 source file
By restricting the error code, if you later introduce a different error on the ignored line, Mypy will still report it. For example, you might add a reference to an undefined variable
x: int x: str = y # type: ignore [no-redef]
Mypy finds the bug:
$ mypy example.py example.py:2: error: Name 'y' is not defined [name-defined] Found 1 error in 1 file (checked 1 source file)
This error would be ignored if the line used an ignore comment without any error code.
If you ever need to, you can ignore two (or more) errors by combining their codes in a comma-separated list:
x: int x: str = y # type: ignore [name-defined,no-redef]
But this may also be a signal to split the line, or fix the errors!
This second option makes Mypy report errors for
# type: ignore comments without specific error codes.
ignore-without-code is one of several optional error codes that need explicitly enabling in the
For example, take the first example again, with the reassignment error ignored with a non-specific comment:
x: int x: str # type: ignore
When you run Mypy with
ignore-without-code enabled, it will disallow this comment:
$ mypy example.py example.py:2: error: "type: ignore" comment without error code (consider "type: ignore[no-redef]" instead) Found 1 error in 1 file (checked 1 source file)
The hint tells you how to change the comment:
x: int x: str # type: ignore [no-redef]
(Mypy suggests without the optional space before
[, but I prefer to add it.)
ignore-without-code on a project will thus require you to rewrite all existing non-specific comments, but it does tell you how to change them!
This third flag helps you manage ignore comments as your code changes. When
warn_unused_ignores is enabled, Mypy will log an error (not a warning) for each unnecessary ignore comment. Such redundancy can appear as your code evolves, such as when imported type hints become more accurate.
For example, imagine if you changed the previous example to remove the first line:
x: str # type: ignore [no-redef]
x is only defined once. If you run Mypy with
$ mypy --warn-unused-ignores example.py example.py:1: error: unused 'type: ignore' comment Found 1 error in 1 file (checked 1 source file)
…you get an error saying that you can remove the ignore comment. Neat!
Improve your Django develompent experience with my new book.
One summary email a week, no spam, I pinky promise.
- Python Type Hints - Mypy doesn’t allow variables to change type
- Python Type Hints - How to Upgrade Syntax with pyupgrade
- Python Type Hints - How to use Mypy’s unreachable code detection
Tags: mypy, python