Skip to content

Commit 9554fb6

Browse files
kkinugasakkinugasakoxudaxi
authored
Fix handling of falsy default values for enums in set-default-enum-member option (#2977)
* Fix handling of falsy default values for enums and model fields * Add tests and JSON schema for handling falsy default enum values * simplify handling default field values in Enum class * rename test file name * remove unnecessary freeze_time with statement * test: add boolean false case to falsy default enum member fixture --------- Co-authored-by: kkinugasa <k-kinugasa@boostry.o.jp> Co-authored-by: Koudai Aono <koxudaxi@gmail.com>
1 parent 1d6bdee commit 9554fb6

5 files changed

Lines changed: 80 additions & 2 deletions

File tree

src/datamodel_code_generator/model/enum.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def find_member(self, value: Any) -> Member | None:
103103

104104
for field in self.fields:
105105
# Remove surrounding quotes from field default value
106-
field_default = str(field.default or "").strip("'\"")
106+
field_default = "" if field.default is None else str(field.default).strip("'\"")
107107

108108
# Compare values after removing quotes
109109
if field_default == str_value:

src/datamodel_code_generator/parser/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2059,7 +2059,7 @@ def __set_default_enum_member(
20592059
if not self.set_default_enum_member:
20602060
return
20612061
for _, model_field, data_type in iter_models_field_data_types(models):
2062-
if not model_field.default:
2062+
if model_field.default is None:
20632063
continue
20642064
if data_type.reference and isinstance(data_type.reference.source, Enum): # pragma: no cover
20652065
if isinstance(model_field.default, list):
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# generated by datamodel-codegen:
2+
# filename: falsy_default_enum_member.json
3+
# timestamp: 2019-07-26T00:00:00+00:00
4+
5+
from __future__ import annotations
6+
7+
from enum import Enum, IntEnum
8+
9+
from pydantic import BaseModel
10+
11+
12+
class Status(IntEnum):
13+
integer_0 = 0
14+
integer_1 = 1
15+
16+
17+
class Name(Enum):
18+
field_ = ''
19+
non_empty = 'non-empty'
20+
21+
22+
class Active(Enum):
23+
boolean_True = True
24+
boolean_False = False
25+
26+
27+
class Model(BaseModel):
28+
status: Status | None = Status.integer_0
29+
name: Name | None = Name.field_
30+
active: Active | None = Active.boolean_False
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"title": "Model",
4+
"type": "object",
5+
"properties": {
6+
"status": {
7+
"$ref": "#/$defs/Status",
8+
"default": 0
9+
},
10+
"name": {
11+
"$ref": "#/$defs/Name",
12+
"default": ""
13+
},
14+
"active": {
15+
"$ref": "#/$defs/Active",
16+
"default": false
17+
}
18+
},
19+
"$defs": {
20+
"Status": {
21+
"title": "Status",
22+
"type": "integer",
23+
"enum": [0, 1]
24+
},
25+
"Name": {
26+
"title": "Name",
27+
"type": "string",
28+
"enum": ["", "non-empty"]
29+
},
30+
"Active": {
31+
"title": "Active",
32+
"type": "boolean",
33+
"enum": [true, false]
34+
}
35+
}
36+
}

tests/main/jsonschema/test_main_jsonschema.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3299,6 +3299,18 @@ def test_main_jsonschema_modular_default_enum_member(output_dir: Path) -> None:
32993299
)
33003300

33013301

3302+
def test_main_jsonschema_falsy_default_enum_member(output_file: Path) -> None:
3303+
"""Test enum member mapping for falsy default values."""
3304+
run_main_and_assert(
3305+
input_path=JSON_SCHEMA_DATA_PATH / "falsy_default_enum_member.json",
3306+
output_path=output_file,
3307+
input_file_type="jsonschema",
3308+
assert_func=assert_file_content,
3309+
expected_file="falsy_default_enum_member.py",
3310+
extra_args=["--set-default-enum-member"],
3311+
)
3312+
3313+
33023314
@pytest.mark.skipif(
33033315
black.__version__.split(".")[0] < "22",
33043316
reason="Installed black doesn't support Python version 3.10",

0 commit comments

Comments
 (0)