Repository navigation
fix(lib): keep description and title beside $ref in transform_schema - #2017
Parsiffall1 wants to merge 2 commits into
Conversation
Pydantic places Field(description=...) next to $ref for enum and model fields. transform_schema previously early-returned on $ref and dropped those siblings, so the descriptions never reached the API. Preserve description and title on the $ref early-return path, matching how they are handled for other schema shapes. Add regression tests.
f6b5a5f to
6b7bcb8
Compare
chrikrah
left a comment
There was a problem hiding this comment.
@Parsiffall1 I'd merge this. With pydantic 2.12.5 every enum or model field that carries Field(description=...) loses it at b4b7916, and at 6b7bcb8 all three come through.
$ python -I probe2017.py # Answer model: level, lvl_default (enum), inner (model), maybe (Optional[enum])
# origin/main b4b7916
{"level": {"$ref": "#/$defs/Level"}, "lvl_default": {"$ref": "#/$defs/Level"}, "inner": {"$ref": "#/$defs/Inner"}, "maybe": {"anyOf": [...], "description": "Optional enum.\n\n{default: None}"}}
# PR head 6b7bcb8
{"level": {"$ref": "#/$defs/Level", "description": "Always choose low."}, "lvl_default": {"$ref": "#/$defs/Level", "description": "Defaulted."}, "inner": {"$ref": "#/$defs/Inner", "description": "Nested model."}, "maybe": ...unchanged}
$ pytest tests/lib/_parse/test_transform.py -q
16 passed # PR head
2 failed, 14 passed # same tests, _transform.py from b4b7916
FAILED ...::test_ref_schema_preserves_sibling_title
FAILED ...::test_ref_schema_preserves_sibling_description
$ ruff check src/anthropic/lib/_parse tests/lib/_parse # ruff 0.15.6
All checks passed!
# not run: a live request, so whether the API honours a description beside $ref rests on the PR's word
non-blocking: lvl_default above is pydantic's {"$ref": ..., "default": "low", "description": ...}, and the default still vanishes. Every other branch folds a leftover keyword into the description (maybe gets {default: None}), so the $ref branch is now the one place that drops it without a trace. I'd run that same fold before this return. It can't simply fall through, since the type check below would raise. Tried locally: lvl_default becomes "Defaulted.\n\n{default: low}" and the 16 tests still pass. Fine as a follow-up if you'd keep this diff to the two keys.
@dtmeadows-ant the open call is yours: fold default into this PR, or take it as a separate one after the merge?
Summary
transform_schemaearly-returned on$refand dropped sibling keywords. Pydantic putsField(description=...)(and sometimestitle) beside$reffor enum and model fields, so those descriptions never reached the API even though the API accepts and follows them.This change preserves
descriptionandtitleon the$refearly-return path, consistent with how they are kept for other schema shapes.Fixes #2016
Test plan
pytest tests/lib/_parse/test_transform.py— 16 passed (includes two new regression cases)Field(description=...)on an enum field survivestransform_schema(Answer)["properties"]["level"]