Skip to content

Annotate and check Python types

I can annotate a function's parameters and return value, run a type checker over the result, and say what the annotations do and do not guarantee at runtime.

Domain
Python Programming
Level
intermediate
Status
draft · v0.1.0
Also called
Type hints, Type annotations, mypy, Static typing in Python
License
CC BY-SA 4.0

Learn first

Learn it

Scope

Saying in the signature what a function takes and returns, and having a tool check that the rest of the code agrees.

In scope: annotating parameters, returns, collections and optional values; running a checker; understanding that annotations are not enforced at runtime. Out of scope: generics, protocols, overloads and typing a large existing codebase.

This outcome is marked evolving: the syntax has changed across recent Python versions — Optional[int] became int | None, List[int] became list[int] — and checkers differ in what they accept. Read the documentation for the version you are on rather than the first answer you find.

What an annotation is, and is not

def total(prices: list[float], discount: float = 0.0) -> float:

That line tells a reader, an editor and a checker what this function expects. It tells the interpreter almost nothing: Python stores the annotations and runs the function regardless. Passing a list of strings raises later, inside, if it raises at all.

So an annotation is a claim checked by a tool you have to run, not a guarantee. That is the design, and it is why mypy exists.

Why bother

  • The signature stops lying. A docstring saying “returns a list” drifts; an annotation is checked.
  • The editor gets useful: completion and inline errors come from annotations.
  • Whole categories of bug — a None reaching something that cannot take one — are found before the code runs, which is exactly the class of bug that survives a happy-path test.

The one that earns its keep: optional

int | None forces the question “what if there is nothing?” at the boundary rather than at 3am. A checker will refuse to let you use the value until you have handled the None case, which is the single highest-value thing annotations do in practice.

Common misconceptions

  • “Annotations make Python faster.” They do not. The interpreter ignores them for execution.
  • “Annotated code is type-safe.” Only what the checker ran over, and only as honestly as it was annotated. Any silences it.
  • “Annotate everything.” Annotate boundaries — public functions, module edges, anything another file calls. A three-line local helper rarely repays it.
  • “The checker is wrong.” Occasionally. Much more often it has found something true that is awkward to express, and the fix is in the code.

Notes for teachers

Give learners a function with a hidden None path and a test suite that passes, then run mypy in front of them. Finding the bug without running the program is the argument, and it is more persuasive than any style guide.

Then ask for one place the annotation would be noise, so the habit is judgement rather than compliance.

Resources

ResourceKindCostProvider
typing: support for type hintsreferencefreePython Software Foundation
mypy: getting startedreadingfreemypy

Courses that include it

draft

Python for a Coding Assessment

A refresher path through the Python graph for someone who has written Python before and has an assessment coming: run and read, rebuild the core, then work the way an assessment expects.

Prove it

Evidence of mastery

  • Annotates an unannotated function, including a collection type and an optional value, and the checker passes.
  • Runs mypy over a small project, reads an error, and either fixes the code or explains why the annotation was wrong.
  • Says what happens at runtime when a caller ignores an annotation, and why that is the design.
  • Chooses not to annotate something where the annotation would be noise, and defends the choice.

Assessments that measure it

No assessment yet.

Credentials that include it

No credential yet.

What learners show

Nothing to show yet. The publisher last published on 2026-09-20, and no aggregate for this outcome has reached the 50 learners a number needs. Open Degree does not track learners. About learner evidence.

What comes next

No outcome builds on this yet. Ask for the next concept.