Mypy Ignore Cheat Sheet: Strategic Error Suppression in Python
When integrating static type checking into dynamic or legacy Python projects, you will inevitably encounter situations where Mypy flags type mismatches that you cannot or should not refactor immediately.
Instead of disabling type checking globally, you should use Mypy's built-in error suppression mechanisms. Suppressing errors should be done with the narrowest possible scope. This cheat sheet details when and how to apply line-level comments, module configuration blocks, decorators, and global settings.
Line-Level Suppression (Narrowest Scope)
The most precise way to silence an error is to place a # type: ignore comment on the exact line causing the warning.
Specifying Error Codes
Using a plain # type: ignore tells Mypy to ignore all errors on that line. This can hide other syntax issues or type errors. The recommended best practice is to specify the exact Mypy error code in brackets:
# type: ignore[error-code]
Benefits of Explicit Codes
- Self-Documentation: It explains to other developers exactly why the type check fails.
- Safety checks: If you clean up the code later and the error no longer occurs, Mypy will warn you that the ignore is unused (provided you have
warn_unused_ignores = Trueenabled in your Mypy settings).
Common Line-Level Ignore Cases
1. Dynamic Attribute Assignment (attr-defined)
Raised when you assign an attribute to a class that is not declared in its type signature or slot definitions:
class DynamicUser:
pass
user = DynamicUser()
# Mypy cannot know this attribute exists
user.role_id = 101 # type: ignore[attr-defined]
2. Untyped Third-Party Calls (no-untyped-call)
Raised when invoking functions from a legacy library that does not have type stubs:
import untyped_vendor_lib
def calculate(value: float) -> int:
# Silence the warning that the library lacks annotations
raw_val = untyped_vendor_lib.compute(value) # type: ignore[no-untyped-call]
return int(raw_val)
Function and Class Level Suppression
If a specific function or class relies heavily on dynamic metaprogramming, applying line-level comments to every line becomes verbose. Instead, use the standard library @typing.no_type_check decorator.
Using no_type_check
This decorator tells Mypy to skip analyzing the contents of the decorated function or class:
from typing import no_type_check
@no_type_check
def process_dynamic_attributes(obj, data_map):
# Mypy ignores all type checking inside this function body
for key, value in data_map.items():
setattr(obj, key, value)
return obj
Note: Mypy still type-checks how this function is used from external typed code. If your function returns Any (untyped) and you try to assign it to an annotated type constraint like int, Mypy will flag the assignment error.
Configuration File Exclusions
For broader module-level or dependency exceptions, manage your settings in your configuration file (typically pyproject.toml or mypy.ini).
1. Disabling Specific Error Codes Per Module
If an entire file relies on dynamic behavior (e.g. database migration scripts or reflection utilities), disable specific error codes for that module only:
# pyproject.toml
[[tool.mypy.overrides]]
module = "my_project.migrations.*"
disable_error_codes = ["attr-defined", "operator"]
2. Silencing Missing Import Warnings Per Library
If an external dependency does not provide type stubs, Mypy raises a import warning. Tell Mypy to ignore missing imports for that library specifically. This keeps global type checking active:
# pyproject.toml
[[tool.mypy.overrides]]
module = "untyped_vendor.*"
ignore_missing_imports = True
Avoid setting ignore_missing_imports = True globally under the main [tool.mypy] block. Doing so silences import issues for all libraries, which can mask configuration errors.
3. Disabling Rules Globally
If your team has a project-wide style convention that conflicts with a Mypy check, you can disable the rule globally. Use this option with caution:
# pyproject.toml
[tool.mypy]
warn_return_any = false
Summary of Suppression Scopes
| Scope | Mechanism | Configuration Location | Best Use Case |
|---|---|---|---|
| Line-Level | # type: ignore[error-code] | Inline Code Comment | Silencing a single, isolated dynamic assignment. |
| Block/Function | @typing.no_type_check | Decorator on definition | Silencing legacy functions or dynamic object loaders. |
| Module-Level | disable_error_codes = [...] | pyproject.toml (Overrides) | Silencing specific checks in files like migrations. |
| Library-Level | ignore_missing_imports = true | pyproject.toml (Overrides) | Silencing import warnings for untyped dependencies. |
| Global-Level | warn_return_any = false | pyproject.toml (Mypy block) | Disabling rules that conflict with project conventions. |
Sources
- [1] Mypy Documentation: Error Codes Reference List
- [2] Mypy Documentation: Silencing Type Checker Warnings
- [3] Mypy Documentation: Per-Module Configuration Rules
- [4] Python Documentation: typing.no_type_check Decorator API
- [5] Real Python: Type Checking in Python - Advanced Mypy Configuration
