PythiloLesson 15 of 15 · progress kept in this browser

Type hints as documentation

A signature is the first thing a reader sees. def find(users, key) leaves every question open. With hints, the signature answers them: what to pass, what comes back, and whether it can be missing.

from dataclasses import dataclass

@dataclass
class User:
    email: str
    name: str

def find_user(users: list[User],
              email: str) -> User | None:
    for user in users:
        if user.email == email:
            return user
    return None

ada = User("ada@x.org", "Ada")
print(find_user([ada], "ada@x.org"))

-> User | None warns every caller to handle the missing case, and a type checker flags one that does not.

Hints are not checked when the code runs, but unlike comments they are read by editors and checkers, so a stale hint gets noticed. Make them precise: dict[int, list[str]] says far more than dict. And let them steer the design: returning an empty list instead of None removes the | None, and every check that came with it.

Your task

Move the comments into the signatures: tags_for(tags_by_user: dict[int, list[str]], user_id: int) -> list[str], returning an empty list for an unknown user, and most_tagged(tags_by_user: dict[int, list[str]]) -> int | None.

All lessons