Python Type Hints Exercises: Annotations That Help Readers
Type hints are a communication tool. They tell a reader what a function expects and returns, and they give editors enough information to warn you before a bug reaches runtime. They do not turn Python into a statically checked language.
Annotate parameters and returns
A colon introduces a parameter annotation, and an arrow introduces the return annotation. Use built-in types for simple values. The annotations are stored in __annotations__ and are available to tools such as get_type_hints.
def greet(name: str) -> str:
return f"Hello, {name}"
print(greet("Ada"))A typed function
Describe collection contents
list[int] says the list contains integers; dict[str, float] says the keys are strings and the values are floats. These hints describe the interface, not each runtime value. A list containing a string can still be passed and will still run.
def total(values: list[int]) -> int:
return sum(values)
print(total([1, 2, 3]))Typed collections
Make missing values explicit
A lookup can return None. Write that possibility into the return type with a union such as float | None. The caller can then check for None before arithmetic, and an editor can point out the missing branch.
def find_price(prices: dict[str, float], item: str) -> float | None:
return prices.get(item)
print(find_price({"tea": 3.5}, "coffee"))A value that may be absent
Read hints at runtime when needed
get_type_hints resolves annotations into type objects. This is useful for small demos and frameworks. Most application code should not branch on annotations; use them to document and check, not to build a second type system.
from typing import get_type_hints
def double(n: int) -> int:
return n * 2
print(get_type_hints(double))Annotations are data too
Expect documentation, not enforcement
Passing a string where an int is annotated does not raise TypeError by itself. The function runs until an operation fails. Use a linter or a type checker in CI if you want static enforcement, and keep runtime validation for untrusted input.
def double(n: int) -> int:
return n * 2
print(double("a"))The hint does not convert the value
Your practice checklist
- Annotate public function parameters and return values.
- Use list[int] and dict[str, float] for collection contents.
- Include None in a return type when a value may be missing.
- Do not expect hints to validate runtime input.
- Use a type checker when you want enforcement beyond the editor.
Common questions
Do type hints make Python faster?
Not by themselves. They are metadata used by tools; the interpreter does not enforce them.
Should I annotate every variable?
Usually no. Annotate function boundaries and values whose type is not obvious from the name and assignment.
What does list[int] mean on older Python?
On Python 3.8 and earlier, use List[int] from typing. Built-in generics are available in modern Python.
Practice type hints
12 questions on annotations, list[int], optional returns, and runtime behavior.
Keep reading: