Skip to content

Commit 61b38e9

Browse files
Fix import handling in --collapse-root-models to exclude both Optional and Union (#2597)
* Fix handling of Optional imports in collapse-root-models functionality * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix import handling by using a list to exclude non-hashable imports in collapse-root-models --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 9b40ee7 commit 61b38e9

4 files changed

Lines changed: 50 additions & 6 deletions

File tree

src/datamodel_code_generator/parser/base.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
IMPORT_ANNOTATIONS,
4040
IMPORT_LITERAL,
4141
IMPORT_OPTIONAL,
42+
IMPORT_UNION,
4243
Import,
4344
Imports,
4445
)
@@ -1285,7 +1286,10 @@ def __collapse_root_models( # noqa: PLR0912
12851286
original_field = get_most_of_parent(data_type, DataModelFieldBase)
12861287
if original_field: # pragma: no cover
12871288
# TODO: Improve detection of reference type
1288-
imports.append([i for i in original_field.imports if i != IMPORT_OPTIONAL])
1289+
# Use list instead of set because Import is not hashable
1290+
excluded_imports = [IMPORT_OPTIONAL, IMPORT_UNION]
1291+
field_imports = [i for i in original_field.imports if i not in excluded_imports]
1292+
imports.append(field_imports)
12891293

12901294
data_type.remove_reference()
12911295

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# generated by datamodel-codegen:
2+
# filename: collapse_root_models_with_optional.json
3+
# timestamp: 2019-07-26T00:00:00+00:00
4+
5+
from __future__ import annotations
6+
7+
from typing import Optional
8+
9+
from pydantic import BaseModel
10+
11+
12+
class Model(BaseModel):
13+
field: Optional[str] = None
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"type": "object",
4+
"properties": {
5+
"field": {
6+
"anyOf": [
7+
{"$ref": "#/$defs/StringType"},
8+
{"$ref": "#/$defs/NullType"}
9+
]
10+
}
11+
},
12+
"$defs": {
13+
"StringType": {
14+
"type": "string"
15+
},
16+
"NullType": {
17+
"type": "null"
18+
}
19+
}
20+
}

tests/main/jsonschema/test_main_jsonschema.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2988,15 +2988,22 @@ def test_main_jsonschema_enum_object_values(output_file: Path) -> None:
29882988

29892989

29902990
def test_main_jsonschema_collapse_root_models_empty_union(output_file: Path) -> None:
2991-
"""Test that collapse-root-models with empty union fallback generates Any instead of invalid Union syntax.
2992-
2993-
This test covers the fix for issue #2161 where --collapse-root-models could generate
2994-
invalid Python syntax like Union[, str] when all union members are filtered out.
2995-
"""
2991+
"""Test that collapse-root-models with empty union fallback generates Any instead of invalid Union syntax."""
29962992
run_main_and_assert(
29972993
input_path=JSON_SCHEMA_DATA_PATH / "collapse_root_models_empty_union.json",
29982994
output_path=output_file,
29992995
input_file_type="jsonschema",
30002996
assert_func=assert_file_content,
30012997
extra_args=["--collapse-root-models"],
30022998
)
2999+
3000+
3001+
def test_main_jsonschema_collapse_root_models_with_optional(output_file: Path) -> None:
3002+
"""Test that collapse-root-models correctly preserves Optional import when needed."""
3003+
run_main_and_assert(
3004+
input_path=JSON_SCHEMA_DATA_PATH / "collapse_root_models_with_optional.json",
3005+
output_path=output_file,
3006+
input_file_type="jsonschema",
3007+
assert_func=assert_file_content,
3008+
extra_args=["--collapse-root-models"],
3009+
)

0 commit comments

Comments
 (0)