datamodel-code-generator 0.27.2__py3-none-any.whl → 0.28.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of datamodel-code-generator might be problematic. Click here for more details.

Files changed (43) hide show
  1. datamodel_code_generator/__init__.py +168 -196
  2. datamodel_code_generator/__main__.py +146 -189
  3. datamodel_code_generator/arguments.py +227 -230
  4. datamodel_code_generator/format.py +77 -129
  5. datamodel_code_generator/http.py +12 -10
  6. datamodel_code_generator/imports.py +59 -65
  7. datamodel_code_generator/model/__init__.py +28 -31
  8. datamodel_code_generator/model/base.py +100 -144
  9. datamodel_code_generator/model/dataclass.py +62 -70
  10. datamodel_code_generator/model/enum.py +34 -30
  11. datamodel_code_generator/model/imports.py +13 -11
  12. datamodel_code_generator/model/msgspec.py +116 -138
  13. datamodel_code_generator/model/pydantic/__init__.py +18 -28
  14. datamodel_code_generator/model/pydantic/base_model.py +121 -140
  15. datamodel_code_generator/model/pydantic/custom_root_type.py +2 -2
  16. datamodel_code_generator/model/pydantic/dataclass.py +6 -4
  17. datamodel_code_generator/model/pydantic/imports.py +35 -33
  18. datamodel_code_generator/model/pydantic/types.py +91 -119
  19. datamodel_code_generator/model/pydantic_v2/__init__.py +21 -18
  20. datamodel_code_generator/model/pydantic_v2/base_model.py +118 -127
  21. datamodel_code_generator/model/pydantic_v2/imports.py +5 -3
  22. datamodel_code_generator/model/pydantic_v2/root_model.py +6 -6
  23. datamodel_code_generator/model/pydantic_v2/types.py +11 -7
  24. datamodel_code_generator/model/rootmodel.py +1 -1
  25. datamodel_code_generator/model/scalar.py +33 -32
  26. datamodel_code_generator/model/typed_dict.py +41 -51
  27. datamodel_code_generator/model/types.py +24 -19
  28. datamodel_code_generator/model/union.py +21 -17
  29. datamodel_code_generator/parser/__init__.py +16 -12
  30. datamodel_code_generator/parser/base.py +327 -515
  31. datamodel_code_generator/parser/graphql.py +87 -119
  32. datamodel_code_generator/parser/jsonschema.py +438 -607
  33. datamodel_code_generator/parser/openapi.py +180 -220
  34. datamodel_code_generator/pydantic_patch.py +8 -9
  35. datamodel_code_generator/reference.py +199 -297
  36. datamodel_code_generator/types.py +149 -215
  37. datamodel_code_generator/util.py +23 -36
  38. {datamodel_code_generator-0.27.2.dist-info → datamodel_code_generator-0.28.0.dist-info}/METADATA +10 -5
  39. datamodel_code_generator-0.28.0.dist-info/RECORD +59 -0
  40. datamodel_code_generator-0.27.2.dist-info/RECORD +0 -59
  41. {datamodel_code_generator-0.27.2.dist-info → datamodel_code_generator-0.28.0.dist-info}/WHEEL +0 -0
  42. {datamodel_code_generator-0.27.2.dist-info → datamodel_code_generator-0.28.0.dist-info}/entry_points.txt +0 -0
  43. {datamodel_code_generator-0.27.2.dist-info → datamodel_code_generator-0.28.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,38 +1,40 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import sys
4
- from typing import TYPE_CHECKING, Callable, Iterable, List, NamedTuple, Optional, Type
4
+ from typing import TYPE_CHECKING, Callable, NamedTuple
5
+
6
+ from datamodel_code_generator import DatetimeClassType, PythonVersion
5
7
 
6
- from .. import DatetimeClassType, PythonVersion
7
- from ..types import DataTypeManager as DataTypeManagerABC
8
8
  from .base import ConstraintsBase, DataModel, DataModelFieldBase
9
9
 
10
10
  if TYPE_CHECKING:
11
- from .. import DataModelType
11
+ from collections.abc import Iterable
12
+
13
+ from datamodel_code_generator import DataModelType
14
+ from datamodel_code_generator.types import DataTypeManager as DataTypeManagerABC
12
15
 
13
16
  DEFAULT_TARGET_DATETIME_CLASS = DatetimeClassType.Datetime
14
- DEFAULT_TARGET_PYTHON_VERSION = PythonVersion(
15
- f'{sys.version_info.major}.{sys.version_info.minor}'
16
- )
17
+ DEFAULT_TARGET_PYTHON_VERSION = PythonVersion(f"{sys.version_info.major}.{sys.version_info.minor}")
17
18
 
18
19
 
19
20
  class DataModelSet(NamedTuple):
20
- data_model: Type[DataModel]
21
- root_model: Type[DataModel]
22
- field_model: Type[DataModelFieldBase]
23
- data_type_manager: Type[DataTypeManagerABC]
24
- dump_resolve_reference_action: Optional[Callable[[Iterable[str]], str]]
25
- known_third_party: Optional[List[str]] = None
21
+ data_model: type[DataModel]
22
+ root_model: type[DataModel]
23
+ field_model: type[DataModelFieldBase]
24
+ data_type_manager: type[DataTypeManagerABC]
25
+ dump_resolve_reference_action: Callable[[Iterable[str]], str] | None
26
+ known_third_party: list[str] | None = None
26
27
 
27
28
 
28
29
  def get_data_model_types(
29
30
  data_model_type: DataModelType,
30
31
  target_python_version: PythonVersion = DEFAULT_TARGET_PYTHON_VERSION,
31
- target_datetime_class: Optional[DatetimeClassType] = None,
32
+ target_datetime_class: DatetimeClassType | None = None,
32
33
  ) -> DataModelSet:
33
- from .. import DataModelType
34
- from . import dataclass, msgspec, pydantic, pydantic_v2, rootmodel, typed_dict
35
- from .types import DataTypeManager
34
+ from datamodel_code_generator import DataModelType # noqa: PLC0415
35
+
36
+ from . import dataclass, msgspec, pydantic, pydantic_v2, rootmodel, typed_dict # noqa: PLC0415
37
+ from .types import DataTypeManager # noqa: PLC0415
36
38
 
37
39
  if target_datetime_class is None:
38
40
  target_datetime_class = DEFAULT_TARGET_DATETIME_CLASS
@@ -44,7 +46,7 @@ def get_data_model_types(
44
46
  data_type_manager=pydantic.DataTypeManager,
45
47
  dump_resolve_reference_action=pydantic.dump_resolve_reference_action,
46
48
  )
47
- elif data_model_type == DataModelType.PydanticV2BaseModel:
49
+ if data_model_type == DataModelType.PydanticV2BaseModel:
48
50
  return DataModelSet(
49
51
  data_model=pydantic_v2.BaseModel,
50
52
  root_model=pydantic_v2.RootModel,
@@ -52,7 +54,7 @@ def get_data_model_types(
52
54
  data_type_manager=pydantic_v2.DataTypeManager,
53
55
  dump_resolve_reference_action=pydantic_v2.dump_resolve_reference_action,
54
56
  )
55
- elif data_model_type == DataModelType.DataclassesDataclass:
57
+ if data_model_type == DataModelType.DataclassesDataclass:
56
58
  return DataModelSet(
57
59
  data_model=dataclass.DataClass,
58
60
  root_model=rootmodel.RootModel,
@@ -60,13 +62,9 @@ def get_data_model_types(
60
62
  data_type_manager=dataclass.DataTypeManager,
61
63
  dump_resolve_reference_action=None,
62
64
  )
63
- elif data_model_type == DataModelType.TypingTypedDict:
65
+ if data_model_type == DataModelType.TypingTypedDict:
64
66
  return DataModelSet(
65
- data_model=(
66
- typed_dict.TypedDict
67
- if target_python_version.has_typed_dict
68
- else typed_dict.TypedDictBackport
69
- ),
67
+ data_model=typed_dict.TypedDict,
70
68
  root_model=rootmodel.RootModel,
71
69
  field_model=(
72
70
  typed_dict.DataModelField
@@ -76,18 +74,17 @@ def get_data_model_types(
76
74
  data_type_manager=DataTypeManager,
77
75
  dump_resolve_reference_action=None,
78
76
  )
79
- elif data_model_type == DataModelType.MsgspecStruct:
77
+ if data_model_type == DataModelType.MsgspecStruct:
80
78
  return DataModelSet(
81
79
  data_model=msgspec.Struct,
82
80
  root_model=msgspec.RootModel,
83
81
  field_model=msgspec.DataModelField,
84
82
  data_type_manager=msgspec.DataTypeManager,
85
83
  dump_resolve_reference_action=None,
86
- known_third_party=['msgspec'],
84
+ known_third_party=["msgspec"],
87
85
  )
88
- raise ValueError(
89
- f'{data_model_type} is unsupported data model type'
90
- ) # pragma: no cover
86
+ msg = f"{data_model_type} is unsupported data model type"
87
+ raise ValueError(msg) # pragma: no cover
91
88
 
92
89
 
93
- __all__ = ['ConstraintsBase', 'DataModel', 'DataModelFieldBase']
90
+ __all__ = ["ConstraintsBase", "DataModel", "DataModelFieldBase"]
@@ -1,23 +1,11 @@
1
+ from __future__ import annotations
2
+
1
3
  from abc import ABC, abstractmethod
2
4
  from collections import defaultdict
3
5
  from copy import deepcopy
4
- from functools import lru_cache
6
+ from functools import cached_property, lru_cache
5
7
  from pathlib import Path
6
- from typing import (
7
- TYPE_CHECKING,
8
- Any,
9
- ClassVar,
10
- DefaultDict,
11
- Dict,
12
- FrozenSet,
13
- Iterator,
14
- List,
15
- Optional,
16
- Set,
17
- Tuple,
18
- TypeVar,
19
- Union,
20
- )
8
+ from typing import TYPE_CHECKING, Any, ClassVar, Optional, TypeVar
21
9
  from warnings import warn
22
10
 
23
11
  from jinja2 import Environment, FileSystemLoader, Template
@@ -25,7 +13,6 @@ from pydantic import Field
25
13
 
26
14
  from datamodel_code_generator.imports import (
27
15
  IMPORT_ANNOTATED,
28
- IMPORT_ANNOTATED_BACKPORT,
29
16
  IMPORT_OPTIONAL,
30
17
  IMPORT_UNION,
31
18
  Import,
@@ -40,20 +27,23 @@ from datamodel_code_generator.types import (
40
27
  chain_as_tuple,
41
28
  get_optional_type,
42
29
  )
43
- from datamodel_code_generator.util import PYDANTIC_V2, ConfigDict, cached_property
30
+ from datamodel_code_generator.util import PYDANTIC_V2, ConfigDict
44
31
 
45
- TEMPLATE_DIR: Path = Path(__file__).parents[0] / 'template'
32
+ if TYPE_CHECKING:
33
+ from collections.abc import Iterator
46
34
 
47
- ALL_MODEL: str = '#all#'
35
+ TEMPLATE_DIR: Path = Path(__file__).parents[0] / "template"
48
36
 
49
- ConstraintsBaseT = TypeVar('ConstraintsBaseT', bound='ConstraintsBase')
37
+ ALL_MODEL: str = "#all#"
38
+
39
+ ConstraintsBaseT = TypeVar("ConstraintsBaseT", bound="ConstraintsBase")
50
40
 
51
41
 
52
42
  class ConstraintsBase(_BaseModel):
53
- unique_items: Optional[bool] = Field(None, alias='uniqueItems')
54
- _exclude_fields: ClassVar[Set[str]] = {'has_constraints'}
43
+ unique_items: Optional[bool] = Field(None, alias="uniqueItems") # noqa: UP045
44
+ _exclude_fields: ClassVar[set[str]] = {"has_constraints"}
55
45
  if PYDANTIC_V2:
56
- model_config = ConfigDict( # pyright: ignore [reportAssignmentType]
46
+ model_config = ConfigDict( # pyright: ignore[reportAssignmentType]
57
47
  arbitrary_types_allowed=True, ignored_types=(cached_property,)
58
48
  )
59
49
  else:
@@ -67,61 +57,51 @@ class ConstraintsBase(_BaseModel):
67
57
  return any(v is not None for v in self.dict().values())
68
58
 
69
59
  @staticmethod
70
- def merge_constraints(
71
- a: ConstraintsBaseT, b: ConstraintsBaseT
72
- ) -> Optional[ConstraintsBaseT]:
60
+ def merge_constraints(a: ConstraintsBaseT, b: ConstraintsBaseT) -> ConstraintsBaseT | None:
73
61
  constraints_class = None
74
62
  if isinstance(a, ConstraintsBase): # pragma: no cover
75
- root_type_field_constraints = {
76
- k: v for k, v in a.dict(by_alias=True).items() if v is not None
77
- }
63
+ root_type_field_constraints = {k: v for k, v in a.dict(by_alias=True).items() if v is not None}
78
64
  constraints_class = a.__class__
79
65
  else:
80
66
  root_type_field_constraints = {} # pragma: no cover
81
67
 
82
68
  if isinstance(b, ConstraintsBase): # pragma: no cover
83
- model_field_constraints = {
84
- k: v for k, v in b.dict(by_alias=True).items() if v is not None
85
- }
69
+ model_field_constraints = {k: v for k, v in b.dict(by_alias=True).items() if v is not None}
86
70
  constraints_class = constraints_class or b.__class__
87
71
  else:
88
72
  model_field_constraints = {}
89
73
 
90
- if constraints_class is None or not issubclass(
91
- constraints_class, ConstraintsBase
92
- ): # pragma: no cover
74
+ if constraints_class is None or not issubclass(constraints_class, ConstraintsBase): # pragma: no cover
93
75
  return None
94
76
 
95
- return constraints_class.parse_obj(
96
- {
97
- **root_type_field_constraints,
98
- **model_field_constraints,
99
- }
100
- )
77
+ return constraints_class.parse_obj({
78
+ **root_type_field_constraints,
79
+ **model_field_constraints,
80
+ })
101
81
 
102
82
 
103
83
  class DataModelFieldBase(_BaseModel):
104
- name: Optional[str] = None
105
- default: Optional[Any] = None
84
+ name: Optional[str] = None # noqa: UP045
85
+ default: Optional[Any] = None # noqa: UP045
106
86
  required: bool = False
107
- alias: Optional[str] = None
87
+ alias: Optional[str] = None # noqa: UP045
108
88
  data_type: DataType
109
89
  constraints: Any = None
110
90
  strip_default_none: bool = False
111
- nullable: Optional[bool] = None
112
- parent: Optional[Any] = None
113
- extras: Dict[str, Any] = {}
91
+ nullable: Optional[bool] = None # noqa: UP045
92
+ parent: Optional[Any] = None # noqa: UP045
93
+ extras: dict[str, Any] = {} # noqa: RUF012
114
94
  use_annotated: bool = False
115
95
  has_default: bool = False
116
96
  use_field_description: bool = False
117
97
  const: bool = False
118
- original_name: Optional[str] = None
98
+ original_name: Optional[str] = None # noqa: UP045
119
99
  use_default_kwarg: bool = False
120
100
  use_one_literal_as_default: bool = False
121
- _exclude_fields: ClassVar[Set[str]] = {'parent'}
122
- _pass_fields: ClassVar[Set[str]] = {'parent', 'data_type'}
101
+ _exclude_fields: ClassVar[set[str]] = {"parent"}
102
+ _pass_fields: ClassVar[set[str]] = {"parent", "data_type"}
123
103
  can_have_extra_keys: ClassVar[bool] = True
124
- type_has_null: Optional[bool] = None
104
+ type_has_null: Optional[bool] = None # noqa: UP045
125
105
 
126
106
  if not TYPE_CHECKING:
127
107
 
@@ -132,46 +112,39 @@ class DataModelFieldBase(_BaseModel):
132
112
  self.process_const()
133
113
 
134
114
  def process_const(self) -> None:
135
- if 'const' not in self.extras:
136
- return None
137
- self.default = self.extras['const']
115
+ if "const" not in self.extras:
116
+ return
117
+ self.default = self.extras["const"]
138
118
  self.const = True
139
119
  self.required = False
140
120
  self.nullable = False
141
121
 
142
122
  @property
143
- def type_hint(self) -> str:
123
+ def type_hint(self) -> str: # noqa: PLR0911
144
124
  type_hint = self.data_type.type_hint
145
125
 
146
126
  if not type_hint:
147
127
  return NONE
148
- elif self.has_default_factory:
149
- return type_hint
150
- elif self.data_type.is_optional and self.data_type.type != ANY:
128
+ if self.has_default_factory or (self.data_type.is_optional and self.data_type.type != ANY):
151
129
  return type_hint
152
- elif self.nullable is not None:
130
+ if self.nullable is not None:
153
131
  if self.nullable:
154
132
  return get_optional_type(type_hint, self.data_type.use_union_operator)
155
133
  return type_hint
156
- elif self.required:
134
+ if self.required:
157
135
  if self.type_has_null:
158
136
  return get_optional_type(type_hint, self.data_type.use_union_operator)
159
137
  return type_hint
160
- elif self.fall_back_to_nullable:
138
+ if self.fall_back_to_nullable:
161
139
  return get_optional_type(type_hint, self.data_type.use_union_operator)
162
- else:
163
- return type_hint
140
+ return type_hint
164
141
 
165
142
  @property
166
- def imports(self) -> Tuple[Import, ...]:
143
+ def imports(self) -> tuple[Import, ...]:
167
144
  type_hint = self.type_hint
168
145
  has_union = not self.data_type.use_union_operator and UNION_PREFIX in type_hint
169
- imports: List[Union[Tuple[Import], Iterator[Import]]] = [
170
- iter(
171
- i
172
- for i in self.data_type.all_imports
173
- if not (not has_union and i == IMPORT_UNION)
174
- )
146
+ imports: list[tuple[Import] | Iterator[Import]] = [
147
+ iter(i for i in self.data_type.all_imports if not (not has_union and i == IMPORT_UNION))
175
148
  ]
176
149
 
177
150
  if self.fall_back_to_nullable:
@@ -179,39 +152,31 @@ class DataModelFieldBase(_BaseModel):
179
152
  self.nullable or (self.nullable is None and not self.required)
180
153
  ) and not self.data_type.use_union_operator:
181
154
  imports.append((IMPORT_OPTIONAL,))
182
- else:
183
- if (
184
- self.nullable and not self.data_type.use_union_operator
185
- ): # pragma: no cover
186
- imports.append((IMPORT_OPTIONAL,))
155
+ elif self.nullable and not self.data_type.use_union_operator: # pragma: no cover
156
+ imports.append((IMPORT_OPTIONAL,))
187
157
  if self.use_annotated and self.annotated:
188
- import_annotated = (
189
- IMPORT_ANNOTATED
190
- if self.data_type.python_version.has_annotated_type
191
- else IMPORT_ANNOTATED_BACKPORT
192
- )
193
- imports.append((import_annotated,))
158
+ imports.append((IMPORT_ANNOTATED,))
194
159
  return chain_as_tuple(*imports)
195
160
 
196
161
  @property
197
- def docstring(self) -> Optional[str]:
162
+ def docstring(self) -> str | None:
198
163
  if self.use_field_description:
199
- description = self.extras.get('description', None)
164
+ description = self.extras.get("description", None)
200
165
  if description is not None:
201
- return f'{description}'
166
+ return f"{description}"
202
167
  return None
203
168
 
204
169
  @property
205
- def unresolved_types(self) -> FrozenSet[str]:
170
+ def unresolved_types(self) -> frozenset[str]:
206
171
  return self.data_type.unresolved_types
207
172
 
208
173
  @property
209
- def field(self) -> Optional[str]:
174
+ def field(self) -> str | None:
210
175
  """for backwards compatibility"""
211
176
  return None
212
177
 
213
178
  @property
214
- def method(self) -> Optional[str]:
179
+ def method(self) -> str | None:
215
180
  return None
216
181
 
217
182
  @property
@@ -219,12 +184,12 @@ class DataModelFieldBase(_BaseModel):
219
184
  return repr(self.default)
220
185
 
221
186
  @property
222
- def annotated(self) -> Optional[str]:
187
+ def annotated(self) -> str | None:
223
188
  return None
224
189
 
225
190
  @property
226
191
  def has_default_factory(self) -> bool:
227
- return 'default_factory' in self.extras
192
+ return "default_factory" in self.extras
228
193
 
229
194
  @property
230
195
  def fall_back_to_nullable(self) -> bool:
@@ -234,22 +199,22 @@ class DataModelFieldBase(_BaseModel):
234
199
  @lru_cache
235
200
  def get_template(template_file_path: Path) -> Template:
236
201
  loader = FileSystemLoader(str(TEMPLATE_DIR / template_file_path.parent))
237
- environment: Environment = Environment(loader=loader)
202
+ environment: Environment = Environment(loader=loader) # noqa: S701
238
203
  return environment.get_template(template_file_path.name)
239
204
 
240
205
 
241
- def get_module_path(name: str, file_path: Optional[Path]) -> List[str]:
206
+ def get_module_path(name: str, file_path: Path | None) -> list[str]:
242
207
  if file_path:
243
208
  return [
244
209
  *file_path.parts[:-1],
245
210
  file_path.stem,
246
- *name.split('.')[:-1],
211
+ *name.split(".")[:-1],
247
212
  ]
248
- return name.split('.')[:-1]
213
+ return name.split(".")[:-1]
249
214
 
250
215
 
251
- def get_module_name(name: str, file_path: Optional[Path]) -> str:
252
- return '.'.join(get_module_path(name, file_path))
216
+ def get_module_name(name: str, file_path: Path | None) -> str:
217
+ return ".".join(get_module_path(name, file_path))
253
218
 
254
219
 
255
220
  class TemplateBase(ABC):
@@ -280,43 +245,42 @@ UNDEFINED: Any = object()
280
245
 
281
246
 
282
247
  class DataModel(TemplateBase, Nullable, ABC):
283
- TEMPLATE_FILE_PATH: ClassVar[str] = ''
284
- BASE_CLASS: ClassVar[str] = ''
285
- DEFAULT_IMPORTS: ClassVar[Tuple[Import, ...]] = ()
248
+ TEMPLATE_FILE_PATH: ClassVar[str] = ""
249
+ BASE_CLASS: ClassVar[str] = ""
250
+ DEFAULT_IMPORTS: ClassVar[tuple[Import, ...]] = ()
286
251
 
287
- def __init__(
252
+ def __init__( # noqa: PLR0913
288
253
  self,
289
254
  *,
290
255
  reference: Reference,
291
- fields: List[DataModelFieldBase],
292
- decorators: Optional[List[str]] = None,
293
- base_classes: Optional[List[Reference]] = None,
294
- custom_base_class: Optional[str] = None,
295
- custom_template_dir: Optional[Path] = None,
296
- extra_template_data: Optional[DefaultDict[str, Dict[str, Any]]] = None,
297
- methods: Optional[List[str]] = None,
298
- path: Optional[Path] = None,
299
- description: Optional[str] = None,
256
+ fields: list[DataModelFieldBase],
257
+ decorators: list[str] | None = None,
258
+ base_classes: list[Reference] | None = None,
259
+ custom_base_class: str | None = None,
260
+ custom_template_dir: Path | None = None,
261
+ extra_template_data: defaultdict[str, dict[str, Any]] | None = None,
262
+ methods: list[str] | None = None,
263
+ path: Path | None = None,
264
+ description: str | None = None,
300
265
  default: Any = UNDEFINED,
301
266
  nullable: bool = False,
302
267
  keyword_only: bool = False,
303
268
  ) -> None:
304
269
  self.keyword_only = keyword_only
305
270
  if not self.TEMPLATE_FILE_PATH:
306
- raise Exception('TEMPLATE_FILE_PATH is undefined')
271
+ msg = "TEMPLATE_FILE_PATH is undefined"
272
+ raise Exception(msg) # noqa: TRY002
307
273
 
308
- self._custom_template_dir: Optional[Path] = custom_template_dir
309
- self.decorators: List[str] = decorators or []
310
- self._additional_imports: List[Import] = []
274
+ self._custom_template_dir: Path | None = custom_template_dir
275
+ self.decorators: list[str] = decorators or []
276
+ self._additional_imports: list[Import] = []
311
277
  self.custom_base_class = custom_base_class
312
278
  if base_classes:
313
- self.base_classes: List[BaseClassDataType] = [
314
- BaseClassDataType(reference=b) for b in base_classes
315
- ]
279
+ self.base_classes: list[BaseClassDataType] = [BaseClassDataType(reference=b) for b in base_classes]
316
280
  else:
317
281
  self.set_base_class()
318
282
 
319
- self.file_path: Optional[Path] = path
283
+ self.file_path: Path | None = path
320
284
  self.reference: Reference = reference
321
285
 
322
286
  self.reference.source = self
@@ -324,9 +288,7 @@ class DataModel(TemplateBase, Nullable, ABC):
324
288
  self.extra_template_data = (
325
289
  # The supplied defaultdict will either create a new entry,
326
290
  # or already contain a predefined entry for this type
327
- extra_template_data[self.name]
328
- if extra_template_data is not None
329
- else defaultdict(dict)
291
+ extra_template_data[self.name] if extra_template_data is not None else defaultdict(dict)
330
292
  )
331
293
 
332
294
  self.fields = self._validate_fields(fields) if fields else []
@@ -342,7 +304,7 @@ class DataModel(TemplateBase, Nullable, ABC):
342
304
  # end up inadvertently sharing state (such as "base_class_kwargs")
343
305
  self.extra_template_data.update(deepcopy(all_model_extra_template_data))
344
306
 
345
- self.methods: List[str] = methods or []
307
+ self.methods: list[str] = methods or []
346
308
 
347
309
  self.description = description
348
310
  for field in self.fields:
@@ -352,18 +314,15 @@ class DataModel(TemplateBase, Nullable, ABC):
352
314
  self.default: Any = default
353
315
  self._nullable: bool = nullable
354
316
 
355
- def _validate_fields(
356
- self, fields: List[DataModelFieldBase]
357
- ) -> List[DataModelFieldBase]:
358
- names: Set[str] = set()
359
- unique_fields: List[DataModelFieldBase] = []
317
+ def _validate_fields(self, fields: list[DataModelFieldBase]) -> list[DataModelFieldBase]:
318
+ names: set[str] = set()
319
+ unique_fields: list[DataModelFieldBase] = []
360
320
  for field in fields:
361
321
  if field.name:
362
322
  if field.name in names:
363
- warn(f'Field name `{field.name}` is duplicated on {self.name}')
323
+ warn(f"Field name `{field.name}` is duplicated on {self.name}", stacklevel=2)
364
324
  continue
365
- else:
366
- names.add(field.name)
325
+ names.add(field.name)
367
326
  unique_fields.append(field)
368
327
  return unique_fields
369
328
 
@@ -371,7 +330,7 @@ class DataModel(TemplateBase, Nullable, ABC):
371
330
  base_class = self.custom_base_class or self.BASE_CLASS
372
331
  if not base_class:
373
332
  self.base_classes = []
374
- return None
333
+ return
375
334
  base_class_import = Import.from_full_path(base_class)
376
335
  self._additional_imports.append(base_class_import)
377
336
  self.base_classes = [BaseClassDataType.from_import(base_class_import)]
@@ -386,14 +345,14 @@ class DataModel(TemplateBase, Nullable, ABC):
386
345
  return template_file_path
387
346
 
388
347
  @property
389
- def imports(self) -> Tuple[Import, ...]:
348
+ def imports(self) -> tuple[Import, ...]:
390
349
  return chain_as_tuple(
391
350
  (i for f in self.fields for i in f.imports),
392
351
  self._additional_imports,
393
352
  )
394
353
 
395
354
  @property
396
- def reference_classes(self) -> FrozenSet[str]:
355
+ def reference_classes(self) -> frozenset[str]:
397
356
  return frozenset(
398
357
  {r.reference.path for r in self.base_classes if r.reference}
399
358
  | {t for f in self.fields for t in f.unresolved_types}
@@ -405,16 +364,16 @@ class DataModel(TemplateBase, Nullable, ABC):
405
364
 
406
365
  @property
407
366
  def duplicate_name(self) -> str:
408
- return self.reference.duplicate_name or ''
367
+ return self.reference.duplicate_name or ""
409
368
 
410
369
  @property
411
370
  def base_class(self) -> str:
412
- return ', '.join(b.type_hint for b in self.base_classes)
371
+ return ", ".join(b.type_hint for b in self.base_classes)
413
372
 
414
373
  @staticmethod
415
374
  def _get_class_name(name: str) -> str:
416
- if '.' in name:
417
- return name.rsplit('.', 1)[-1]
375
+ if "." in name:
376
+ return name.rsplit(".", 1)[-1]
418
377
  return name
419
378
 
420
379
  @property
@@ -423,10 +382,8 @@ class DataModel(TemplateBase, Nullable, ABC):
423
382
 
424
383
  @class_name.setter
425
384
  def class_name(self, class_name: str) -> None:
426
- if '.' in self.reference.name:
427
- self.reference.name = (
428
- f'{self.reference.name.rsplit(".", 1)[0]}.{class_name}'
429
- )
385
+ if "." in self.reference.name:
386
+ self.reference.name = f"{self.reference.name.rsplit('.', 1)[0]}.{class_name}"
430
387
  else:
431
388
  self.reference.name = class_name
432
389
 
@@ -435,7 +392,7 @@ class DataModel(TemplateBase, Nullable, ABC):
435
392
  return self._get_class_name(self.duplicate_name)
436
393
 
437
394
  @property
438
- def module_path(self) -> List[str]:
395
+ def module_path(self) -> list[str]:
439
396
  return get_module_path(self.name, self.file_path)
440
397
 
441
398
  @property
@@ -456,8 +413,8 @@ class DataModel(TemplateBase, Nullable, ABC):
456
413
  def path(self) -> str:
457
414
  return self.reference.path
458
415
 
459
- def render(self, *, class_name: Optional[str] = None) -> str:
460
- response = self._render(
416
+ def render(self, *, class_name: str | None = None) -> str:
417
+ return self._render(
461
418
  class_name=class_name or self.class_name,
462
419
  fields=self.fields,
463
420
  decorators=self.decorators,
@@ -467,4 +424,3 @@ class DataModel(TemplateBase, Nullable, ABC):
467
424
  keyword_only=self.keyword_only,
468
425
  **self.extra_template_data,
469
426
  )
470
- return response