Messages and tool results as dataclasses, versus NamedTuple
slots=True and kw_only=True need Python 3.10 or later. ChatMessage and ToolResult mirror the shape of real chat-API data.
A dataclass is a class for holding data. The @dataclass decorator reads the annotated fields you list and writes __init__, __repr__ and __eq__ for you, with options for defaults, immutability (frozen), ordering, slots and keyword-only fields.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 6 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write a dataclass Student with name: str, marks: list (default empty list) and passed: bool = False. Create two students, add a mark to one and show the other's list is still empty.
Write a frozen, ordered dataclass Version with major, minor, patch ints. Sort [Version(1,2,0), Version(1,10,0), Version(1,2,5)] and print the result.
Write a dataclass Order with price: float and quantity: int and a __post_init__ that raises ValueError if either is not positive, and a computed total field (field(init=False)).
Explain it without notes
What does @dataclass generate, and what does it save you from writing?
Why can't you write items: list = [] in a dataclass, and what is the fix?
What do frozen=True and order=True do?
When would you choose a NamedTuple over a dataclass, and the reverse?
Expected output
ChatMessage(role='assistant', content='Here you go', tool_results=[ToolResult(tool='search', ok=True, output='3 results', warnings=[])])
{"role": "assistant", "content": "Here you go", "tool_results": [{"tool": "search", "ok": true, "output": "3 results", "warnings": []}]}
TypeError: ToolResult.__init__() takes 1 positional argument but 2 were given
AttributeError: 'ToolResult' object has no attribute 'colour' and no __dict__ for setting new attributes
False
1 2 1 2 True
False 1
PointDC(x=99, y=2)
AttributeError: can't set attribute
PointDC(x='a', y=None)