You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(types): document Field(exclude=True) and @model_serializer for nested wire isolation (#630)
* docs(types): document Field(exclude=True) and @model_serializer for nested wire isolation
Pydantic v2's Rust-backed serializer does not call Python model_dump()
overrides on nested child instances — a gap that was driving adopters to
write mechanical parent-level dispatch boilerplate (~59 overrides in
at least one downstream integration). Neither Field(exclude=True) nor
@model_serializer(mode='wrap') require parent-level workarounds; both
work correctly at every nesting depth via Pydantic's own pipeline.
This commit:
- Adds a top-level serialization note to extending-types.md explaining
the Pydantic v2 nesting behavior
- Adds a "Field(exclude=True) — Recommended" section with a working
nested example
- Adds a "@model_serializer" section for custom Python-level logic
- Adds a migration guide replacing the 59-style parent-dispatch pattern
- Adds a serialize_as_any note for runtime-type field inclusion
- Updates Best Practices #1 to prefer Field(exclude=True) over
call-site exclude={}
- Adds a one-line comment on AdCPBaseModel.model_dump() cross-referencing
the doc so source readers hit the explanation at the declaration
https://claude.ai/code/session_01P7MQW9tW7z4rYm13zghrVC
* docs(types): fix pre-PR review blockers in extending-types.md
- @model_serializer: correct nesting claim — serializer only fires when
serialized directly or when parent calls model_dump(serialize_as_any=True);
update example to use user-defined source_label field (no non-existent
render_url), add serialize_as_any=True demonstration
- Field(exclude=True): fix import (adcp.types.base not adcp.types),
switch example to Creative/CreativePayload (verifiable fields), remove
invalid Product constructor that would raise ValidationError
- Migration section: rename GetCreativesResponse (non-existent) to
MyCreativePayload
- Best Practices #1: fix CreateMediaBuySuccess → CreateMediaBuySuccessResponse
(correct export name), add imports
https://claude.ai/code/session_01P7MQW9tW7z4rYm13zghrVC
* docs(types): fix pre-existing wrong type names throughout extending-types.md
CreateMediaBuySuccess is not exported from adcp — the correct name is
CreateMediaBuySuccessResponse. WebhookPayload is also not exported —
McpWebhookPayload is the correct replacement. All 10+ import and usage
sites in the pre-existing patterns corrected; class name suffixes
(CreateMediaBuySuccessExtended) preserved.
https://claude.ai/code/session_01P7MQW9tW7z4rYm13zghrVC
---------
Co-authored-by: Claude <noreply@anthropic.com>
### 1. Always Use Field Exclusion for Wire Protocol
213
361
214
-
**Don't**rely on serialization settings to exclude internal fields automatically:
362
+
**Prefer `Field(exclude=True)` over call-site `model_dump(exclude={...})`.**`Field(exclude=True)` is declared once on the field, works at every nesting depth automatically, and cannot be forgotten at a call site.
215
363
216
364
```python
365
+
from adcp import CreateMediaBuySuccessResponse
366
+
from pydantic import Field
367
+
217
368
# ❌ BAD: Relying on field name conventions
218
-
classExtended(CreateMediaBuySuccess):
219
-
_internal_id: str# Private field - might not serialize correctly
369
+
classExtended(CreateMediaBuySuccessResponse):
370
+
_internal_id: str# Private field — may or may not serialize correctly
220
371
221
-
#✅ GOOD: Explicit exclusion
222
-
classExtended(CreateMediaBuySuccess):
372
+
#⚠ OK but fragile: call-site exclusion must be repeated every time model_dump() is called
0 commit comments