Skip to content

Commit 43eb240

Browse files
committed
Exclude OpenAPI/JSON Schema extension fields (x-*)
1 parent 09b36f2 commit 43eb240

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

src/datamodel_code_generator/parser/jsonschema.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,14 +454,19 @@ def has_ref_with_schema_keywords(self) -> bool:
454454
"""Check if schema has $ref combined with schema-affecting keywords.
455455
456456
Metadata-only keywords (title, description, etc.) are excluded
457-
as they don't affect the schema structure.
457+
as they don't affect the schema structure. OpenAPI/JSON Schema
458+
extension fields (x-*) are also excluded as they are vendor
459+
extensions and don't affect the core schema structure.
458460
"""
459461
if not self.ref:
460462
return False
461463
other_fields = get_fields_set(self) - {"ref"}
462464
schema_affecting_fields = other_fields - self.__metadata_only_fields__ - {"extras"}
463465
if self.extras:
464-
schema_affecting_extras = {k for k in self.extras if k not in self.__metadata_only_fields__}
466+
# Filter out metadata-only fields AND extension fields (x-* prefix)
467+
schema_affecting_extras = {
468+
k for k in self.extras if k not in self.__metadata_only_fields__ and not k.startswith("x-")
469+
}
465470
if schema_affecting_extras:
466471
schema_affecting_fields |= {"extras"}
467472
return bool(schema_affecting_fields)

tests/parser/test_jsonschema.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,28 @@ def test_has_ref_with_schema_keywords_extras_with_metadata_only_keys() -> None:
910910
assert obj.has_ref_with_schema_keywords is False
911911

912912

913+
def test_has_ref_with_schema_keywords_extras_with_extension_keys() -> None:
914+
"""Test has_ref_with_schema_keywords when extras contains only x-* extension keys.
915+
916+
OpenAPI/JSON Schema extension fields (x-*) should be treated as metadata
917+
and not trigger schema merging, which prevents infinite recursion with
918+
self-referencing schemas.
919+
"""
920+
# x-* extensions are vendor extensions, should not trigger merge
921+
obj = JsonSchemaObject.parse_obj({
922+
"$ref": "#/$defs/Base",
923+
"deprecated": False, # metadata-only field
924+
"x-internalAPI": False, # extension field
925+
"x-custom-field": "value", # another extension field
926+
})
927+
# Verify extras contains extension keys
928+
assert obj.extras
929+
assert "x-internalAPI" in obj.extras
930+
assert "x-custom-field" in obj.extras
931+
# Extension fields should NOT trigger schema merge
932+
assert obj.has_ref_with_schema_keywords is False
933+
934+
913935
def test_has_ref_with_schema_keywords_no_extras() -> None:
914936
"""Test has_ref_with_schema_keywords when extras is empty."""
915937
# Only $ref and a schema-affecting field, no extras

0 commit comments

Comments
 (0)