Skip to content

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.

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 faster checking or tighter VS Code integration, consider pyright; 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-defs or --strict 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 via Protocol, and TypedDict for typed dictionaries.
  • 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.

Recent Developments

mypy 2.0 (May 2026)

mypy 2.0 ships parallel type checking and flips several flag defaults that change inference behavior. The release lands the work tracked for years in issue #933.

  • Parallel checking (experimental): pass --num-workers N or -nN to type-check across N worker processes. The release notes report gains of up to 5x with 8 workers, with the disclaimer that the speedup depends on a project’s import structure and the host environment. Parallel mode implicitly enables the native parser and still has minor semantic differences from single-process mode that future releases will close.
  • --local-partial-types is now default, which changes how mypy infers types from assignments in other scopes. Code that passed under 1.x can surface new errors after upgrade.
  • --strict-bytes is now default per PEP 688: bytearray and memoryview values are no longer assignable to the bytes type.
  • --allow-redefinition semantics changed. The flag now behaves like --allow-redefinition-new did in 1.20, requires --local-partial-types (which is now default), and forbids two type annotations on the same variable. Pass --allow-redefinition-old to keep the legacy behavior.
  • --python-version 3.9 is rejected with an error. The minimum target is now 3.10.
  • --ignore-missing-imports is now consistent across all packages; the legacy bundled-stub special case is gone.

mypy 1.18 through 1.20 (March 2026)

  • Performance: versions 1.18+ delivered roughly 40% faster type checking compared to 1.17, with some cases improving by 10x. A binary cache format and SQLite-backed cache (both now enabled by default) make incremental builds faster.
  • Native parser: an experimental parser based on Ruff’s parser became available via uv add --dev "mypy[native-parser]" and the --native-parser flag.
  • Python 3.14 support: mypy handles t-strings (PEP 750) and ships mypyc-accelerated wheels for Python 3.14 free-threading builds.
  • Better type narrowing: mypy 1.20 reworked narrowing for equality expressions, containment checks, and match statements to be more aggressive and more correct.

Note

mypy 2.0 rejects --python-version 3.9. mypy 1.20 had already dropped runtime support for Python 3.9 itself; 2.0 also drops it as a target.

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
  • Recent versions have closed the performance gap with newer tools

Cons

  • Skips unannotated functions by default, which surprises users who expect it to catch obvious errors everywhere
  • 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 (mypy 2.0+)
uv run mypy -n 8 src/

Configuration

mypy reads configuration from mypy.ini, .mypy.ini, setup.cfg, or pyproject.toml (under [tool.mypy]). Per-module overrides let you treat vendored code or test files differently from application code:

pyproject.toml
[tool.mypy]
python_version = "3.12"
strict = true

[[tool.mypy.overrides]]
module = "tests.*"
disallow_untyped_defs = false

Learn More

Last updated on