Python Type Safety
Leverage Python's type system to catch errors at static analysis time. Type annotations serve as enforced documentation that tooling validates automatically.
When to Use This Skill
- Adding type hints to existing code
- Creating generic, reusable classes
- Defining structural interfaces with protocols
- Configuring mypy or pyright for strict checking
- Understanding type narrowing and guards
- Building type-safe APIs and libraries
Core Concepts
1. Type Annotations
Declare expected types for function parameters, return values, and variables.
2. Generics
Write reusable code that preserves type information across different types.
3. Protocols
Define structural interfaces without inheritance (duck typing with type safety).
4. Type Narrowing
Use guards and conditionals to narrow types within code blocks.
Quick Start
def get_user(user_id: str) -> User | None:
"""Return type makes 'might not exist' explicit."""
...
# Type checker enforces handling None case
user = get_user("123")
if user is None:
raise UserNotFoundError("123")
print(user.name) # Type checker knows user is User here
Fundamental Patterns
Pattern 1: Annotate All Public Signatures
Every public function, method, and class should have type annotations.
def get_user(user_id: str) -> User:
"""Retrieve user by ID."""
...
def process_batch(
items: list[Item],
max_workers: int = 4,
) -> BatchResult[ProcessedItem]:
...
:
() -> :
._db = db
() -> User | :
...
() -> User | :
...
() -> User:
...