Repository navigation
fix(python): preserve optional nested additional properties - #150
Draft
liutmelody wants to merge 2 commits into
Draft
liutmelody wants to merge 2 commits into
liutmelody wants to merge 2 commits into
Conversation
|
I have read the CLA Document and I hereby sign the CLA You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot. |
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.
Why
An optional nullable object can disappear from a serialized Python request or response when it contains a nested model that allows additional properties. The typed attribute still exists, but
model_dump()andmodel_dump_json()omit it.The generated
Field(init=False)default shadows Pydantic's internal__pydantic_extra__slot. Nested union serialization rejects the unexpected field, selects theUnsetfallback, and removes the value.Minimal reproduction using the generated primary fixture:
Before:
{}with no client exception.After:
{"configuration":{"options":{"kind":"structured","custom_options":true}}}.What changed
Generate the
__pydantic_extra__default only underif TYPE_CHECKING:. At runtime, the model has only the type annotation, so Pydantic's extra-fields slot works as intended. Type checkers still seepydantic.Field(init=False), so constructors do not require a__pydantic_extra__argument. Add request and response regression coverage using generated models, and regenerate the two affected review models and their checksums. Additional-property values still follow their declared schema.Testing
Manual reproduction on generated models with Pydantic 2.11.2 and 2.14.1 confirms that optional nested values, extension keys, explicit nulls, and omitted values retain their intended serialization. Reverting the generator change drops the nested values again. mypy and pyright report no errors on the regenerated review SDK or when constructing the new models. Regenerated review models also reject invalid values in a typed additional-properties map.
Public-safety check
.claude/skills/public-repo-communication/SKILL.md).git diff --check.Summary by cubic
Fixes generated Python SDK serialization dropping optional nested objects that allow additional properties, so
model_dump()andmodel_dump_json()now preserve them.The
Field(init=False)default on__pydantic_extra__shadowed Pydantic's internal extra-fields slot, causing nested union serialization to fall back toUnset.__pydantic_extra__without a runtime default, keepingField(init=False)only underif TYPE_CHECKING:so constructors stay valid for type checkers.Written for commit 6517a51. Summary will update on new commits.