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.
show_error_codes
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 show_error_codes
on:
$ 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
Great.
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 y
:
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!
enable_error_code = ['ignore-without-code']
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 enable_error_code
option.
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.)
Enabling 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!
warn_unused_ignores
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]
Now x
is only defined once. If you run Mypy with warn_unused_ignores
enabled:
$ 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.
Related posts: