Python Typing Patterns
Modern type hints for safe, documented Python code.
Basic Annotations
python# Variables name: str = "Alice" count: int = 42 items: list[str] = ["a", "b"] mapping: dict[str, int] = {"key": 1} # Function signatures def greet(name: str, times: int = 1) -> str: return f"Hello, {name}!" * times # None handling def find(id: int) -> str | None: return db.get(id) # May return None
Collections
pythonfrom collections.abc import Sequence, Mapping, Iterable # Use collection ABCs for flexibility def process(items: Sequence[str]) -> list[str]: """Accepts list, tuple, or any sequence.""" return [item.upper() for item in items] def lookup(data: Mapping[str, int], key: str) -> int: """Accepts dict or any mapping.""" return data.get(key, 0) # Nested types Matrix = list[list[float]] Config = dict[str, str | int | bool]
Optional and Union
python# Modern syntax (3.10+) def find(id: int) -> User | None: pass def parse(value: str | int | float) -> str: pass # With default None def fetch(url: str, timeout: float | None = None) -> bytes: pass
TypedDict
pythonfrom typing import TypedDict, Required, NotRequired class UserDict(TypedDict): id: int name: str email: str | None class ConfigDict(TypedDict, total=False): # All optional debug: bool log_level: str class APIResponse(TypedDict): data: Required[list[dict]] error: NotRequired[str] def process_user(user: UserDict) -> str: return user["name"] # Type-safe key access
Callable
pythonfrom collections.abc import Callable # Function type Handler = Callable[[str, int], bool] def register(callback: Callable[[str], None]) -> None: pass # With keyword args (use Protocol instead) from typing import Protocol class Processor(Protocol): def __call__(self, data: str, *, verbose: bool = False) -> int: ...
Generics
pythonfrom typing import TypeVar T = TypeVar("T") def first(items: list[T]) -> T | None: return items[0] if items else None # Bounded TypeVar from typing import SupportsFloat N = TypeVar("N", bound=SupportsFloat) def average(values: list[N]) -> float: return sum(float(v) for v in values) / len(values)
Protocol (Structural Typing)
pythonfrom typing import Protocol class Readable(Protocol): def read(self, n: int = -1) -> bytes: ... def load(source: Readable) -> dict: """Accepts any object with read() method.""" data = source.read() return json.loads(data) # Works with file, BytesIO, custom classes load(open("data.json", "rb")) load(io.BytesIO(b"{}"))
Type Guards
pythonfrom typing import TypeGuard def is_string_list(val: list[object]) -> TypeGuard[list[str]]: return all(isinstance(x, str) for x in val) def process(items: list[object]) -> None: if is_string_list(items): # items is now list[str] print(", ".join(items))
Literal and Final
pythonfrom typing import Literal, Final Mode = Literal["read", "write", "append"] def open_file(path: str, mode: Mode) -> None: pass # Constants MAX_SIZE: Final = 1024 API_VERSION: Final[str] = "v2"
Quick Reference
| Type | Use Case |
|---|---|
X | None | Optional value |
list[T] | Homogeneous list |
dict[K, V] | Dictionary |
Callable[[Args], Ret] | Function type |
TypeVar("T") | Generic parameter |
Protocol | Structural typing |
TypedDict | Dict with fixed keys |
Literal["a", "b"] | Specific values only |
Final | Cannot be reassigned |
Type Checker Commands
bash# mypy mypy src/ --strict # pyright pyright src/ # In pyproject.toml [tool.mypy] strict = true python_version = "3.11"
Additional Resources
./references/generics-advanced.md- TypeVar, ParamSpec, TypeVarTuple./references/protocols-patterns.md- Structural typing, runtime protocols./references/type-narrowing.md- Guards, isinstance, assert./references/mypy-config.md- mypy/pyright configuration./references/runtime-validation.md- Pydantic v2, typeguard, beartype./references/overloads.md- @overload decorator patterns
Scripts
./scripts/check-types.sh- Run type checkers with common options
Assets
./assets/pyproject-typing.toml- Recommended mypy/pyright config
See Also
This is a foundation skill with no prerequisites.
Related Skills:
python-pytest-patterns- Type-safe fixtures and mocking
Build on this skill:
python-async-patterns- Async type annotationspython-fastapi-patterns- Pydantic models and validationpython-database-patterns- SQLAlchemy type annotations

