Static type checker for Python · catch bugs before runtime · verified against mypy 2.3 (2026)

mypy cheat sheet

mypy checks Python type hints statically — it finds type errors, wrong arguments, and None bugs without running your code. Annotations are standard Python (PEP 484+); mypy verifies they're consistent and infers the rest. This sheet targets mypy 2.x (2.0 added experimental parallel checking via --num-workers) and modern syntax valid on Python 3.12+ (built-in generics, X | Y unions). Pair it with a linter/formatter (ruff) for full coverage.

run & annotate everyday types advanced typing config & strictness narrowing & escape hatches gotcha most common

Verified 2026-08-24 against the official docs at mypy.readthedocs.io and mypy-lang.org (mypy 2.x). Type hints follow the stdlib typing module and PEP standards; syntax shown targets Python 3.12+.

Outline

Annotate → run mypy → fix. Most real value comes from Optional/None checking and turning on strictness gradually.

Basics

  1. 1 · Install & run
  2. 2 · Annotate functions & vars

Types

  1. 3 · Collections & unions
  2. 4 · Any, Callable, Literal, Final

Advanced

  1. 5 · Generics & TypeVar
  2. 6 · Protocol & TypedDict
  3. 7 · overload & more

Operate

  1. 8 · Config & strictness
  2. 9 · Narrowing & ignores
  3. 10 · Gotchas
  4. Worth memorizing

Basics

Run it, and write your first annotations.

1Install & run2.x
2Annotate functions & varsthe syntax

Everyday Types

The annotations you'll write constantly.

3Collections & unionsmodern syntax
4Any, Callable, Literal, Finalspecial forms

Advanced Typing

Generics, structural typing, and precise signatures.

5Generics & TypeVarreusable types
6Protocol & TypedDictstructural & dicts
7overload & moreprecise signatures

Operate

Configure strictness and handle the awkward cases.

8Config & strictnesspyproject.toml
9Narrowing & ignoresescape hatches
!Common gotchasread before shipping

Worth memorizing

annotate, run mypy, fixstatic — it never runs your code
X | None is the winmypy forces you to handle None before use
built-in genericslist[int], dict[str, float] — no typing.List anymore
Protocol = duck typing, typedstructural match, no inheritance needed
[T] inline generics (3.12+)def first[T](xs: list[T]) -> T
strict = truethe target for new code; adopt flags gradually on legacy
narrowing refines unionsisinstance / is None / assert
type: ignore[code], never bareand turn on warn_unused_ignores
annotate empty containersx: list[int] = [] or you get list[Any]
Any silences checkinguse object when you mean "anything but still checked"