Skip to main content

How to MyPy Ignore Errors Strategically

Β· 8 min read
Serhii Hrekov
software engineer, creator, artist, programmer, projects founder

When integrating MyPy into a large or legacy Python codebase, or when dealing with highly dynamic code, you will inevitably encounter situations where MyPy raises valid errors that you cannot (or should not) fix immediately. In these cases, selectively ignoring errors becomes a vital skill.

A super experienced developer never ignores errors blindly; they use these mechanisms strategically to maintain the highest possible type-checking quality in the rest of the codebase.

Here is a deep dive into the various methods MyPy provides for ignoring errors, from the narrowest to the broadest scope.

1. The Line-Level Ignore (Narrowest Scope)​

The most precise and preferred way to silence a specific, known issue is using a comment on the line where the error occurs.

Mechanism: # type: ignore​

Adding # type: ignore to the end of a line tells MyPy to completely skip type checking on that single line.

Use CaseExampleWhy Use It
Dynamic Attributesresult.data = json.loads(text) # type: ignoreWhen dynamically adding attributes to an object where MyPy cannot infer the type.
Untyped External Callclient.send_event(data) # type: ignoreWhen calling a function in an untyped third-party library whose arguments MyPy flags.

Expert Enhancement: Specifying the Error Code​

To make the ignore transparent and durable, specify the exact MyPy error code (e.g., attr-defined, name-defined). If the code is fixed later, MyPy will warn if the ignore is no longer needed (if warn_unused_ignores = True is set).

# The explicit error code documents *why* the ignore is necessary.
class MyObject:
...

obj = MyObject()
obj.dynamic_attr = 5 # type: ignore[attr-defined]

2. The Block-Level Ignore (The type: ignore Block)​

If a sequence of lines generates many related type errors (e.g., in a section dealing with highly dynamic dictionaries or metaprogramming), you can ignore an entire block.

Mechanism: # type: ignore[code] on the line above​

If you use # type: ignore on a line with no code, MyPy will treat it as applying to the block immediately following it.

# type: ignore[misc]
# This entire block will be skipped for type checking.
def dynamic_creator(data):
# MyPy error 1: Missing return type
# MyPy error 2: Untyped argument 'data'
instance = MyClass()
for key, value in data.items():
setattr(instance, key, value)
return instance

Caveat: This is a broad hammer. It should be used sparingly, as it completely hides any new type errors introduced within that block.


3. The Function/Class Level Ignore (Targeted Suppression)​

When an entire function or class relies on dynamic patterns that are impossible or impractical to type hint, you can use the @typing.no_type_check decorator.

Mechanism: @typing.no_type_check​

This decorator (from the standard typing module) tells MyPy and other static checkers to ignore all type hints within the decorated function or class.

from typing import no_type_check

@no_type_check
def large_legacy_function(a, b):
# MyPy will skip all checks inside this function body.
return "This is intentionally untyped."

# You still receive errors when calling it *from* typed code:
# typed_var: int = large_legacy_function(1, 2) # MyPy will flag this!

Scope: The check is skipped within the function, but MyPy will still check how the function is used externally.


4. Configuration File Ignores (Broadest Scope)​

For errors related to external dependencies or specific modules, you must use the MyPy configuration file (mypy.ini or pyproject.toml).

Mechanism A: Ignoring Missing Imports​

If an external library lacks type stubs, MyPy will raise an error on import.

[tool.mypy]
# Globally ignore errors for libraries missing type stubs
ignore_missing_imports = True

Expert Advice: Do not set this globally if you can avoid it. Instead, use the per-module configuration below.

Mechanism B: Per-Module Exclusions​

This is the cleanest way to ignore errors related to an entire third-party library or a legacy internal module.

# In pyproject.toml
[tool.mypy]
# Global strict settings...

# 1. Completely ignore a third-party library named 'untyped_vendor'
[tool.mypy.untyped_vendor.*]
ignore_errors = True

# 2. Ignore errors only in a specific internal legacy file
[tool.mypy.legacy_code.old_api_file]
disallow_untyped_defs = False # Relax a specific rule

)', and the outermost is 'Global ([tool.mypy] settings)', illustrating the hierarchy of scope.]

Mechanism C: Ignoring Specific Error Codes Globally​

If you have a project-wide coding style that conflicts with one specific MyPy check (e.g., you prefer Any for specific constructs), you can disable that rule globally.

[tool.mypy]
# Disable the check for implicitly returning 'Any' in all modules
warn_return_any = False

Use with Caution: This lowers type safety across the entire project.

Summary: Hierarchy of Ignoring​

Always choose the narrowest possible scope for ignoring errors to maximize the coverage and reliability of your type checks.

  1. # type: ignore[code] on a single line (Best).
  2. @typing.no_type_check on a function/class (Good for dynamic methods).
  3. [tool.mypy.module.*] ignore_errors = True in config (Good for external libraries).
  4. ignore_missing_imports = True (Avoid globally if possible).

Sources and Further Reading​

  1. MyPy Documentation - Suppressing Errors (Official Guide)
  2. MyPy Documentation - Command Line Flags and Configuration
  3. Python Documentation - typing.no_type_check decorator
  4. MyPy Documentation - Error Codes List