Skip to content

Commit 936e6a8

Browse files
committed
Fix empty list default for GraphQL list fields
1 parent 4fa0727 commit 936e6a8

4 files changed

Lines changed: 39 additions & 16 deletions

File tree

src/datamodel_code_generator/model/pydantic/base_model.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,23 @@ def _get_strict_field_constraint_value(self, constraint: str, value: Any) -> Any
126126
return value
127127
return int(value)
128128

129-
def _get_default_as_pydantic_model(self) -> str | None:
129+
def _get_default_as_pydantic_model(self) -> str | None: # noqa: PLR0911, PLR0912
130130
if isinstance(self.default, WrappedDefault):
131131
return f"lambda :{self.default!r}"
132+
# Handle the case where self.data_type.is_list is True directly (e.g., GraphQL)
133+
if self.data_type.is_list and len(self.data_type.data_types) == 1:
134+
data_type_child = self.data_type.data_types[0]
135+
if (
136+
data_type_child.reference
137+
and isinstance(data_type_child.reference.source, BaseModelBase)
138+
and isinstance(self.default, list)
139+
):
140+
if not self.default:
141+
return STANDARD_LIST
142+
return ( # pragma: no cover
143+
f"lambda :[{data_type_child.alias or data_type_child.reference.source.class_name}."
144+
f"{self._PARSE_METHOD}(v) for v in {self.default!r}]"
145+
)
132146
for data_type in self.data_type.data_types or (self.data_type,):
133147
# TODO: Check nested data_types
134148
if data_type.is_dict:

tests/data/expected/main/graphql/empty_list_default.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,26 @@
77
from typing import Literal
88

99
from pydantic import BaseModel, Field
10+
from typing_extensions import TypeAliasType
1011

12+
Boolean = TypeAliasType("Boolean", bool)
13+
"""
14+
The `Boolean` scalar type represents `true` or `false`.
15+
"""
1116

12-
class Container(BaseModel):
13-
name: str
14-
typename__: Literal['Container'] | None = Field('Container', alias='__typename')
1517

18+
String = TypeAliasType("String", str)
19+
"""
20+
The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
21+
"""
1622

17-
class PodSpec(BaseModel):
18-
container_list: list[Container] = Field(default_factory=list)
19-
container_list_or_none: list[Container | None] = Field(default_factory=list)
20-
container_or_none_list_or_none: list[Container | None] | None = Field(default_factory=list)
21-
typename__: Literal['PodSpec'] | None = Field('PodSpec', alias='__typename')
23+
24+
class TagInput(BaseModel):
25+
name: String
26+
value: String
27+
typename__: Literal['TagInput'] | None = Field('TagInput', alias='__typename')
28+
29+
30+
class ModelInput(BaseModel):
31+
tags: list[TagInput] | None = Field(default_factory=list)
32+
typename__: Literal['ModelInput'] | None = Field('ModelInput', alias='__typename')
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
2-
input Container {
1+
input TagInput {
32
name: String!
3+
value: String!
44
}
55

6-
input PodSpec {
7-
container_list: [Container!]! = []
8-
container_list_or_none: [Container]! = []
9-
container_or_none_list_or_none: [Container] = []
6+
input ModelInput {
7+
tags: [TagInput!] = []
108
}

tests/main/graphql/test_main_graphql.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
EXPECTED_GRAPHQL_PATH,
1313
GRAPHQL_DATA_PATH,
1414
LEGACY_BLACK_SKIP,
15-
run_main_and_assert
15+
run_main_and_assert,
1616
)
1717
from tests.main.graphql.conftest import assert_file_content
1818

0 commit comments

Comments
 (0)