Type Hints
Say what your code expects.
Ava's shop program has grown, and she has started to forget things. Does this function expect a price as a number, or as text? Does it return a list, or a single item? Teammates ask the same questions. Type hints answer them, right in the code, and special tools can catch whole families of bugs before the program even runs.

- Forgetting what a function expects
- Teammates asking the same questions
- Hints document the answer, in the code
Basic type hints
A type hint follows a colon after a parameter, and an arrow shows the return type. Python does not enforce them while running, they are information for people and tools. Here, the function says, I take a float and an int, and I give back a float. Variables can be annotated too.
def total(price: float, qty: int) -> float:
return price * qty
name: str = "fern"
count: int = 3
print(total(9.5, 2))
print(total.__annotations__)19.0
{'price': <class 'float'>, 'qty': <class 'int'>, 'return': <class 'float'>}Collections and optional values
For containers, say what is inside them. A list of strings, a dictionary from string to float. A value that may be missing is written with a pipe and None, meaning, either this or nothing. A union of types uses the same pipe. These make your intentions precise, and catch mistakes early.
def cheapest(prices: dict[str, float]) -> str | None:
if not prices:
return None
return min(prices, key=prices.get)
def names(items: list[str]) -> list[str]:
return [i.title() for i in items]
print(cheapest({"fern": 9.5, "ivy": 7.0}))
print(cheapest({}))
print(names(["fern", "ivy"]))ivy None ['Fern', 'Ivy']
Checking types with mypy
Hints become powerful with a type checker, like mypy or pyright, which many editors run for you. It reads your code, without running it, and reports mismatches, like passing text where a number is expected. Add hints gradually, starting with function signatures. Dataclasses and modern libraries use them everywhere.
Annotate a function
Your turn. Write a function with full type hints, that takes a list of integers, and returns the largest one, or None, if the list is empty. Ready? Here is one solution. A list of ints in, an int or None out, and a check for empty input.
Write largest(nums: list[int]) -> int | None that returns the biggest number or None for an empty list.
Show hint
int | None as the return type
Show solution
def largest(nums: list[int]) -> int | None:
if not nums:
return None
return max(nums)
print(largest([3, 9, 4]))
print(largest([]))9 None
Summary
Good work. Type hints document your code, make editors smarter, and let tools like mypy catch bugs before they run. Next, Ava learns how to prove her code works, and keep it working, with automated tests.
Key takeaways- def f(x: int) -> str
- list[str], dict[str, float], X | None
- mypy checks hints without running code