mypy: Python Static Type Checker
mypy is a static type checker for Python that analyzes type annotations to detect bugs before runtime. It has been the default Python type checker since 2012 and has the broadest ecosystem support of any Python type checking tool. Development happens in the python/mypy repository under an MIT license.
When to use mypy
Use mypy when you want to catch type-related bugs before runtime by adding static type checking to a Python project. It is the most established Python type checker with broad ecosystem support, making it a reliable default for projects that are adopting type annotations incrementally. For tighter VS Code integration and checking of unannotated code, consider pyright, which is slower than current mypy despite older claims to the contrary; for an emerging alternative from the creators of Ruff, see ty.
Key Features
- Gradual typing: add type annotations incrementally to an existing codebase. Unannotated functions are skipped by default unless
--check-untyped-defsor strict mode is enabled. - Type inference: deduces types from assignments, return values, and usage patterns when explicit annotations are absent.
- Generic types, unions, protocols: supports parameterized types (
list[int]), union types (str | int), structural subtyping viaProtocol, andTypedDictfor typed dictionaries, including closed TypedDicts (PEP 728) that reject undeclared keys. - Type stubs: works with typeshed and custom stub files for libraries that don’t ship inline annotations.
- mypyc compilation: mypy includes mypyc, a compiler that translates type-annotated Python into C extensions for significant runtime speedups.
- Parallel type checking: pass
--num-workers N(short form-n N, or set theMYPY_NUM_WORKERSenvironment variable) to type-check across multiple worker processes. Parallel mode implicitly enables the native parser. - Daemon mode:
dmypykeeps a warm server between invocations that caches analysis, so a re-check after an edit skips re-parsing unchanged modules. - Native parser: an optional parser based on Ruff’s parser, available via
uv add --dev "mypy[native-parser]"and the--native-parserflag. - Python 3.14 support: handles t-strings (PEP 750) and ships mypyc-accelerated wheels for free-threading builds.
Pros
- Most established type checker with the broadest library compatibility and community resources
- Gradual adoption path via per-module configuration overrides
- mypyc compiler can speed up runtime performance of type-annotated code
- Parallel checking and an optimized binary cache close the performance gap with newer tools
Cons
- Skips unannotated functions by default, which surprises users who expect it to catch obvious errors everywhere (see how to configure mypy strict mode to enable stricter checking)
- No built-in language server; editor integration relies on third-party plugins or pairing with pyright or ty
- Slower than ty on large codebases, though roughly on par with pyright on current versions
- Struggles with highly dynamic Python patterns
Installation and Usage
# Add as a dev dependency
uv add --dev mypy
# Check a single file
uv run mypy example.py
# Check multiple files or directories
uv run mypy src/ tests/
# Enable stricter checking
uv run mypy --strict example.py
# Type-check in parallel
uv run mypy -n 8 src/Daemon Mode
dmypy ships with mypy and runs the same checks against a long-lived server process, so the second and later invocations reuse the analysis already in memory:
# Start the daemon and check a path
uv run dmypy run -- src/
# Re-check after an edit; the warm daemon answers without a full restart
uv run dmypy run -- src/
# Shut the daemon down
uv run dmypy stopThe first run prints Daemon started before the diagnostics; subsequent runs print the diagnostics alone. The daemon reads the same [tool.mypy] configuration and reports the same errors as mypy.
Release Cadence
The 2.x line opened with mypy 2.0 in May 2026, which introduced parallel type checking, and reached 2.3.0 on 13 July 2026. The python/mypy repository merged 77 commits in the two months to August 2026.
Configuration
mypy reads configuration from mypy.ini, .mypy.ini, setup.cfg, or pyproject.toml (under [tool.mypy]). The minimum --python-version target is 3.10. --local-partial-types and --strict-bytes (PEP 688) are enabled by default; projects upgrading from 1.x may see new errors from these stricter defaults.
Per-module overrides let you treat vendored code or test files differently from application code:
[tool.mypy]
python_version = "3.12"
strict = true
[[tool.mypy.overrides]]
module = "tests.*"
disallow_untyped_defs = falseLearn More
- How do mypy, pyright, and ty compare?
- Does Ruff support type checking?
- How to configure mypy strict mode
- How to configure mypy and django-stubs in a uv project
- How to gradually adopt type checking in an existing Python project
- How to configure Claude Code with a Python type checker
- How to migrate from mypy to ty
- How to migrate from mypy to Pyrefly
- How to try the ty type checker
- ty reference
- Pyrefly reference
- pyright reference
- Zuban reference
- mypy 2.0 picks parallelism over a rewrite walks through the 2.0 release and how the parallel-checking gains compare to the Rust-based type checkers
- Official mypy Documentation
- Mypy 2.0 Release Blog Post
- Mypy Changelog