Skip to content
← All tracks

The Type System as a Design Tool

Python

Generics, protocols, narrowing, variance and `Final`. The hard prerequisite for every other python track.

This track is written for Python, which isn't the mode you're browsing in.

0 / 22 solved · 2 articles
  1. 1. Not solved yet. Modernise legacy annotations
  2. 2. Not solved yet. Flatten a union at runtime
  3. 3. Not solved yet. Coerce to int at an untyped boundary
  4. 4. Not solved yet. assert_never and the event that was never handled
  5. 5. Not solved yet. Literal fit modes and the Final default
  6. 6. Not solved yet. A @final rate limiter
  7. 7. Not solved yet. ClassVar, field(), and the counter that must reset
  8. 8. Not solved yet. Amortise cents without mixing up the units
  9. 9. Not solved yet. A recursive Json alias, depth and flatten
  10. 10. Not solved yet. Generic partition and chunk
  11. 11. Not solved yet. A generic Result[T, E]
  12. 12. Not solved yet. Bounds versus constraints: clamp and dedupe
  13. 13. PEP 696: default values for type parameters Read
  14. 14. Not solved yet. Why list[Dog] is not a list[Animal]
  15. 15. Not solved yet. Producer, Consumer, Cell: variance by member set
  16. 16. Not solved yet. Accept broad, return narrow: group_by and merge_counts
  17. 17. Not solved yet. Retry, and the predicate that reads backwards
  18. 18. Not solved yet. Self and the fluent query builder
  19. 19. Not solved yet. @override and the notifier that stopped notifying
  20. 20. Not solved yet. Narrowing without the truthiness trap
  21. 21. Not solved yet. TypeIs, TypeGuard, and a predicate that lies
  22. 22. Not solved yet. runtime_checkable is presence, not a signature
  23. 23. PEP 649/749: the end of quoted forward references Read
  24. 24. Not solved yet. Modernisation kata: inventory.py, 2019 to 2026

Check yourself

4 questions · one attempt each

These do not count toward finishing the track. They are here to catch the things that are easy to read past.

0 / 4

Why does the first function fail type checking and the second pass?

def f(x: int | None) -> int:
    return x + 1

def g(x: int | None) -> int:
    if x is None:
        return 0
    return x + 1
Question 1 of 4