Types as design: runtime vs static
advanced18 min readLesson 116 of 169
Understand what annotations promise, who consumes them, and where to draw boundaries.
Runtime vs static: what types are and are not
Python's type hints are not enforced at runtime. def f(x: int) -> str runs
happily with f("oops"). Hints are consumed by static checkers (mypy, pyright)
and by readers ā they are a design language layered over the code.
What this means at an advanced level:
- Types describe intent and contracts, not runtime behavior. A wrong annotation is a lie that ships silently unless a checker runs in CI.
typing.get_type_hints(obj)/obj.__annotations__can read hints at runtime ā that is how dataclasses, pydantic, and dependency-injection frameworks build behavior from annotations.- The workflow professionals run: annotate the boundaries first (function
signatures, API models), let inference handle the inside, run the checker in
CI, and treat
Anyas a TODO, not a default.
Version note (prose only): Python 3.12 adds PEP 695 type-parameter syntax
(def first[T](xs: list[T]) -> T), and 3.13 adds typing.TypeIs. This course's
graded code targets 3.11 (TypeVar, Generic, TypeGuard), which runs
unchanged on 3.12+ sandboxes.