🔍

Pydantic Internals — How Type Hints Become Runtime Validation

__annotations__ → Rust core (pydantic-core) → validation execution

Validation logic is created at class definition time.

V2 Core — pydantic-core

Pydantic v2 validation runs in Rust (pydantic-core), not Python. 5-50x faster than v1.

Flow: class definition → ModelMetaclass.__new__() → read __annotations__ → generate core_schema per type → create SchemaValidator (Rust object) → stored on class → User(...) triggers SchemaValidator.validate_python(data) in Rust.

Auto-Coercion

User(name='Kim', age='25') — age is str but auto-converts to int. age='abc' → ValidationError.

Role in FastAPI

FastAPI auto-parses/validates request body when endpoint parameter type is a Pydantic model. One type hint line handles input validation + docs + serialization.

Key Points

1

On class User(BaseModel): definition, ModelMetaclass reads __annotations__

2

Generates core_schema per field type (Rust level)

3

User(...) call triggers SchemaValidator.validate_python() validation in Rust

4

Validation failure → ValidationError — detailed info on which field failed and why

Use Cases

API request validation — auto input validation with FastAPI + Pydantic Config parsing — BaseSettings auto-loads env vars/.env with type validation