Exercise: Add Type Hints and Write Your First Test
Three short pieces: annotate two functions you've already written, define a Pydantic model, and prove it works with pytest.
Part 1: Type Hints
Open the chapter 1 exercise file where you wrote is_overdue and next_status. Add full type hints to both.
Just annotate the parameters and return types. date and TaskStatus are already imported at the top of the file from the chapter 1 exercise.
The expected signatures:
def is_overdue(due_date: date | None, status: TaskStatus) -> bool: ...
def next_status(status: TaskStatus) -> TaskStatus: ...
Part 2: A Pydantic Model
In a fresh file called computer.py at your project root, define a Pydantic model called Computer:
brand: strram_gb: inthard_drive_gb: int
Create a valid instance:
laptop = Computer(brand="apple", ram_gb=16, hard_drive_gb=512)
print(laptop)
Then try to create an invalid one with a string where Pydantic expects an integer:
try:
bad = Computer(brand="apple", ram_gb="thirty two", hard_drive_gb=512)
except ValidationError as e:
print(e)
Read the error message. Pydantic tells you exactly which field failed, what type it expected, and what it got.
Part 3: Tests
Create tests/test_computer.py. Write three tests:
test_computer_valid: construct a validComputerand assert each of the three fields holds the value you passed in.test_computer_rejects_string_ram: assert that passing a string forram_gbraisesValidationError. Usepytest.raises.test_computer_requires_brand: assert that constructing aComputerwithout abrandargument raisesValidationError.
Run the suite:
uv run pytest
You should see three dots and 3 passed.
Solution
computer.py:
from pydantic import BaseModel, ValidationError
class Computer(BaseModel):
brand: str
ram_gb: int
hard_drive_gb: int
if __name__ == "__main__":
laptop = Computer(brand="apple", ram_gb=16, hard_drive_gb=512)
print(laptop)
try:
bad = Computer(brand="apple", ram_gb="thirty two", hard_drive_gb=512)
except ValidationError as e:
print(e)
tests/test_computer.py:
import pytest
from pydantic import ValidationError
from computer import Computer
def test_computer_valid():
laptop = Computer(brand="apple", ram_gb=16, hard_drive_gb=512)
assert laptop.brand == "apple"
assert laptop.ram_gb == 16
assert laptop.hard_drive_gb == 512
def test_computer_rejects_string_ram():
with pytest.raises(ValidationError):
Computer(brand="apple", ram_gb="thirty two", hard_drive_gb=512)
def test_computer_requires_brand():
with pytest.raises(ValidationError):
Computer(ram_gb=16, hard_drive_gb=512)
Success
When uv run pytest reports 3 passed, you've confirmed Computer accepts a valid spec, rejects a string in ram_gb, and refuses to construct without a brand.