Skip to content

Commit 599ae84

Browse files
authored
Fix handling of empty enums to return null type when not nullable and add tests for null-only enum generation (#2674)
1 parent f42c49f commit 599ae84

5 files changed

Lines changed: 82 additions & 0 deletions

File tree

src/datamodel_code_generator/parser/jsonschema.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2567,6 +2567,46 @@ def parse_enum(
25672567
)
25682568
)
25692569

2570+
if not enum_fields:
2571+
if not nullable:
2572+
return self.data_type_manager.get_data_type(Types.null)
2573+
name = self._apply_title_as_name(name, obj)
2574+
reference = self.model_resolver.add(
2575+
path,
2576+
name,
2577+
class_name=True,
2578+
singular_name=singular_name,
2579+
singular_name_suffix="Enum",
2580+
loaded=True,
2581+
)
2582+
data_model_root_type = self.data_model_root_type(
2583+
reference=reference,
2584+
fields=[
2585+
self.data_model_field_type(
2586+
data_type=self.data_type_manager.get_data_type(Types.null),
2587+
default=obj.default,
2588+
required=False,
2589+
nullable=True,
2590+
strip_default_none=self.strip_default_none,
2591+
extras=self.get_field_extras(obj),
2592+
use_annotated=self.use_annotated,
2593+
has_default=obj.has_default,
2594+
use_field_description=self.use_field_description,
2595+
use_inline_field_description=self.use_inline_field_description,
2596+
original_name=None,
2597+
)
2598+
],
2599+
custom_base_class=obj.custom_base_path or self.base_class,
2600+
custom_template_dir=self.custom_template_dir,
2601+
extra_template_data=self.extra_template_data,
2602+
path=self.current_source_path,
2603+
default=obj.default if obj.has_default else UNDEFINED,
2604+
nullable=obj.type_has_null,
2605+
treat_dot_as_module=self.treat_dot_as_module,
2606+
)
2607+
self.results.append(data_model_root_type)
2608+
return self.data_type(reference=reference)
2609+
25702610
def create_enum(reference_: Reference) -> DataType:
25712611
type_: Types | None = (
25722612
self._get_type_with_mappings(obj.type, obj.format) if isinstance(obj.type, str) else None
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# generated by datamodel-codegen:
2+
# filename: null_only_enum.yaml
3+
# timestamp: 2019-07-26T00:00:00+00:00
4+
5+
from __future__ import annotations
6+
7+
from pydantic import BaseModel
8+
9+
10+
class NullEnum(BaseModel):
11+
__root__: None = None
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
openapi: 3.0.1
2+
info:
3+
title: Null Only Enum Test
4+
version: 1.0.0
5+
paths: {}
6+
components:
7+
schemas:
8+
NullEnum:
9+
type: string
10+
enum:
11+
- null
12+
nullable: true

tests/main/openapi/test_main_openapi.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4172,3 +4172,14 @@ def test_main_unique_items_default_set(output_model: str, expected_output: str,
41724172
expected_file=expected_output,
41734173
extra_args=["--output-model-type", output_model, "--use-unique-items-as-set"],
41744174
)
4175+
4176+
4177+
def test_main_openapi_null_only_enum(output_file: Path) -> None:
4178+
"""Test OpenAPI generation with enum containing only null value."""
4179+
run_main_and_assert(
4180+
input_path=OPEN_API_DATA_PATH / "null_only_enum.yaml",
4181+
output_path=output_file,
4182+
input_file_type="openapi",
4183+
assert_func=assert_file_content,
4184+
expected_file="null_only_enum.py",
4185+
)

tests/parser/test_jsonschema.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -921,3 +921,11 @@ def test_parse_combined_schema_anyof_with_ref_and_schema_keywords() -> None:
921921
parser.parse_raw_obj("Model", schema, [])
922922
results = list(parser.results)
923923
assert len(results) >= 1
924+
925+
926+
def test_parse_enum_empty_enum_not_nullable() -> None:
927+
"""Test parse_enum returns null type when enum_fields is empty and not nullable."""
928+
parser = JsonSchemaParser("")
929+
obj = JsonSchemaObject.parse_obj({"type": "integer", "enum": []})
930+
result = parser.parse_enum("EmptyEnum", obj, ["EmptyEnum"])
931+
assert result.type == "None"

0 commit comments

Comments
 (0)