Internals
This chapter is about the internal shape of Pydantic: what gets prepared at class-definition time, what gets cached, and why some extension points are easy while others push you closer to pydantic-core internals. You do not need to become a library author to benefit from this model.
Quick takeaway: when a Pydantic model class is defined, it collects fields and annotations, builds core schema, and prepares a `SchemaValidator` plus `SchemaSerializer`. Rebuilds are only needed when annotation resolution was incomplete, such as with forward references or dynamic model construction.
Internal Flow
What You Can Inspect Directly
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
print(User.model_fields)
print(type(User.__pydantic_validator__).__name__)
print(type(User.__pydantic_serializer__).__name__)A model class already carries `model_fields`, `__pydantic_validator__`, and `__pydantic_serializer__`. Validation is not reinterpreted from scratch on every call.
Why Annotation Resolution Matters
- Forward references may need a later rebuild.
- Generic and recursive models depend on annotation resolution order.
- Frameworks that consume annotations and build Pydantic schemas depend on the same runtime behavior.
When model_rebuild() Enters the Picture
- a forward reference was not yet resolvable
- a model was assembled dynamically
- generic parameters or delayed imports left the first schema incomplete
The Feel of Caching and Reuse
- Each model class owns prepared validator and serializer objects.
TypeAdapteralso prepares reusable validation and serialization objects.- In hot paths, reuse model classes and adapters instead of recreating them repeatedly.
Framework-Facing Checklist
Annotation reading
Frameworks often do not use annotations directly; they feed them into schema generation first.
Schema cache
Reusing the same model or adapter means reusing prepared validator/serializer machinery.
Dynamic model cost
Dynamic generation and rebuilds are powerful, but more complex to reason about than static declarations.
Custom hooks
The deeper you go into custom schema hooks, the more this internal model matters.