feat(python): add model_dump_json override to handle FieldMetadata aliases #11067
+34
−0
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.
Description
Refs extend-hq/extend-python-sdk#14
Adds a
model_dump_json()override toUniversalBaseModelso that JSON serialization properly respectsFieldMetadataaliases (e.g.,snake_case→camelCase).Background: The existing
dict()method already handlesFieldMetadataaliases viaconvert_and_respect_annotation_metadata(). However,model_dump_json()was calling Pydantic's native implementation directly, which doesn't know aboutFieldMetadataannotations. This caused JSON output to use Python field names instead of the expected wire-format aliases.Requested by: [email protected] (@tjb9dc)
Link to Devin run: https://app.devin.ai/sessions/078ffa2dec06476a9c041a29f6f37cf4
Changes Made
model_dump_json()override toUniversalBaseModelinpydantic_utilities.pywith_pydantic_v1_on_v2/pydantic_utilities.pyvariantversions.ymlwith changelog entry for v4.43.0The new method delegates to our custom
dict()(which handles aliases correctly) and then serializes to JSON:to_jsonable_python(data, fallback=encode_by_type)for proper v2 JSON normalizationjson.dumps(data, default=encode_by_type)directlyNote: The
with_pydantic_aliasesvariants were intentionally NOT updated because they use native PydanticField(alias=...)whereby_alias=Truealready works correctly. Thewith_pydantic_v1_on_v2variant uses the simpler v1-style implementation since it's explicitly v1-only.Updates Since Last Revision
pydantic_utilities.pyto useto_jsonable_pythonfor Pydantic v2, matching the existing pattern used byto_jsonable_with_fallbackin the codebaseTesting
pnpm run check)Human Review Checklist
to_jsonable_python, v1 usesjson.dumpswithdefault)encode_by_typehandles all necessary types (datetime, UUID, Decimal, Enum, etc.) - it uses Pydantic'sENCODERS_BY_TYPEmodel_dump_json()with aliased fieldswith_pydantic_v1_on_v2variant correctly uses simpler implementation (noIS_PYDANTIC_V2check needed since it's v1-only)