Skip to content

Commit 837b245

Browse files
committed
Add version-specific schema processing using schema_features
1 parent c6b945d commit 837b245

3 files changed

Lines changed: 20 additions & 8 deletions

File tree

src/datamodel_code_generator/parser/jsonschema.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,12 @@ class JSONReference(_enum.Enum):
192192

193193

194194
class Discriminator(BaseModel):
195-
"""Represent OpenAPI discriminator object."""
195+
"""Represent OpenAPI discriminator object.
196+
197+
This is an OpenAPI-specific concept for supporting polymorphism.
198+
It identifies which schema applies based on a property value.
199+
Kept in jsonschema.py to avoid circular imports with openapi.py.
200+
"""
196201

197202
propertyName: str # noqa: N815
198203
mapping: Optional[dict[str, str]] = None # noqa: UP045
@@ -517,7 +522,7 @@ def _get_type(
517522
data_formats: dict[str, dict[str, Types]] | None = None,
518523
) -> Types:
519524
"""Get the appropriate Types enum for a given JSON Schema type and format."""
520-
if data_formats is None:
525+
if data_formats is None: # pragma: no cover
521526
data_formats = json_schema_data_formats
522527
if type_ not in data_formats:
523528
return Types.any
@@ -3575,9 +3580,15 @@ def parse_id(self, obj: JsonSchemaObject, path: list[str]) -> None:
35753580

35763581
@contextmanager
35773582
def root_id_context(self, root_raw: dict[str, Any]) -> Generator[None, None, None]:
3578-
"""Context manager to temporarily set the root $id during parsing."""
3583+
"""Context manager to temporarily set the root $id during parsing.
3584+
3585+
Uses schema_features.id_field to support both "id" (Draft 4) and "$id" (Draft 6+).
3586+
Falls back to checking both fields for lenient compatibility.
3587+
"""
35793588
previous_root_id = self.root_id
3580-
self.root_id = root_raw.get("$id") or None
3589+
# Try version-specific field first, then fallback to alternative for compatibility
3590+
id_field = self.schema_features.id_field
3591+
self.root_id = root_raw.get(id_field) or root_raw.get("$id") or root_raw.get("id") or None
35813592
yield
35823593
self.root_id = previous_root_id
35833594

src/datamodel_code_generator/parser/openapi.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,11 @@ def get_ref_model(self, ref: str) -> dict[str, Any]:
243243

244244
def get_data_type(self, obj: JsonSchemaObject) -> DataType:
245245
"""Get data type from JSON schema object, handling OpenAPI nullable semantics."""
246-
# OpenAPI 3.0 doesn't allow `null` in the `type` field and list of types
246+
# OpenAPI 3.0 uses `nullable: true` flag for null support (nullable_keyword=True)
247+
# OpenAPI 3.1 uses `type: ["string", "null"]` instead (nullable_keyword=False)
247248
# https://swagger.io/docs/specification/data-models/data-types/#null
248-
# OpenAPI 3.1 does allow `null` in the `type` field and is equivalent to
249-
# a `nullable` flag on the property itself
249+
# When strict_nullable is enabled, convert nullable flag to type array for
250+
# consistent handling regardless of OpenAPI version
250251
if obj.nullable and self.strict_nullable and isinstance(obj.type, str):
251252
obj.type = [obj.type, "null"]
252253

src/datamodel_code_generator/parser/schema_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ def get_data_formats(*, is_openapi: bool = False) -> DataFormatMapping:
272272
for type_key, type_formats in _get_openapi_only_formats().items():
273273
if type_key in formats:
274274
formats[type_key] = {**formats[type_key], **type_formats}
275-
else:
275+
else: # pragma: no cover
276276
formats[type_key] = type_formats
277277
return formats
278278

0 commit comments

Comments
 (0)