Python Typing Patterns
Modern type hints for safe, documented Python code.
Basic Annotations
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
from 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
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
from 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
from 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
from 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)
from 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
from 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
from 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
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 annotations
-
python-fastapi-patterns
-
Pydantic models and validation
-
python-database-patterns
-
SQLAlchemy type annotations