mypy Per-Module Options: Override by Module
mypy per-module options apply different settings to different modules using glob-matched override blocks.
Per-module options are how you adopt strictness gradually: hold new packages to a high bar while leaving legacy ones alone, all in one config.
What it does
mypy lets most boolean options be set per module. In pyproject.toml this is an array of [[tool.mypy.overrides]] tables, each with a module glob; in INI it is [mypy-<glob>] sections. More specific module patterns take precedence over broader ones.
Common usage
[[tool.mypy.overrides]]
module = ["legacy.*", "vendor.*"]
disallow_untyped_defs = false
check_untyped_defs = false
[[tool.mypy.overrides]]
module = "thirdparty_without_stubs.*"
ignore_missing_imports = trueOptions
| Key | What it does |
|---|---|
| module | Glob (or list of globs) the override matches |
| disallow_untyped_defs | Tighten/relax annotation requirements per module |
| ignore_missing_imports | Mute unresolved imports for matched modules |
| ignore_errors | Suppress all errors for matched modules |
In CI
Per-module overrides are the recommended path to roll out --strict without a giant one-shot diff. Keep the strict default global and carve out legacy modules, so new code is checked strictly and the carve-outs shrink over time.
Common errors in CI
A glob like legacy not matching anything is silently ignored, so a typo in the module name leaves the override inert and errors still fire. mypy warns about unused override sections only with --warn-unused-configs; enable it to catch dead overrides in CI.