Dataclass reads hints, Pydantic validates and makes a schema
Pydantic is available in the browser runner. The schema is what you would send to an LLM as the parameters of a tool.
Hints are ordinary data that Python keeps, so a program can read them: __annotations__, typing.get_type_hints, get_origin and get_args. Dataclasses and Pydantic do exactly this, and so you can write a tiny validator yourself.
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 5 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Print the resolved type hints (use get_type_hints) of a function def f(a: int, b: list[str] = []) -> bool.
Write field_names(cls) that returns the list of annotated field names of a class, and call it for a small class.
Create a Pydantic model User with name: str and age: int, build one from age="42", and print user.age + 1.
Explain it without notes
Where does Python store type hints, and how should you read them?
What is the difference between how a dataclass and Pydantic use the same hints?
What is a forward reference and what changed in Python 3.14?
How do type hints help with LLM tool calling?
Why can reading __annotations__ fail or mislead, and what do you use instead? What changes on 3.14?
Expected output
dataclass reads the hints: [('name', <class 'str'>), ('price', <class 'float'>)]
Item(name='tea', price='oops')
city='Pune' celsius=21.5 rainy=False
float
1 error
float_parsing - Input should be a valid number, unable to parse string as a number
{"celsius": {"title": "Celsius", "type": "number"}, "city": {"title": "City", "type": "string"}, "rainy": {"default": false, "title": "Rainy", "type": "boolean"}}
required: ['city', 'celsius']