mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-23 22:14:18 +02:00
OpenAPI: rewrite $ref under propertyNames and patternProperties in _replace_ref_with_defs; add regression test for dict[StrEnum, Model] (#3306)
* Normalize OpenAPI $ref everywhere (incl. propertyNames); migrate components→$defs; add regression test * Fix: normalize $ref in propertyNames and additionalProperties; add regression test * Deterministic migration: components.schemas override $defs on collision; preserve direct $defs refs via alias; add collision test * Fix: rewrite $ref in propertyNames and patternProperties in _replace_ref_with_defs * Fix syntax error, formatting, and stray files * Skip boolean subschemas in patternProperties --------- Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
This commit is contained in:
parent
2d3d0d5eab
commit
507e6b80ab
2 changed files with 47 additions and 0 deletions
|
|
@ -123,6 +123,19 @@ def _replace_ref_with_defs(
|
|||
schema["additionalProperties"] = _replace_ref_with_defs(
|
||||
additionalProperties
|
||||
)
|
||||
# Handle propertyNames
|
||||
if property_names := schema.get("propertyNames"):
|
||||
if isinstance(property_names, dict):
|
||||
schema["propertyNames"] = _replace_ref_with_defs(property_names)
|
||||
# Handle patternProperties
|
||||
if pattern_properties := schema.get("patternProperties"):
|
||||
if isinstance(pattern_properties, dict):
|
||||
schema["patternProperties"] = {
|
||||
pattern: _replace_ref_with_defs(subschema)
|
||||
if isinstance(subschema, dict)
|
||||
else subschema
|
||||
for pattern, subschema in pattern_properties.items()
|
||||
}
|
||||
if info.get("description", description) and not schema.get("description"):
|
||||
schema["description"] = description
|
||||
return schema
|
||||
|
|
|
|||
34
tests/utilities/openapi/test_propertynames_ref_rewrite.py
Normal file
34
tests/utilities/openapi/test_propertynames_ref_rewrite.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
from fastmcp.utilities.openapi.schemas import _replace_ref_with_defs
|
||||
|
||||
|
||||
def test_replace_ref_with_defs_rewrites_propertyNames_ref():
|
||||
"""
|
||||
Regression test for issue #3303.
|
||||
|
||||
When using dict[StrEnum, Model], Pydantic generates:
|
||||
|
||||
{
|
||||
"type": "object",
|
||||
"propertyNames": {"$ref": "#/components/schemas/Category"},
|
||||
"additionalProperties": {"$ref": "#/components/schemas/ItemInfo"}
|
||||
}
|
||||
|
||||
_replace_ref_with_defs should rewrite BOTH refs to #/$defs/.
|
||||
"""
|
||||
|
||||
schema = {
|
||||
"type": "object",
|
||||
"propertyNames": {"$ref": "#/components/schemas/Category"},
|
||||
"additionalProperties": {"$ref": "#/components/schemas/ItemInfo"},
|
||||
}
|
||||
|
||||
result = _replace_ref_with_defs(schema)
|
||||
|
||||
# additionalProperties ref is rewritten
|
||||
assert result["additionalProperties"]["$ref"] == "#/$defs/ItemInfo"
|
||||
|
||||
# propertyNames ref must also be rewritten (this was the bug)
|
||||
assert result["propertyNames"]["$ref"] == "#/$defs/Category"
|
||||
|
||||
# Ensure no dangling OpenAPI refs remain
|
||||
assert "#/components/schemas/" not in str(result)
|
||||
Loading…
Add table
Add a link
Reference in a new issue