Advanced·12 min·advanced · types · mypy
Type hints + mypy
Type hints: docs that catch bugs
Python doesn't enforce type hints at runtime. But a static checker (mypy, pyright) reads them, and so does your IDE — you get autocomplete, refactor safety, and errors caught before you run the code.
The syntax you'll use daily
- Basics:
int,str,float,bool,bytes,None. - Containers:
list[int],dict[str, int],tuple[int, str],set[str]. - Optional:
int | None(modern syntax, 3.10+). Old syntax:Optional[int]. - Union:
int | str— either one. - Callable:
Callable[[int, str], bool]— args then return type. - Any: escape hatch. Use sparingly — you're telling the checker "don't check this."
TypedDict — shaped dicts
Perfect for JSON-shaped data:
class User(TypedDict):
id: int
email: str
Now the checker knows user["id"] is an int and yells if you write user["id"] + " ".
Protocol — structural typing
class HasName(Protocol):
name: str
Anything with a .name attribute satisfies the protocol — no inheritance needed. This is Python's answer to interfaces.
dataclasses + type hints
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float = 0.0
Auto-generates __init__, __repr__, __eq__. Type hints are how it knows the fields.
Running the checker
pip install mypy
mypy myfile.py
Common flags:
--strict— enable everything (recommended for new projects).--ignore-missing-imports— for third-party libs without stubs.
Common pitfall
Type hints are checked, not enforced. add(1, "two") runs — mypy catches it, Python doesn't. So type hints replace neither tests nor input validation at API boundaries.
Try it
- Add a return-type hint to
lookupthat's wrong on purpose and see how mypy would flag it. - Add a
SessionTypedDictwithuser_id: int,expires_at: str,ip: str | None.