7 routes42 sections324 units

Unit 3.7 · about 3 h

16 / 324

Type hints, generics, protocols and narrowing

Typed boundaries are the foundation of the next section. Hints are documentation the machine checks.

  • explain
  • implement

You can now

  • Write PEP 695 generics and type aliases, and explain deferred annotation evaluation on Python 3.14.
  • Define a Protocol and contrast structural with nominal subtyping, including runtime_checkable limits.
  • Narrow unions with isinstance and assert_type, and pass mypy clean on a typed module.

Covers

  • Type hints, unions, generics, protocols and narrowing

Study, in this order

6 steps

  1. Type parameter lists
    Python language reference

    Sections 8.10 to 8.10.3: generic functions, classes and aliases since Python 3.12 by PEP 695; bounds, constraints and defaults

  2. Annotation scopes and lazy evaluation
    Python language reference

    Sections 4.2.3 and 4.2.4: annotation scopes; lazy evaluation since 3.12, extended to all annotations in 3.14 by PEP 649 and PEP 749

  3. Protocols
    typing - type hints and protocols

    Protocols: structural subtyping; runtime_checkable limits (isinstance checks presence only)

  4. Generics
    typing - type hints and protocols

    Generics: TypeVar-based generics for reading older code; write new code with the PEP 695 syntax above

  5. Checked narrowing
    typing - type hints and protocols

    assert_type: ask the checker to prove a narrowed type at a program point

  6. mypy Type Checker
    AlgoMaster Python - structured revision

    The mypy Type Checker lesson and its exercise; verify every syntax claim against the 3.14 sections above, since older examples may predate PEP 695

Focus on

  • Annotations are lazily evaluated since 3.14 by PEP 649: def f(x: 1/0) defines fine and fails only when __annotations__ is read. get_type_hints evaluates them in the right scope.
  • PEP 695 in 3.12 puts type parameters in brackets: def first[T](xs: list[T]) -> T. Read old TypeVar code; write the new syntax.
  • A Protocol defines structure, not lineage. isinstance against a non-runtime_checkable Protocol raises TypeError; a runtime_checkable check tests member presence only.
  • Narrowing proves a type at a point: isinstance branches plus assert_type as the checkable claim. isinstance with a parameterized generic raises TypeError.

Reproduce closed-book

Closed-book, type a generic first() plus a small Protocol and a narrowing function over int | str; run mypy 2.4.0 clean. Show that def f(x: 1/0) defines without error on 3.14 and raises only on annotation access.

Traps

  • Checking with isinstance(x, list[int]). Parameterized generics are not valid isinstance targets.
  • Treating a runtime_checkable Protocol as a full interface check. It verifies member presence, never signatures or semantics.
  • Assuming annotations run at def time. On 3.14 a ZeroDivisionError inside an annotation waits until someone reads it, which delays import-time failures.

Practice

AlgoMaster Python: Exercise: mypy Type Checker

Exercises 1 to 4: exposing annotations, a NewType call, counting error codes and a pyproject.toml mypy section

Run the same checks locally with mypy 2.4.0 from the section interpreter.

Self-test

  1. def f(x: 1/0) -> None: pass runs without error on 3.14. When does it fail, and which PEP changed this?

  2. What does isinstance([], list[int]) do, and what should you write instead?

  3. class P(Protocol): def m(self) -> int. What does isinstance(obj, P) do without @runtime_checkable?

  4. Rewrite class Box(Generic[T]) with 3.12 syntax and state the minimum version.

Completion criterion

Stop when

Your typed module passes mypy clean, your Protocol accepts an unrelated matching class, and you can state exactly when each annotation evaluates.

Mark passed, then open 3.8 Only mark this when you can do it without notes.

Leads to

Comes after

Resources for this unit

  • Python language reference
    Python Software Foundationrequiredreference
    Check Data model, Execution model, Import system and Exceptions whenever a claim depends on Python semantics. These pages are the authority when the course and a runtime observation disagree.
  • AlgoMaster Python - structured revision
    AlgoMastersupportpractice
    Use Functions, Modules and Packages, OOP, Advanced OOP, Exception Handling, Iterators and Generators, Type Hints and Annotations only after the cookbook pass. Open it for recall practice or a diagnosed weak mechanism, not as a second complete course.
  • typing - type hints and protocols
    Python Software Foundationreferencereference
    Read Protocols for structural typing and runtime_checkable limits, Generics for TypeVar generics, and assert_type for narrowing checks. Use for the Protocol and narrowing parts of type-hints-protocols; PEP 695 syntax itself is in the language reference.

Also in this section

  • Stas' Python Cookbook - selected path
    Stas Bekmanprimarycourse
    Run Part I on dictionaries, iteration, functions, closures, decorators, classes and context managers; Part II on modules, files, paths, environment and arguments; and Part IV on versions, dependencies, packaging and code quality. Finish by building one src-layout package from a blank directory.
  • Packaging Python Projects
    Python Packaging Authorityrequiredimplementation
    Follow the packaging tutorial once from a blank directory, using a src layout, pyproject.toml, an isolated build and a clean-environment installation test.
  • dataclasses - data classes
    Python Software Foundationreferencereference
    Read the @dataclass parameters (eq, order, frozen, slots), field() with default_factory, frozen instances, post-init processing, replace, asdict and astuple. Use for the validated frozen dataclass in attributes-protocols-dataclasses.
  • gc - cycle garbage collector
    Python Software Foundationreferencereference
    Read the cycle collector interface: collect, get_count, garbage and disable/enable. Use for the cycle-collection and measurement parts of refcounting-gc-weakrefs.
  • weakref - weak references
    Python Software Foundationreferencereference
    Read weak-reference objects (ref callbacks, proxy objects) and the WeakValueDictionary example. Use for the weak-reference part of refcounting-gc-weakrefs.

Quick find

Search Michi

Type to search every route, section, unit, topic and resource.

Enter opens the first result Esc closes

Reference

Keyboard shortcuts

n
Continue to the first unit not passed
j / k
Next / previous unit
1 2 3
Toggle learned, practised, passed
/
Open search
?
Show this help
Esc
Close open panels