Repository navigation
Conversation
This was referenced Oct 23, 2026
There was a problem hiding this comment.
All reported issues were addressed across 31 files
Shadow auto-approve: would not auto-approve because issues were found.
View guided diff | Turn on auto-fix | Re-trigger cubic
2ynn
force-pushed
the
qynn/fix/python-unrecognized-enum-serialization
branch
from
October 23, 2026 15:55
e86efdc to
dce293e
Compare
2ynn
force-pushed
the
qynn/feat/python-preserve-unknown-fields
branch
from
October 23, 2026 15:55
a47683e to
189b725
Compare
Generator Snapshot TestingSnapshot tests are running. Snapshot results: https://github.com/speakeasy-api/openapi-generation-snapshots/issues/135#issuecomment-6372136181 |
2ynn
force-pushed
the
qynn/feat/python-preserve-unknown-fields
branch
from
October 23, 2026 17:19
189b725 to
56a8cb5
Compare
4 tasks done
2ynn
changed the base branch from
qynn/fix/python-unrecognized-enum-serialization
to
qynn/fix/python-model-dump-filters
October 23, 2026 17:19
2ynn
marked this pull request as ready for review
October 23, 2026 17:37
4 tasks done
Pydantic drops fields a model does not declare, so undeclared fields in nested JSON request and response bodies were lost on validation and on serialization back to the API. Add python.preserveUnknownFields (default false). When enabled: - generated models and error bodies allow extra fields, including schemas with additionalProperties: false; explicitly typed additional properties still validate - model serializers read each declared field from the key Pydantic emitted (alias or field name, including the alias-keyed output a nested model is serialized from again) and copy the remaining keys back out - marshal_json keeps nested nulls and only excludes a top-level None - UNSET ignores extra fields - generated test assertions compare only the fields their examples declare, since mock responses can carry more; declared additional properties keep their exact key set and are compared recursively basemodel.py becomes a template, so the review SDK copy now passes through the Python formatter. The option is covered by an echo fragment exercised in the primary (disabled), secondary and quaternary variants.
2ynn
force-pushed
the
qynn/fix/python-model-dump-filters
branch
from
October 23, 2026 18:05
9ddfe10 to
7eca0ea
Compare
2ynn
force-pushed
the
qynn/feat/python-preserve-unknown-fields
branch
from
October 23, 2026 18:05
56a8cb5 to
876df5f
Compare
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
Pydantic drops fields a model does not declare. Python SDKs therefore lose undeclared fields in nested JSON request and response bodies: they are not sent to the API, and they disappear from response models, so a response cannot be sent back unchanged.
What changed
Add
python.preserveUnknownFields(defaultfalse). When enabled:additionalProperties: false; explicitly typed additional properties still validate;marshal_jsonkeeps nestednulls and excludes only a top-levelNone; optional fields left unset are still omitted;UNSETignores extra fields;drop_unexpected_fieldstest helper, because mock responses can carry more. Declared additional properties keep their exact key set, and their values are compared the same way.Known limitations
displayNameanddisplay_name), API-name dumps (model_dump(by_alias=True), the request body) keep both keys, but Python-name dumps (the defaultmodel_dump()) show the undeclared value in place of the declared one. Plain Pydantic behaves the same withextra="allow"andpopulate_by_name=True.flattenRequests: false; nested objects keep theirs. The option description states this.exclude_none=Truewithinclude,exclude,exclude_unsetorexclude_defaultscan still write excluded required fields back asNone.types/basemodel.pybecomes a template (basemodel.py.stmpl), so the review SDK copy now goes through the Python formatter. Apart from that formatting, the review SDK gains onlypreserveUnknownFields: falseingen.yaml.Test coverage
unknown-fieldsuber fragment: an echo operation whose body nests objects, arrays, maps, discriminated and plain unions,allOf, open/typed/closed additional properties (including additional properties typed as an object schema), empty objects, open enums and nullable fields, plus a flattened variant and an error response.unknown-fields-json-round-trip, skipped for other targets. The tertiary TypeScript overlay removes the echo operation because its inline success and error bodies get the same generated name in that configuration.flattenRequests: false): request/response round trips for dicts and models, response-only and error-body extras, dump filters, typed additional-properties validation, top-levelNonehandling.flattenRequests: true): nested unknown fields through flattened arguments, sync and async;drop_unexpected_fieldsignores unknown fields inside typed additional-property values but still reports extra map entries and changed values.Stack
preserveUnknownFieldsmodelSerializationMethodsTesting
TARGET=primary make test-pythonv2(option disabled): 723 passed.TARGET=secondary make test-pythonv2: 330 passed, 1 skipped.TARGET=quaternary make test-pythonv2: 256 passed, 1 skipped. The typed additional-properties helper test fails with the previousdrop_unexpected_fields.TARGET=review make build-pythonv2: integrity validation passes.make check-template-pythonv2was run on the top of the stack (feat(python): add modelSerializationMethods option #147), which contains these templates.git diff --checkpasses.TARGET=tertiary make test-pythonv2(option disabled): 214 passed, 1 skipped.Public-safety check
.claude/skills/public-repo-communication/SKILL.md).git diff --check.