Conversation
Symmetric with the existing exclude_none=True default. Removes the parent-side model_dump boilerplate that adopters previously needed to write per response type to make subclass @model_serializer overrides fire through base-typed parent fields. Field(exclude=True) remains the wire-isolation contract and continues to suppress internal fields at every nesting depth. BREAKING CHANGE: Subclasses that add fields without Field(exclude=True) will now have those fields appear in model_dump() output where they were previously dropped by Pydantic's declared-schema firewall. Audit each subclass and mark internal fields with Field(exclude=True). To restore the prior behavior at a specific call site, pass serialize_as_any=False explicitly. Closes #615 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
serialize_as_any=TrueinAdCPBaseModel.model_dump()andmodel_dump_json(), symmetric with the existingexclude_none=Truedefault.@model_serializeroverrides now fire automatically through base-typed parent fields.Field(exclude=True)remains the wire-isolation contract and continues to suppress internal fields at every nesting depth.model_dumpboilerplate that adopters previously needed to write (the salesagent SDK alone has ~14 such overrides on top of 58Field(exclude=True)markers).Closes #615.
Why this and not the docs-only fix in #630
#630 documented the workaround: "you must remember
serialize_as_any=Trueat every call site." That's the strongest argument for making it a default — if the kwarg is worth documenting as a footgun, it's worth flipping. The change is a one-line addition that's perfectly symmetric withexclude_none=Trueand eliminates the need for the workaround.Behavior change
Subclasses that add fields without
Field(exclude=True)previously had those fields silently dropped by Pydantic's declared-schema firewall when nested under a base-typed parent. Under this PR they appear inmodel_dump()output. The migration is mechanical: audit each subclass, mark internal fields withField(exclude=True). Taggedfeat!so release-please bumps the major version and the CHANGELOG flags the change clearly. Adopters who want the prior behavior at a specific call site can passserialize_as_any=Falseexplicitly.docs/extending-types.mdis updated to reflect the new default and call out the audit step for adopters with non-excluded subclass fields.Test plan
tests/test_serialize_as_any_default.py— 8 new tests pinning: subclass@model_serializerfires on singular and list fields,model_dump_jsoncarries the same default,Field(exclude=True)continues to suppress internal fields, the new wire-leak path is observable (so adopters who relied on the firewall surface a failing test), explicitserialize_as_any=Falseopt-out works, and the two defaults (exclude_none,serialize_as_any) are independent.mypyclean on the touched files;mypy --strict tests/type_checks/(the suite added in feat(testing): adopter type-checking test suite with zero-ignore contract #634) still clean.🤖 Generated with Claude Code