Python type hints
1 · Warm-up 3 min
It is the first lesson, so the warm-up is a quick check of Day 0.
- Open a terminal and run
uv --version. If it prints a version number, you are ready. - Not ready yet? Go back to the Day 0 setup first, then come back. It is a one-time job.
2 · Hook 2 min
What does Python do if a function wants a number and you give it the word “banana”?
Guess first, then open
It shrugs, and tries to run it. If something fails, it fails later, inside the function. That surprise is today’s lesson.
3 · The idea, in three small pieces 10 min
mypy, before you run
- reads the hints
- finds a mismatch
- no code runs
Python, when it runs
- ignores the hints
- runs the line anyway
- fails only if that line breaks
Piece 1: a hint is a sticky note
A type hint says what a function takes and returns, like a sticky note on a door: “numbers only, please”.
def double(x: int) -> int:
return x * 2
Read it as: x should be an int, and the function gives back an int.
Piece 2: who reads the sticky note?
| Reads the hint? | |
|---|---|
| Python, while the program runs | No. It ignores it. |
| Your editor | Yes. It underlines mistakes. |
mypy (a checker tool) | Yes. It finds mistakes before you run. |
Piece 3: checking while the program runs is a different job
If you want something to refuse bad data at runtime, you need validation. On Day 3 you will meet Pydantic, the bouncer who checks IDs at the door.
list[str] feels like List<string> and str | None feels like string?. The big difference: there is no compiler that stops the program. In Python, the checker is a friend who whispers, “are you sure?”.4 · Worked example 5 min
Read it first. Then run it.
def summarize(text: str, max_words: int = 50) -> str:
words = text.split()
return " ".join(words[:max_words])
print(summarize("hello brave new world", 2))
hello brave
5 · Try it 25-30 min
Four steps, from guided to free. Make a folder for your work and a file called practice_types.py. (This is the checklist you tick on My Learning.)
Step 1 Copy and run
Paste this into practice_types.py and run it with uv run python practice_types.py (or python3 practice_types.py).
from collections import Counter
import re
def word_count(text: str) -> int:
return len(text.split())
def top_n_words(text: str, n: int = 5) -> list[str]:
words = re.findall(r"\b\w+\b", text.lower())
return [word for word, _ in Counter(words).most_common(n)]
def find_user(users: dict[str, str], user_id: str) -> str | None:
return users.get(user_id)
if __name__ == "__main__":
text = "the cat and the dog and the bird"
print(word_count(text))
print(top_n_words(text, 2))
users = {"1": "Ann", "2": "Bob"}
print(find_user(users, "1"))
print(find_user(users, "9"))
8
['the', 'and']
Ann
None
Step 2 Change one thing
Change top_n_words(text, 2) to top_n_words(text, 3). Predict the output before you run it, then check.
Check your prediction
['the', 'and', 'cat']
The words “cat”, “dog” and “bird” each appear once, and ties keep the order they first appeared in.
Step 3 Break it on purpose
Make a file broken.py next to it:
from practice_types import word_count, find_user
users = {"1": "Ann", "2": "Bob"}
print(find_user(users, 1))
print(word_count(123))
Run it: uv run python broken.py.
None
AttributeError: 'int' object has no attribute 'split'
Notice: find_user quietly returned None for the wrong type, and word_count failed inside the function, not at the hint.
Now ask mypy. Install it with uv add --dev mypy (or pip install mypy), then run uv run mypy broken.py practice_types.py.
broken.py:4: error: Argument 2 to "find_user" has incompatible type "int"; expected "str" [arg-type]
broken.py:5: error: Argument 1 to "word_count" has incompatible type "int"; expected "str" [arg-type]
That is what hints are for: the checker finds both mistakes before you run anything.
Step 4 Your turn
Write a function shout(text: str, times: int = 1) -> str that returns the text in upper case, repeated times times, separated by spaces. Test it with shout("hello", 2). Then call shout("hello", "two") in a second file and let mypy catch it.
Hint 1
Turning text into upper case: text.upper().
Hint 2
A list can be repeated: ["a"] * 3 gives ["a", "a", "a"]. Then " ".join(...) glues the pieces with spaces.
Solution
def shout(text: str, times: int = 1) -> str:
return " ".join([text.upper()] * times)
print(shout("hello", 2))HELLO HELLO
And mypy on the bad call says: Argument 2 to "shout" has incompatible type "str"; expected "int".
6 · Stuck? anytime
- “command not found: uv”: close and reopen the terminal. Still failing? Redo the uv step of Day 0.
- “No module named mypy”: install it with
uv add --dev mypyfirst. - mypy says nothing: that can mean no mistakes. Check that you really called a function with a wrong type.
- Still stuck? Comment on the video with the exact message you see.
7 · Check yourself 5 min
- What does a type hint guarantee while the program runs?
- In Step 3, why did
find_user(users, 1)printNoneinstead of failing? - Which tool would have caught the mistake before you ran the program?
Answers
- Nothing. Python ignores hints at runtime; they are for you, your editor and tools like mypy.
- Because
dict.getreturnsNonewhen the key is missing, and the integer1is not the key"1". Python never checked that the key was supposed to be a string. mypy(or an editor that reads type hints).
+ · Game: Sticky Note Sorter 5 min
Fetch the pixel dog delivers a small function with a sticky note (a type hint) and one call. Two questions each round: what does Python do when it runs? and does mypy flag it before you run? 8 rounds, 2 points each. Real results, no tricks.
Ready? You need no setup. Just read the code and decide.
mypy...Tick “Play the Sticky Note Sorter game” on My Learning when you reach the end. Any score counts. If you score under 10, read “Piece 2” again and replay: the rounds are shuffled.
8 · Your win, and what’s next 3 min
You made: typed functions, saw Python ignore a wrong type, and made mypy catch it. That is a real skill.
- Go to My Learning and tick your Day 1 checklist. Finish all the items to unlock Day 2.
- Share one line in the comments: what surprised you?
- Tomorrow: Day 2, project setup with
uv. And on Day 3 you will meet Pydantic, which turns hints into real checks.