Type Hints Like a Professional
Transform Python type hints into verifiable API specifications. Master static duck typing (`typing.Protocol`), advanced type primitives (`TypeVar`, `Self`, `@overload`, `TypedDict`, `Literal`), and enforce compile-time exhaustiveness checking with `assert_never`.
Senior Systems Studio: Type Hints Like a Professional
Select any senior topic below to verify static duck typing with typing.Protocol, test advanced type primitives (Self, TypeVar, @overload, TypedDict, Literal), and enforce static exhaustiveness checking using assert_never.
Professional Type System Architecture in Modern Python
- Structural Subtyping: `typing.Protocol` (PEP 544) defines static duck-typing contracts satisfied without nominal inheritance.
- Advanced Primitives: Use `Self` (PEP 673) for subclass method chaining, `@overload` for polymorphic return types, and `TypedDict` for zero-overhead JSON contracts.
- Exhaustiveness Checking: Pair discriminated union types (`Card | Crypto`) with `assert_never(unreachable)` inside `match-case` blocks for static safety.
1. Structural Subtyping (`typing.Protocol`)
Protocols implement static duck typing (PEP 544). Classes satisfy protocol contracts structurally without explicit base class inheritance. `@runtime_checkable` enables runtime `isinstance` inspection.
from typing import Protocol, runtime_checkable
@runtime_checkable
class PaymentGateway(Protocol):
def charge(self, amount: int) -> bool: ...
class StripeGateway:
"""Satisfies PaymentGateway contract implicitly."""
def charge(self, amount: int) -> bool:
print(f"Stripe charged ${amount}")
return True
def process_payment(gateway: PaymentGateway, amount: int) -> bool:
return gateway.charge(amount)
2. Advanced Type Primitives (`Self`, `@overload`, `TypedDict`, `Literal`)
Modern Python type primitives express complex API constraints without runtime memory overhead:
from typing import Self, overload, TypedDict, Literal
class UserPayload(TypedDict):
user_id: str
role: Literal["admin", "developer", "guest"]
class QueryBuilder:
def filter_by(self, field: str, value: str) -> Self:
"""Returns instance type for fluent method chaining."""
return self
@overload
def parse_id(val: int) -> int: ...
@overload
def parse_id(val: str) -> str: ...
def parse_id(val: int | str) -> int | str:
return val
3. Static Exhaustiveness Checking (`assert_never`)
Pair discriminated unions with `assert_never` inside `match-case` blocks to guarantee compile-time exhaustiveness checks across static type checkers like `mypy` and `pyright`.
from typing import assert_never, Literal
from dataclasses import dataclass
@dataclass
class Card:
method: Literal["card"]
pan: str
@dataclass
class Crypto:
method: Literal["crypto"]
wallet: str
Payment = Card | Crypto
def route_payment(p: Payment) -> str:
match p:
case Card(pan=pan):
return f"Processing Card: {pan}"
case Crypto(wallet=w):
return f"Processing Crypto Wallet: {w}"
case _ as unreachable:
assert_never(unreachable)