MyPy Configuration for Strict Typing
MyPy is the premier static type checker for Python. While running MyPy with no configuration works, achieving true, robust type safety requires a configuration that enables strict mode and specifically targets potential weak points in Python's type system.
This article details the essential settings within the mypy.ini, pyproject.toml, or setup.cfg file that an experienced developer uses to maximize type checking effectiveness.
Why Strict Mode Mattersβ
By default, MyPy allows many behaviors that compromise type safety (e.g., implicitly assuming untyped functions return Any). Strict mode eliminates these permissive defaults, forcing you to explicitly annotate and handle complex scenarios.
1. The Strict Global Sectionβ
The core step is to enable all strict checks simultaneously. This is the single most powerful line in your configuration.
| Setting | Location | Description |
|---|---|---|
strict = True | [mypy] (Global) | Enables all strict_* flags below. Highly recommended for new projects. |
If you are migrating an existing, large codebase, you may need to enable these flags incrementally instead of using strict = True:
# Recommended for migration: Enable checks one by one
[mypy]
disallow_untyped_defs = True
warn_return_any = True
no_implicit_optional = True
check_untyped_defs = True
warn_unused_ignores = True
2. Mandatory Un-Typed Disallowanceβ
These settings ensure that MyPy validates the integrity of your function and class definitions, forcing full type coverage.
Setting: disallow_untyped_defs = Trueβ
-
Action: Requires all function definitions to have type annotations for every argument and for the return value.
-
Example (MyPy Error):
# MyPy will fail here:
def untyped_function(a):
return a + 1
Setting: disallow_incomplete_defs = Trueβ
- Action: Ensures that even if a function is decorated, it must still have explicit type hints (e.g., if using framework decorators like
functools.lru_cache).
Setting: disallow_untyped_calls = Trueβ
- Action: Prevents your typed code from calling functions that have no type annotations. This guards against integrating weakly typed codebases.
3. Handling None and Optionals Explicitlyβ
Python's implicit handling of None is a major source of runtime bugs. These settings enforce clarity around when None is allowed.
Setting: no_implicit_optional = Trueβ
-
Action: If an argument has a default value of
None, its type hint must explicitly includeNone(i.e., useOptional[T]orT | None). -
Example (MyPy Error):
# MyPy fails without no_implicit_optional = True
def load_user(user_id: str = None): # Error: user_id must be str | None
...
Setting: strict_optional = Trueβ
- Action: Ensures that variables declared as
Optional[T]are not treated as typeTwithout first checking forNone. This flag is usually covered bystrict = True.
4. Configuration for External Libraries (Skipping/Ignoring)β
MyPy attempts to check all imported code. For large or external libraries that do not yet have type hints (or have invalid ones), you must instruct MyPy to skip them to prevent noise.
Setting: ignore_missing_imports = Trueβ
- Action: Prevents MyPy from failing if it cannot find stub files (
.pyi) for a third-party library. This is often necessary for libraries that are not fully typed.
Setting: Per-Module Exclusions (Highly Recommended)β
You can specify exact modules to skip type checking for, which is much cleaner than using the global flag above.
# In pyproject.toml or mypy.ini
[mypy]
# Global settings for your code...
# Tell MyPy to completely ignore the pandas library checks
[mypy-pandas.*]
ignore_errors = True
# Tell MyPy to allow missing imports only for a specific library
[mypy-untyped_api_client]
ignore_missing_imports = True
5. Advanced Check: Disallowing Anyβ
The Any type acts as a wildcard, effectively turning off type checking for that variable. While useful for transitioning code, its overuse defeats the purpose of MyPy.
Setting: warn_return_any = Trueβ
- Action: MyPy will issue a warning if a function is inferred (or explicitly annotated) to return
Any. This forces you to be precise about return types.
Summary of Recommended Strict Configurationβ
If starting a new project, use this minimal and effective setup in your pyproject.toml file:
[tool.mypy]
# Enable ALL strict checks simultaneously
strict = true
# Optional: Add common exclusions
ignore_missing_imports = true
# Required for code that needs to handle external libraries without stubs
[tool.mypy.explicit_ignore]
# Example: Ignore the slow validation on a large third-party library
"some_untyped_library.*" = true
