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 1.18 through 1.20 (released March 2026) brought substantial changes:

  • 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 is available via pip install mypy[native-parser] and --native-parser. It provides access to all Python syntax regardless of the Python version running mypy.
  • 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.
  • Flexible redefinitions: the --allow-redefinition-new flag permits reassigning variables and parameters with different types inside a function.

Note

mypy no longer runs on Python 3.9 (end of life) as of version 1.20. Checking code that targets Python 3.9 still works with --python-version 3.9.

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 and pyright on large codebases, though the gap has narrowed
  • 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

# Use the experimental native parser
uv pip install mypy[native-parser]
uv run mypy --native-parser 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

Please submit corrections and feedback...