fix: enforce uniqueItems on generated array fields - #59
Open
XiaolongZhang-TT wants to merge 1 commit into
Open
Conversation
datamodel-code-generator drops `uniqueItems`, so generated list fields accept duplicate entries in violation of the schema. Three UCP array properties declare `uniqueItems: true` at 2026-04-08: context.eligibility, card_payment_instrument.brands, and identity_linking.required_claims. Extend postprocess_models.py to collect array property names declared with `uniqueItems` and inject a `field_validator(mode="after")` into each generated class that declares a matching list field. The check uses equality (`item in seen`) so it holds for both hashable (str) and unhashable (model) items. Mirrors the data-driven, idempotent approach used for minProperties (Universal-Commerce-Protocol#55). Two generated models carry the affected list fields and gain the validator: Context.eligibility and Constraints.brands. required_claims has no generated typed field (ScopePolicy is extra="allow" free-form), so it is not enforceable and is skipped. Add UniqueItemsInjectorTest (scan walks nested properties and ignores non-arrays; injection targets only matching list fields, is idempotent, and enforces uniqueness when exec'd) and UniqueItemsSemanticTest (Constraints rejects duplicate brands, accepts unique/None).
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.
Description
datamodel-code-generatordropsuniqueItems, so generated list fields accept duplicate entries in violation of the schema. Three UCP array properties declareuniqueItems: trueat the2026-04-08release this SDK targets:context.eligibility,card_payment_instrument.brands, andidentity_linking.required_claims.This extends
postprocess_models.pyto collect array property names declared withuniqueItemsand inject afield_validator(mode="after")into each generated class that declares a matching list field. The check uses equality (item in seen) rather than aset, so it holds for both hashable (str) and unhashable (Pydantic model) items. It mirrors the data-driven, idempotent approach already used forminProperties(#55), and complements the opencontainswork in #57 — the third constraint the generator drops.Two generated models carry the affected list fields and gain the validator:
Context.eligibilityandConstraints.brands.required_claimshas no generated typed field (ScopePolicyisextra="allow"free-form, so the field is an untyped extra key), so it is not enforceable and is skipped. Verified against the realrelease/2026-04-08schemas that exactly these two models are touched on a fresh tree.Note: like #57, this modifies
postprocess_models.py, so it may need a rebase if #57 lands first.Category (Required)
Please select one or more categories that apply to this change.
ucp-schematool (resolver, linter, validator). (Requires Maintainer approval)Related Issues
None. (Follow-up to the constraint-enforcement work in #55; complements the open
containsenforcement in #57.)Checklist
!for breaking changes).Screenshots / Logs (if applicable)
The injected validator (e.g.
Constraints.brands):Before:
Constraints(brands=["visa", "visa"])was accepted. After: it raisesValidationError("Items must be unique").postprocessrun reports:uniqueItems fields ['brands', 'eligibility', 'required_claims'] -> 2 module(s) patched (context.py, card_payment_instrument.py).Full suite green as CI runs it (
python -m unittest discover -s tests -p "test_*.py"): 35 passed, 0 failed. ruff (--ignore D,E501, matching the pre-commit hook),ruff format, and codespell are clean.