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,40 +1,21 @@
1
+ from __future__ import annotations
2
+
3
+ import operator
1
4
  import re
2
5
  import sys
3
6
  from abc import ABC, abstractmethod
4
7
  from collections import OrderedDict, defaultdict
5
8
  from itertools import groupby
6
9
  from pathlib import Path
7
- from typing import (
8
- Any,
9
- Callable,
10
- DefaultDict,
11
- Dict,
12
- Iterable,
13
- Iterator,
14
- List,
15
- Mapping,
16
- NamedTuple,
17
- Optional,
18
- Sequence,
19
- Set,
20
- Tuple,
21
- Type,
22
- TypeVar,
23
- Union,
24
- )
10
+ from typing import TYPE_CHECKING, Any, Callable, NamedTuple, Optional, Protocol, TypeVar, runtime_checkable
25
11
  from urllib.parse import ParseResult
26
12
 
27
13
  from pydantic import BaseModel
28
14
 
29
- from datamodel_code_generator.format import (
30
- CodeFormatter,
31
- DatetimeClassType,
32
- PythonVersion,
33
- )
15
+ from datamodel_code_generator.format import CodeFormatter, DatetimeClassType, PythonVersion, PythonVersionMin
34
16
  from datamodel_code_generator.imports import (
35
17
  IMPORT_ANNOTATIONS,
36
18
  IMPORT_LITERAL,
37
- IMPORT_LITERAL_BACKPORT,
38
19
  Import,
39
20
  Imports,
40
21
  )
@@ -54,27 +35,27 @@ from datamodel_code_generator.model.enum import Enum, Member
54
35
  from datamodel_code_generator.parser import DefaultPutDict, LiteralType
55
36
  from datamodel_code_generator.reference import ModelResolver, Reference
56
37
  from datamodel_code_generator.types import DataType, DataTypeManager, StrictTypes
57
- from datamodel_code_generator.util import Protocol, runtime_checkable
58
38
 
59
- SPECIAL_PATH_FORMAT: str = '#-datamodel-code-generator-#-{}-#-special-#'
39
+ if TYPE_CHECKING:
40
+ from collections.abc import Iterable, Iterator, Mapping, Sequence
60
41
 
42
+ SPECIAL_PATH_FORMAT: str = "#-datamodel-code-generator-#-{}-#-special-#"
61
43
 
62
- def get_special_path(keyword: str, path: List[str]) -> List[str]:
44
+
45
+ def get_special_path(keyword: str, path: list[str]) -> list[str]:
63
46
  return [*path, SPECIAL_PATH_FORMAT.format(keyword)]
64
47
 
65
48
 
66
- escape_characters = str.maketrans(
67
- {
68
- '\u0000': r'\x00', # Null byte
69
- '\\': r'\\',
70
- "'": r'\'',
71
- '\b': r'\b',
72
- '\f': r'\f',
73
- '\n': r'\n',
74
- '\r': r'\r',
75
- '\t': r'\t',
76
- }
77
- )
49
+ escape_characters = str.maketrans({
50
+ "\u0000": r"\x00", # Null byte
51
+ "\\": r"\\",
52
+ "'": r"\'",
53
+ "\b": r"\b",
54
+ "\f": r"\f",
55
+ "\n": r"\n",
56
+ "\r": r"\r",
57
+ "\t": r"\t",
58
+ })
78
59
 
79
60
 
80
61
  def to_hashable(item: Any) -> Any:
@@ -86,7 +67,7 @@ def to_hashable(item: Any) -> Any:
86
67
  ),
87
68
  ):
88
69
  return tuple(sorted(to_hashable(i) for i in item))
89
- elif isinstance(item, dict):
70
+ if isinstance(item, dict):
90
71
  return tuple(
91
72
  sorted(
92
73
  (
@@ -96,42 +77,40 @@ def to_hashable(item: Any) -> Any:
96
77
  for k, v in item.items()
97
78
  )
98
79
  )
99
- elif isinstance(item, set): # pragma: no cover
80
+ if isinstance(item, set): # pragma: no cover
100
81
  return frozenset(to_hashable(i) for i in item)
101
- elif isinstance(item, BaseModel):
82
+ if isinstance(item, BaseModel):
102
83
  return to_hashable(item.dict())
103
84
  return item
104
85
 
105
86
 
106
- def dump_templates(templates: List[DataModel]) -> str:
107
- return '\n\n\n'.join(str(m) for m in templates)
87
+ def dump_templates(templates: list[DataModel]) -> str:
88
+ return "\n\n\n".join(str(m) for m in templates)
108
89
 
109
90
 
110
- ReferenceMapSet = Dict[str, Set[str]]
111
- SortedDataModels = Dict[str, DataModel]
91
+ ReferenceMapSet = dict[str, set[str]]
92
+ SortedDataModels = dict[str, DataModel]
112
93
 
113
94
  MAX_RECURSION_COUNT: int = sys.getrecursionlimit()
114
95
 
115
96
 
116
- def sort_data_models(
117
- unsorted_data_models: List[DataModel],
118
- sorted_data_models: Optional[SortedDataModels] = None,
119
- require_update_action_models: Optional[List[str]] = None,
97
+ def sort_data_models( # noqa: PLR0912
98
+ unsorted_data_models: list[DataModel],
99
+ sorted_data_models: SortedDataModels | None = None,
100
+ require_update_action_models: list[str] | None = None,
120
101
  recursion_count: int = MAX_RECURSION_COUNT,
121
- ) -> Tuple[List[DataModel], SortedDataModels, List[str]]:
102
+ ) -> tuple[list[DataModel], SortedDataModels, list[str]]:
122
103
  if sorted_data_models is None:
123
104
  sorted_data_models = OrderedDict()
124
105
  if require_update_action_models is None:
125
106
  require_update_action_models = []
126
107
  sorted_model_count: int = len(sorted_data_models)
127
108
 
128
- unresolved_references: List[DataModel] = []
109
+ unresolved_references: list[DataModel] = []
129
110
  for model in unsorted_data_models:
130
111
  if not model.reference_classes:
131
112
  sorted_data_models[model.path] = model
132
- elif (
133
- model.path in model.reference_classes and len(model.reference_classes) == 1
134
- ): # only self-referencing
113
+ elif model.path in model.reference_classes and len(model.reference_classes) == 1: # only self-referencing
135
114
  sorted_data_models[model.path] = model
136
115
  require_update_action_models.append(model.path)
137
116
  elif (
@@ -156,32 +135,25 @@ def sort_data_models(
156
135
 
157
136
  # sort on base_class dependency
158
137
  while True:
159
- ordered_models: List[Tuple[int, DataModel]] = []
138
+ ordered_models: list[tuple[int, DataModel]] = []
160
139
  unresolved_reference_model_names = [m.path for m in unresolved_references]
161
140
  for model in unresolved_references:
162
141
  indexes = [
163
142
  unresolved_reference_model_names.index(b.reference.path)
164
143
  for b in model.base_classes
165
- if b.reference
166
- and b.reference.path in unresolved_reference_model_names
144
+ if b.reference and b.reference.path in unresolved_reference_model_names
167
145
  ]
168
146
  if indexes:
169
- ordered_models.append(
170
- (
171
- max(indexes),
172
- model,
173
- )
174
- )
147
+ ordered_models.append((
148
+ max(indexes),
149
+ model,
150
+ ))
175
151
  else:
176
- ordered_models.append(
177
- (
178
- -1,
179
- model,
180
- )
181
- )
182
- sorted_unresolved_models = [
183
- m[1] for m in sorted(ordered_models, key=lambda m: m[0])
184
- ]
152
+ ordered_models.append((
153
+ -1,
154
+ model,
155
+ ))
156
+ sorted_unresolved_models = [m[1] for m in sorted(ordered_models, key=operator.itemgetter(0))]
185
157
  if sorted_unresolved_models == unresolved_references:
186
158
  break
187
159
  unresolved_references = sorted_unresolved_models
@@ -189,15 +161,9 @@ def sort_data_models(
189
161
  # circular reference
190
162
  unsorted_data_model_names = set(unresolved_reference_model_names)
191
163
  for model in unresolved_references:
192
- unresolved_model = (
193
- model.reference_classes - {model.path} - set(sorted_data_models)
194
- )
195
- base_models = [
196
- getattr(s.reference, 'path', None) for s in model.base_classes
197
- ]
198
- update_action_parent = set(require_update_action_models).intersection(
199
- base_models
200
- )
164
+ unresolved_model = model.reference_classes - {model.path} - set(sorted_data_models)
165
+ base_models = [getattr(s.reference, "path", None) for s in model.base_classes]
166
+ update_action_parent = set(require_update_action_models).intersection(base_models)
201
167
  if not unresolved_model:
202
168
  sorted_data_models[model.path] = model
203
169
  if update_action_parent:
@@ -208,22 +174,22 @@ def sort_data_models(
208
174
  require_update_action_models.append(model.path)
209
175
  continue
210
176
  # unresolved
211
- unresolved_classes = ', '.join(
212
- f'[class: {item.path} references: {item.reference_classes}]'
213
- for item in unresolved_references
177
+ unresolved_classes = ", ".join(
178
+ f"[class: {item.path} references: {item.reference_classes}]" for item in unresolved_references
214
179
  )
215
- raise Exception(f'A Parser can not resolve classes: {unresolved_classes}.')
180
+ msg = f"A Parser can not resolve classes: {unresolved_classes}."
181
+ raise Exception(msg) # noqa: TRY002
216
182
  return unresolved_references, sorted_data_models, require_update_action_models
217
183
 
218
184
 
219
- def relative(current_module: str, reference: str) -> Tuple[str, str]:
185
+ def relative(current_module: str, reference: str) -> tuple[str, str]:
220
186
  """Find relative module path."""
221
187
 
222
- current_module_path = current_module.split('.') if current_module else []
223
- *reference_path, name = reference.split('.')
188
+ current_module_path = current_module.split(".") if current_module else []
189
+ *reference_path, name = reference.split(".")
224
190
 
225
191
  if current_module_path == reference_path:
226
- return '', ''
192
+ return "", ""
227
193
 
228
194
  i = 0
229
195
  for x, y in zip(current_module_path, reference_path):
@@ -231,65 +197,58 @@ def relative(current_module: str, reference: str) -> Tuple[str, str]:
231
197
  break
232
198
  i += 1
233
199
 
234
- left = '.' * (len(current_module_path) - i)
235
- right = '.'.join(reference_path[i:])
200
+ left = "." * (len(current_module_path) - i)
201
+ right = ".".join(reference_path[i:])
236
202
 
237
203
  if not left:
238
- left = '.'
204
+ left = "."
239
205
  if not right:
240
206
  right = name
241
- elif '.' in right:
242
- extra, right = right.rsplit('.', 1)
207
+ elif "." in right:
208
+ extra, right = right.rsplit(".", 1)
243
209
  left += extra
244
210
 
245
211
  return left, right
246
212
 
247
213
 
248
- def exact_import(from_: str, import_: str, short_name: str) -> Tuple[str, str]:
249
- if from_ == len(from_) * '.':
214
+ def exact_import(from_: str, import_: str, short_name: str) -> tuple[str, str]:
215
+ if from_ == len(from_) * ".":
250
216
  # Prevents "from . import foo" becoming "from ..foo import Foo"
251
217
  # or "from .. import foo" becoming "from ...foo import Foo"
252
218
  # when our imported module has the same parent
253
- return f'{from_}{import_}', short_name
254
- return f'{from_}.{import_}', short_name
219
+ return f"{from_}{import_}", short_name
220
+ return f"{from_}.{import_}", short_name
255
221
 
256
222
 
257
223
  @runtime_checkable
258
224
  class Child(Protocol):
259
225
  @property
260
- def parent(self) -> Optional[Any]:
226
+ def parent(self) -> Any | None:
261
227
  raise NotImplementedError
262
228
 
263
229
 
264
- T = TypeVar('T')
230
+ T = TypeVar("T")
265
231
 
266
232
 
267
- def get_most_of_parent(value: Any, type_: Optional[Type[T]] = None) -> Optional[T]:
233
+ def get_most_of_parent(value: Any, type_: type[T] | None = None) -> T | None:
268
234
  if isinstance(value, Child) and (type_ is None or not isinstance(value, type_)):
269
235
  return get_most_of_parent(value.parent, type_)
270
236
  return value
271
237
 
272
238
 
273
239
  def title_to_class_name(title: str) -> str:
274
- classname = re.sub('[^A-Za-z0-9]+', ' ', title)
275
- classname = ''.join(x for x in classname.title() if not x.isspace())
276
- return classname
240
+ classname = re.sub(r"[^A-Za-z0-9]+", " ", title)
241
+ return "".join(x for x in classname.title() if not x.isspace())
277
242
 
278
243
 
279
- def _find_base_classes(model: DataModel) -> List[DataModel]:
280
- return [
281
- b.reference.source
282
- for b in model.base_classes
283
- if b.reference and isinstance(b.reference.source, DataModel)
284
- ]
244
+ def _find_base_classes(model: DataModel) -> list[DataModel]:
245
+ return [b.reference.source for b in model.base_classes if b.reference and isinstance(b.reference.source, DataModel)]
285
246
 
286
247
 
287
- def _find_field(
288
- original_name: str, models: List[DataModel]
289
- ) -> Optional[DataModelFieldBase]:
248
+ def _find_field(original_name: str, models: list[DataModel]) -> DataModelFieldBase | None:
290
249
  def _find_field_and_base_classes(
291
250
  model_: DataModel,
292
- ) -> Tuple[Optional[DataModelFieldBase], List[DataModel]]:
251
+ ) -> tuple[DataModelFieldBase | None, list[DataModel]]:
293
252
  for field_ in model_.fields:
294
253
  if field_.original_name == original_name:
295
254
  return field_, []
@@ -299,18 +258,16 @@ def _find_field(
299
258
  field, base_models = _find_field_and_base_classes(model)
300
259
  if field:
301
260
  return field
302
- models.extend(base_models) # pragma: no cover
261
+ models.extend(base_models) # pragma: no cover # noqa: B909
303
262
 
304
263
  return None # pragma: no cover
305
264
 
306
265
 
307
- def _copy_data_types(data_types: List[DataType]) -> List[DataType]:
308
- copied_data_types: List[DataType] = []
266
+ def _copy_data_types(data_types: list[DataType]) -> list[DataType]:
267
+ copied_data_types: list[DataType] = []
309
268
  for data_type_ in data_types:
310
269
  if data_type_.reference:
311
- copied_data_types.append(
312
- data_type_.__class__(reference=data_type_.reference)
313
- )
270
+ copied_data_types.append(data_type_.__class__(reference=data_type_.reference))
314
271
  elif data_type_.data_types: # pragma: no cover
315
272
  copied_data_type = data_type_.copy()
316
273
  copied_data_type.data_types = _copy_data_types(data_type_.data_types)
@@ -322,7 +279,7 @@ def _copy_data_types(data_types: List[DataType]) -> List[DataType]:
322
279
 
323
280
  class Result(BaseModel):
324
281
  body: str
325
- source: Optional[Path] = None
282
+ source: Optional[Path] = None # noqa: UP045
326
283
 
327
284
 
328
285
  class Source(BaseModel):
@@ -330,7 +287,7 @@ class Source(BaseModel):
330
287
  text: str
331
288
 
332
289
  @classmethod
333
- def from_path(cls, path: Path, base_path: Path, encoding: str) -> 'Source':
290
+ def from_path(cls, path: Path, base_path: Path, encoding: str) -> Source:
334
291
  return cls(
335
292
  path=path.relative_to(base_path),
336
293
  text=path.read_text(encoding=encoding),
@@ -338,80 +295,78 @@ class Source(BaseModel):
338
295
 
339
296
 
340
297
  class Parser(ABC):
341
- def __init__(
298
+ def __init__( # noqa: PLR0913, PLR0915
342
299
  self,
343
- source: Union[str, Path, List[Path], ParseResult],
300
+ source: str | Path | list[Path] | ParseResult,
344
301
  *,
345
- data_model_type: Type[DataModel] = pydantic_model.BaseModel,
346
- data_model_root_type: Type[DataModel] = pydantic_model.CustomRootType,
347
- data_type_manager_type: Type[DataTypeManager] = pydantic_model.DataTypeManager,
348
- data_model_field_type: Type[DataModelFieldBase] = pydantic_model.DataModelField,
349
- base_class: Optional[str] = None,
350
- additional_imports: Optional[List[str]] = None,
351
- custom_template_dir: Optional[Path] = None,
352
- extra_template_data: Optional[DefaultDict[str, Dict[str, Any]]] = None,
353
- target_python_version: PythonVersion = PythonVersion.PY_38,
354
- dump_resolve_reference_action: Optional[Callable[[Iterable[str]], str]] = None,
302
+ data_model_type: type[DataModel] = pydantic_model.BaseModel,
303
+ data_model_root_type: type[DataModel] = pydantic_model.CustomRootType,
304
+ data_type_manager_type: type[DataTypeManager] = pydantic_model.DataTypeManager,
305
+ data_model_field_type: type[DataModelFieldBase] = pydantic_model.DataModelField,
306
+ base_class: str | None = None,
307
+ additional_imports: list[str] | None = None,
308
+ custom_template_dir: Path | None = None,
309
+ extra_template_data: defaultdict[str, dict[str, Any]] | None = None,
310
+ target_python_version: PythonVersion = PythonVersionMin,
311
+ dump_resolve_reference_action: Callable[[Iterable[str]], str] | None = None,
355
312
  validation: bool = False,
356
313
  field_constraints: bool = False,
357
314
  snake_case_field: bool = False,
358
315
  strip_default_none: bool = False,
359
- aliases: Optional[Mapping[str, str]] = None,
316
+ aliases: Mapping[str, str] | None = None,
360
317
  allow_population_by_field_name: bool = False,
361
318
  apply_default_values_for_required_fields: bool = False,
362
319
  allow_extra_fields: bool = False,
363
320
  force_optional_for_required_fields: bool = False,
364
- class_name: Optional[str] = None,
321
+ class_name: str | None = None,
365
322
  use_standard_collections: bool = False,
366
- base_path: Optional[Path] = None,
323
+ base_path: Path | None = None,
367
324
  use_schema_description: bool = False,
368
325
  use_field_description: bool = False,
369
326
  use_default_kwarg: bool = False,
370
327
  reuse_model: bool = False,
371
- encoding: str = 'utf-8',
372
- enum_field_as_literal: Optional[LiteralType] = None,
328
+ encoding: str = "utf-8",
329
+ enum_field_as_literal: LiteralType | None = None,
373
330
  set_default_enum_member: bool = False,
374
331
  use_subclass_enum: bool = False,
375
332
  strict_nullable: bool = False,
376
333
  use_generic_container_types: bool = False,
377
334
  enable_faux_immutability: bool = False,
378
- remote_text_cache: Optional[DefaultPutDict[str, str]] = None,
335
+ remote_text_cache: DefaultPutDict[str, str] | None = None,
379
336
  disable_appending_item_suffix: bool = False,
380
- strict_types: Optional[Sequence[StrictTypes]] = None,
381
- empty_enum_field_name: Optional[str] = None,
382
- custom_class_name_generator: Optional[
383
- Callable[[str], str]
384
- ] = title_to_class_name,
385
- field_extra_keys: Optional[Set[str]] = None,
337
+ strict_types: Sequence[StrictTypes] | None = None,
338
+ empty_enum_field_name: str | None = None,
339
+ custom_class_name_generator: Callable[[str], str] | None = title_to_class_name,
340
+ field_extra_keys: set[str] | None = None,
386
341
  field_include_all_keys: bool = False,
387
- field_extra_keys_without_x_prefix: Optional[Set[str]] = None,
388
- wrap_string_literal: Optional[bool] = None,
342
+ field_extra_keys_without_x_prefix: set[str] | None = None,
343
+ wrap_string_literal: bool | None = None,
389
344
  use_title_as_name: bool = False,
390
345
  use_operation_id_as_name: bool = False,
391
346
  use_unique_items_as_set: bool = False,
392
- http_headers: Optional[Sequence[Tuple[str, str]]] = None,
347
+ http_headers: Sequence[tuple[str, str]] | None = None,
393
348
  http_ignore_tls: bool = False,
394
349
  use_annotated: bool = False,
395
350
  use_non_positive_negative_number_constrained_types: bool = False,
396
- original_field_name_delimiter: Optional[str] = None,
351
+ original_field_name_delimiter: str | None = None,
397
352
  use_double_quotes: bool = False,
398
353
  use_union_operator: bool = False,
399
354
  allow_responses_without_content: bool = False,
400
355
  collapse_root_models: bool = False,
401
- special_field_name_prefix: Optional[str] = None,
356
+ special_field_name_prefix: str | None = None,
402
357
  remove_special_field_name_prefix: bool = False,
403
358
  capitalise_enum_members: bool = False,
404
359
  keep_model_order: bool = False,
405
360
  use_one_literal_as_default: bool = False,
406
- known_third_party: Optional[List[str]] = None,
407
- custom_formatters: Optional[List[str]] = None,
408
- custom_formatters_kwargs: Optional[Dict[str, Any]] = None,
361
+ known_third_party: list[str] | None = None,
362
+ custom_formatters: list[str] | None = None,
363
+ custom_formatters_kwargs: dict[str, Any] | None = None,
409
364
  use_pendulum: bool = False,
410
- http_query_parameters: Optional[Sequence[Tuple[str, str]]] = None,
365
+ http_query_parameters: Sequence[tuple[str, str]] | None = None,
411
366
  treat_dots_as_module: bool = False,
412
367
  use_exact_imports: bool = False,
413
- default_field_extras: Optional[Dict[str, Any]] = None,
414
- target_datetime_class: Optional[DatetimeClassType] = DatetimeClassType.Datetime,
368
+ default_field_extras: dict[str, Any] | None = None,
369
+ target_datetime_class: DatetimeClassType | None = DatetimeClassType.Datetime,
415
370
  keyword_only: bool = False,
416
371
  no_alias: bool = False,
417
372
  ) -> None:
@@ -425,55 +380,43 @@ class Parser(ABC):
425
380
  use_pendulum=use_pendulum,
426
381
  target_datetime_class=target_datetime_class,
427
382
  )
428
- self.data_model_type: Type[DataModel] = data_model_type
429
- self.data_model_root_type: Type[DataModel] = data_model_root_type
430
- self.data_model_field_type: Type[DataModelFieldBase] = data_model_field_type
383
+ self.data_model_type: type[DataModel] = data_model_type
384
+ self.data_model_root_type: type[DataModel] = data_model_root_type
385
+ self.data_model_field_type: type[DataModelFieldBase] = data_model_field_type
431
386
 
432
387
  self.imports: Imports = Imports(use_exact_imports)
433
388
  self.use_exact_imports: bool = use_exact_imports
434
389
  self._append_additional_imports(additional_imports=additional_imports)
435
390
 
436
- self.base_class: Optional[str] = base_class
391
+ self.base_class: str | None = base_class
437
392
  self.target_python_version: PythonVersion = target_python_version
438
- self.results: List[DataModel] = []
439
- self.dump_resolve_reference_action: Optional[Callable[[Iterable[str]], str]] = (
440
- dump_resolve_reference_action
441
- )
393
+ self.results: list[DataModel] = []
394
+ self.dump_resolve_reference_action: Callable[[Iterable[str]], str] | None = dump_resolve_reference_action
442
395
  self.validation: bool = validation
443
396
  self.field_constraints: bool = field_constraints
444
397
  self.snake_case_field: bool = snake_case_field
445
398
  self.strip_default_none: bool = strip_default_none
446
- self.apply_default_values_for_required_fields: bool = (
447
- apply_default_values_for_required_fields
448
- )
449
- self.force_optional_for_required_fields: bool = (
450
- force_optional_for_required_fields
451
- )
399
+ self.apply_default_values_for_required_fields: bool = apply_default_values_for_required_fields
400
+ self.force_optional_for_required_fields: bool = force_optional_for_required_fields
452
401
  self.use_schema_description: bool = use_schema_description
453
402
  self.use_field_description: bool = use_field_description
454
403
  self.use_default_kwarg: bool = use_default_kwarg
455
404
  self.reuse_model: bool = reuse_model
456
405
  self.encoding: str = encoding
457
- self.enum_field_as_literal: Optional[LiteralType] = enum_field_as_literal
406
+ self.enum_field_as_literal: LiteralType | None = enum_field_as_literal
458
407
  self.set_default_enum_member: bool = set_default_enum_member
459
408
  self.use_subclass_enum: bool = use_subclass_enum
460
409
  self.strict_nullable: bool = strict_nullable
461
410
  self.use_generic_container_types: bool = use_generic_container_types
462
411
  self.use_union_operator: bool = use_union_operator
463
412
  self.enable_faux_immutability: bool = enable_faux_immutability
464
- self.custom_class_name_generator: Optional[Callable[[str], str]] = (
465
- custom_class_name_generator
466
- )
467
- self.field_extra_keys: Set[str] = field_extra_keys or set()
468
- self.field_extra_keys_without_x_prefix: Set[str] = (
469
- field_extra_keys_without_x_prefix or set()
470
- )
413
+ self.custom_class_name_generator: Callable[[str], str] | None = custom_class_name_generator
414
+ self.field_extra_keys: set[str] = field_extra_keys or set()
415
+ self.field_extra_keys_without_x_prefix: set[str] = field_extra_keys_without_x_prefix or set()
471
416
  self.field_include_all_keys: bool = field_include_all_keys
472
417
 
473
- self.remote_text_cache: DefaultPutDict[str, str] = (
474
- remote_text_cache or DefaultPutDict()
475
- )
476
- self.current_source_path: Optional[Path] = None
418
+ self.remote_text_cache: DefaultPutDict[str, str] = remote_text_cache or DefaultPutDict()
419
+ self.current_source_path: Path | None = None
477
420
  self.use_title_as_name: bool = use_title_as_name
478
421
  self.use_operation_id_as_name: bool = use_operation_id_as_name
479
422
  self.use_unique_items_as_set: bool = use_unique_items_as_set
@@ -481,30 +424,26 @@ class Parser(ABC):
481
424
  if base_path:
482
425
  self.base_path = base_path
483
426
  elif isinstance(source, Path):
484
- self.base_path = (
485
- source.absolute() if source.is_dir() else source.absolute().parent
486
- )
427
+ self.base_path = source.absolute() if source.is_dir() else source.absolute().parent
487
428
  else:
488
429
  self.base_path = Path.cwd()
489
430
 
490
- self.source: Union[str, Path, List[Path], ParseResult] = source
431
+ self.source: str | Path | list[Path] | ParseResult = source
491
432
  self.custom_template_dir = custom_template_dir
492
- self.extra_template_data: DefaultDict[str, Any] = (
493
- extra_template_data or defaultdict(dict)
494
- )
433
+ self.extra_template_data: defaultdict[str, Any] = extra_template_data or defaultdict(dict)
495
434
 
496
435
  if allow_population_by_field_name:
497
- self.extra_template_data[ALL_MODEL]['allow_population_by_field_name'] = True
436
+ self.extra_template_data[ALL_MODEL]["allow_population_by_field_name"] = True
498
437
 
499
438
  if allow_extra_fields:
500
- self.extra_template_data[ALL_MODEL]['allow_extra_fields'] = True
439
+ self.extra_template_data[ALL_MODEL]["allow_extra_fields"] = True
501
440
 
502
441
  if enable_faux_immutability:
503
- self.extra_template_data[ALL_MODEL]['allow_mutation'] = False
442
+ self.extra_template_data[ALL_MODEL]["allow_mutation"] = False
504
443
 
505
444
  self.model_resolver = ModelResolver(
506
445
  base_url=source.geturl() if isinstance(source, ParseResult) else None,
507
- singular_name_suffix='' if disable_appending_item_suffix else None,
446
+ singular_name_suffix="" if disable_appending_item_suffix else None,
508
447
  aliases=aliases,
509
448
  empty_field_name=empty_enum_field_name,
510
449
  snake_case_field=snake_case_field,
@@ -516,21 +455,16 @@ class Parser(ABC):
516
455
  capitalise_enum_members=capitalise_enum_members,
517
456
  no_alias=no_alias,
518
457
  )
519
- self.class_name: Optional[str] = class_name
520
- self.wrap_string_literal: Optional[bool] = wrap_string_literal
521
- self.http_headers: Optional[Sequence[Tuple[str, str]]] = http_headers
522
- self.http_query_parameters: Optional[Sequence[Tuple[str, str]]] = (
523
- http_query_parameters
524
- )
458
+ self.class_name: str | None = class_name
459
+ self.wrap_string_literal: bool | None = wrap_string_literal
460
+ self.http_headers: Sequence[tuple[str, str]] | None = http_headers
461
+ self.http_query_parameters: Sequence[tuple[str, str]] | None = http_query_parameters
525
462
  self.http_ignore_tls: bool = http_ignore_tls
526
463
  self.use_annotated: bool = use_annotated
527
464
  if self.use_annotated and not self.field_constraints: # pragma: no cover
528
- raise Exception(
529
- '`use_annotated=True` has to be used with `field_constraints=True`'
530
- )
531
- self.use_non_positive_negative_number_constrained_types = (
532
- use_non_positive_negative_number_constrained_types
533
- )
465
+ msg = "`use_annotated=True` has to be used with `field_constraints=True`"
466
+ raise Exception(msg) # noqa: TRY002
467
+ self.use_non_positive_negative_number_constrained_types = use_non_positive_negative_number_constrained_types
534
468
  self.use_double_quotes = use_double_quotes
535
469
  self.allow_responses_without_content = allow_responses_without_content
536
470
  self.collapse_root_models = collapse_root_models
@@ -541,7 +475,7 @@ class Parser(ABC):
541
475
  self.custom_formatter = custom_formatters
542
476
  self.custom_formatters_kwargs = custom_formatters_kwargs
543
477
  self.treat_dots_as_module = treat_dots_as_module
544
- self.default_field_extras: Optional[Dict[str, Any]] = default_field_extras
478
+ self.default_field_extras: dict[str, Any] | None = default_field_extras
545
479
 
546
480
  @property
547
481
  def iter_source(self) -> Iterator[Source]:
@@ -549,7 +483,7 @@ class Parser(ABC):
549
483
  yield Source(path=Path(), text=self.source)
550
484
  elif isinstance(self.source, Path): # pragma: no cover
551
485
  if self.source.is_dir():
552
- for path in sorted(self.source.rglob('*'), key=lambda p: p.name):
486
+ for path in sorted(self.source.rglob("*"), key=lambda p: p.name):
553
487
  if path.is_file():
554
488
  yield Source.from_path(path, self.base_path, self.encoding)
555
489
  else:
@@ -560,14 +494,10 @@ class Parser(ABC):
560
494
  else:
561
495
  yield Source(
562
496
  path=Path(self.source.path),
563
- text=self.remote_text_cache.get_or_put(
564
- self.source.geturl(), default_factory=self._get_text_from_url
565
- ),
497
+ text=self.remote_text_cache.get_or_put(self.source.geturl(), default_factory=self._get_text_from_url),
566
498
  )
567
499
 
568
- def _append_additional_imports(
569
- self, additional_imports: Optional[List[str]]
570
- ) -> None:
500
+ def _append_additional_imports(self, additional_imports: list[str] | None) -> None:
571
501
  if additional_imports is None:
572
502
  additional_imports = []
573
503
 
@@ -578,36 +508,34 @@ class Parser(ABC):
578
508
  self.imports.append(new_import)
579
509
 
580
510
  def _get_text_from_url(self, url: str) -> str:
581
- from datamodel_code_generator.http import get_body
511
+ from datamodel_code_generator.http import get_body # noqa: PLC0415
582
512
 
583
513
  return self.remote_text_cache.get_or_put(
584
514
  url,
585
- default_factory=lambda url_: get_body(
515
+ default_factory=lambda url_: get_body( # noqa: ARG005
586
516
  url, self.http_headers, self.http_ignore_tls, self.http_query_parameters
587
517
  ),
588
518
  )
589
519
 
590
520
  @classmethod
591
- def get_url_path_parts(cls, url: ParseResult) -> List[str]:
521
+ def get_url_path_parts(cls, url: ParseResult) -> list[str]:
592
522
  return [
593
- f'{url.scheme}://{url.hostname}',
594
- *url.path.split('/')[1:],
523
+ f"{url.scheme}://{url.hostname}",
524
+ *url.path.split("/")[1:],
595
525
  ]
596
526
 
597
527
  @property
598
- def data_type(self) -> Type[DataType]:
528
+ def data_type(self) -> type[DataType]:
599
529
  return self.data_type_manager.data_type
600
530
 
601
531
  @abstractmethod
602
532
  def parse_raw(self) -> None:
603
533
  raise NotImplementedError
604
534
 
605
- def __delete_duplicate_models(self, models: List[DataModel]) -> None:
606
- model_class_names: Dict[str, DataModel] = {}
607
- model_to_duplicate_models: DefaultDict[DataModel, List[DataModel]] = (
608
- defaultdict(list)
609
- )
610
- for model in models[:]:
535
+ def __delete_duplicate_models(self, models: list[DataModel]) -> None: # noqa: PLR0912
536
+ model_class_names: dict[str, DataModel] = {}
537
+ model_to_duplicate_models: defaultdict[DataModel, list[DataModel]] = defaultdict(list)
538
+ for model in models.copy(): # noqa: PLR1702
611
539
  if isinstance(model, self.data_model_root_type):
612
540
  root_data_type = model.fields[0].data_type
613
541
 
@@ -619,9 +547,7 @@ class Parser(ABC):
619
547
  and not root_data_type.is_list
620
548
  and root_data_type.reference.source in models
621
549
  and root_data_type.reference.name
622
- == self.model_resolver.get_class_name(
623
- model.reference.original_name, unique=False
624
- ).name
550
+ == self.model_resolver.get_class_name(model.reference.original_name, unique=False).name
625
551
  ):
626
552
  # Replace referenced duplicate model to original model
627
553
  for child in model.reference.children[:]:
@@ -655,9 +581,7 @@ class Parser(ABC):
655
581
  original_model_key = tuple(
656
582
  to_hashable(v)
657
583
  for v in (
658
- original_model.render(
659
- class_name=original_model.duplicate_class_name
660
- ),
584
+ original_model.render(class_name=original_model.duplicate_class_name),
661
585
  original_model.imports,
662
586
  )
663
587
  )
@@ -673,26 +597,21 @@ class Parser(ABC):
673
597
  # simplify if introduce duplicate base classes
674
598
  if isinstance(child, DataModel):
675
599
  child.base_classes = list(
676
- {
677
- f'{c.module_name}.{c.type_hint}': c
678
- for c in child.base_classes
679
- }.values()
600
+ {f"{c.module_name}.{c.type_hint}": c for c in child.base_classes}.values()
680
601
  )
681
602
  models.remove(duplicate_model)
682
603
 
683
604
  @classmethod
684
- def __replace_duplicate_name_in_module(cls, models: List[DataModel]) -> None:
605
+ def __replace_duplicate_name_in_module(cls, models: list[DataModel]) -> None:
685
606
  scoped_model_resolver = ModelResolver(
686
607
  exclude_names={i.alias or i.import_ for m in models for i in m.imports},
687
- duplicate_name_suffix='Model',
608
+ duplicate_name_suffix="Model",
688
609
  )
689
610
 
690
- model_names: Dict[str, DataModel] = {}
611
+ model_names: dict[str, DataModel] = {}
691
612
  for model in models:
692
613
  class_name: str = model.class_name
693
- generated_name: str = scoped_model_resolver.add(
694
- [model.path], class_name, unique=True, class_name=True
695
- ).name
614
+ generated_name: str = scoped_model_resolver.add([model.path], class_name, unique=True, class_name=True).name
696
615
  if class_name != generated_name:
697
616
  model.class_name = generated_name
698
617
  model_names[model.class_name] = model
@@ -707,10 +626,10 @@ class Parser(ABC):
707
626
 
708
627
  def __change_from_import(
709
628
  self,
710
- models: List[DataModel],
629
+ models: list[DataModel],
711
630
  imports: Imports,
712
631
  scoped_model_resolver: ModelResolver,
713
- init: bool,
632
+ init: bool, # noqa: FBT001
714
633
  ) -> None:
715
634
  for model in models:
716
635
  scoped_model_resolver.add([model.path], model.class_name)
@@ -727,42 +646,30 @@ class Parser(ABC):
727
646
 
728
647
  if isinstance(data_type, BaseClassDataType):
729
648
  left, right = relative(model.module_name, data_type.full_name)
730
- from_ = (
731
- ''.join([left, right])
732
- if left.endswith('.')
733
- else '.'.join([left, right])
734
- )
649
+ from_ = f"{left}{right}" if left.endswith(".") else f"{left}.{right}"
735
650
  import_ = data_type.reference.short_name
736
651
  full_path = from_, import_
737
652
  else:
738
- from_, import_ = full_path = relative(
739
- model.module_name, data_type.full_name
740
- )
653
+ from_, import_ = full_path = relative(model.module_name, data_type.full_name)
741
654
  if imports.use_exact: # pragma: no cover
742
- from_, import_ = exact_import(
743
- from_, import_, data_type.reference.short_name
744
- )
745
- import_ = import_.replace('-', '_')
655
+ from_, import_ = exact_import(from_, import_, data_type.reference.short_name)
656
+ import_ = import_.replace("-", "_")
746
657
  if (
747
658
  len(model.module_path) > 1
748
- and model.module_path[-1].count('.') > 0
659
+ and model.module_path[-1].count(".") > 0
749
660
  and not self.treat_dots_as_module
750
661
  ):
751
- rel_path_depth = model.module_path[-1].count('.')
662
+ rel_path_depth = model.module_path[-1].count(".")
752
663
  from_ = from_[rel_path_depth:]
753
664
 
754
665
  alias = scoped_model_resolver.add(full_path, import_).name
755
666
 
756
667
  name = data_type.reference.short_name
757
668
  if from_ and import_ and alias != name:
758
- data_type.alias = (
759
- alias
760
- if data_type.reference.short_name == import_
761
- else f'{alias}.{name}'
762
- )
669
+ data_type.alias = alias if data_type.reference.short_name == import_ else f"{alias}.{name}"
763
670
 
764
671
  if init:
765
- from_ = '.' + from_
672
+ from_ = "." + from_
766
673
  imports.append(
767
674
  Import(
768
675
  from_=from_,
@@ -776,11 +683,11 @@ class Parser(ABC):
776
683
  imports.append(after_import)
777
684
 
778
685
  @classmethod
779
- def __extract_inherited_enum(cls, models: List[DataModel]) -> None:
780
- for model in models[:]:
686
+ def __extract_inherited_enum(cls, models: list[DataModel]) -> None:
687
+ for model in models.copy():
781
688
  if model.fields:
782
689
  continue
783
- enums: List[Enum] = []
690
+ enums: list[Enum] = []
784
691
  for base_model in model.base_classes:
785
692
  if not base_model.reference:
786
693
  continue
@@ -798,20 +705,20 @@ class Parser(ABC):
798
705
  )
799
706
  models.remove(model)
800
707
 
801
- def __apply_discriminator_type(
708
+ def __apply_discriminator_type( # noqa: PLR0912, PLR0915
802
709
  self,
803
- models: List[DataModel],
710
+ models: list[DataModel],
804
711
  imports: Imports,
805
712
  ) -> None:
806
- for model in models:
713
+ for model in models: # noqa: PLR1702
807
714
  for field in model.fields:
808
- discriminator = field.extras.get('discriminator')
715
+ discriminator = field.extras.get("discriminator")
809
716
  if not discriminator or not isinstance(discriminator, dict):
810
717
  continue
811
- property_name = discriminator.get('propertyName')
718
+ property_name = discriminator.get("propertyName")
812
719
  if not property_name: # pragma: no cover
813
720
  continue
814
- mapping = discriminator.get('mapping', {})
721
+ mapping = discriminator.get("mapping", {})
815
722
  for data_type in field.data_type.data_types:
816
723
  if not data_type.reference: # pragma: no cover
817
724
  continue
@@ -828,80 +735,55 @@ class Parser(ABC):
828
735
  ):
829
736
  continue # pragma: no cover
830
737
 
831
- type_names: List[str] = []
738
+ type_names: list[str] = []
832
739
 
833
740
  def check_paths(
834
- model: Union[
835
- pydantic_model.BaseModel,
836
- pydantic_model_v2.BaseModel,
837
- Reference,
838
- ],
839
- mapping: Dict[str, str],
840
- type_names: List[str] = type_names,
741
+ model: pydantic_model.BaseModel | pydantic_model_v2.BaseModel | Reference,
742
+ mapping: dict[str, str],
743
+ type_names: list[str] = type_names,
841
744
  ) -> None:
842
745
  """Helper function to validate paths for a given model."""
843
746
  for name, path in mapping.items():
844
- if (
845
- model.path.split('#/')[-1] != path.split('#/')[-1]
846
- ) and (
847
- path.startswith('#/')
848
- or model.path[:-1] != path.split('/')[-1]
747
+ if (model.path.split("#/")[-1] != path.split("#/")[-1]) and (
748
+ path.startswith("#/") or model.path[:-1] != path.split("/")[-1]
849
749
  ):
850
- t_path = path[str(path).find('/') + 1 :]
851
- t_disc = model.path[: str(model.path).find('#')].lstrip(
852
- '../'
853
- )
854
- t_disc_2 = '/'.join(t_disc.split('/')[1:])
855
- if t_path != t_disc and t_path != t_disc_2:
750
+ t_path = path[str(path).find("/") + 1 :]
751
+ t_disc = model.path[: str(model.path).find("#")].lstrip("../") # noqa: B005
752
+ t_disc_2 = "/".join(t_disc.split("/")[1:])
753
+ if t_path not in {t_disc, t_disc_2}:
856
754
  continue
857
755
  type_names.append(name)
858
756
 
859
757
  # Check the main discriminator model path
860
758
  if mapping:
861
- check_paths(discriminator_model, mapping) # pyright: ignore [reportArgumentType]
759
+ check_paths(discriminator_model, mapping) # pyright: ignore[reportArgumentType]
862
760
 
863
761
  # Check the base_classes if they exist
864
762
  if len(type_names) == 0:
865
763
  for base_class in discriminator_model.base_classes:
866
- check_paths(base_class.reference, mapping) # pyright: ignore [reportArgumentType]
764
+ check_paths(base_class.reference, mapping) # pyright: ignore[reportArgumentType]
867
765
  else:
868
- type_names = [discriminator_model.path.split('/')[-1]]
766
+ type_names = [discriminator_model.path.split("/")[-1]]
869
767
  if not type_names: # pragma: no cover
870
- raise RuntimeError(
871
- f'Discriminator type is not found. {data_type.reference.path}'
872
- )
768
+ msg = f"Discriminator type is not found. {data_type.reference.path}"
769
+ raise RuntimeError(msg)
873
770
  has_one_literal = False
874
771
  for discriminator_field in discriminator_model.fields:
875
- if (
876
- discriminator_field.original_name
877
- or discriminator_field.name
878
- ) != property_name:
772
+ if (discriminator_field.original_name or discriminator_field.name) != property_name:
879
773
  continue
880
774
  literals = discriminator_field.data_type.literals
881
- if len(literals) == 1 and literals[0] == (
882
- type_names[0] if type_names else None
883
- ):
775
+ if len(literals) == 1 and literals[0] == (type_names[0] if type_names else None):
884
776
  has_one_literal = True
885
- if isinstance(
886
- discriminator_model, msgspec_model.Struct
887
- ): # pragma: no cover
888
- discriminator_model.add_base_class_kwarg(
889
- 'tag_field', f"'{property_name}'"
890
- )
891
- discriminator_model.add_base_class_kwarg(
892
- 'tag', discriminator_field.represented_default
893
- )
894
- discriminator_field.extras['is_classvar'] = True
777
+ if isinstance(discriminator_model, msgspec_model.Struct): # pragma: no cover
778
+ discriminator_model.add_base_class_kwarg("tag_field", f"'{property_name}'")
779
+ discriminator_model.add_base_class_kwarg("tag", discriminator_field.represented_default)
780
+ discriminator_field.extras["is_classvar"] = True
895
781
  # Found the discriminator field, no need to keep looking
896
782
  break
897
- for (
898
- field_data_type
899
- ) in discriminator_field.data_type.all_data_types:
783
+ for field_data_type in discriminator_field.data_type.all_data_types:
900
784
  if field_data_type.reference: # pragma: no cover
901
785
  field_data_type.remove_reference()
902
- discriminator_field.data_type = self.data_type(
903
- literals=type_names
904
- )
786
+ discriminator_field.data_type = self.data_type(literals=type_names)
905
787
  discriminator_field.data_type.parent = discriminator_field
906
788
  discriminator_field.required = True
907
789
  imports.append(discriminator_field.imports)
@@ -914,20 +796,12 @@ class Parser(ABC):
914
796
  required=True,
915
797
  )
916
798
  )
917
- literal = (
918
- IMPORT_LITERAL
919
- if self.target_python_version.has_literal_type
920
- else IMPORT_LITERAL_BACKPORT
921
- )
922
- has_imported_literal = any(
923
- literal == import_ # type: ignore [comparison-overlap]
924
- for import_ in imports
925
- )
799
+ has_imported_literal = any(import_ == IMPORT_LITERAL for import_ in imports)
926
800
  if has_imported_literal: # pragma: no cover
927
- imports.append(literal)
801
+ imports.append(IMPORT_LITERAL)
928
802
 
929
803
  @classmethod
930
- def _create_set_from_list(cls, data_type: DataType) -> Optional[DataType]:
804
+ def _create_set_from_list(cls, data_type: DataType) -> DataType | None:
931
805
  if data_type.is_list:
932
806
  new_data_type = data_type.copy()
933
807
  new_data_type.is_list = False
@@ -935,7 +809,7 @@ class Parser(ABC):
935
809
  for data_type_ in new_data_type.data_types:
936
810
  data_type_.parent = new_data_type
937
811
  return new_data_type
938
- elif data_type.data_types: # pragma: no cover
812
+ if data_type.data_types: # pragma: no cover
939
813
  for index, nested_data_type in enumerate(data_type.data_types[:]):
940
814
  set_data_type = cls._create_set_from_list(nested_data_type)
941
815
  if set_data_type: # pragma: no cover
@@ -943,15 +817,13 @@ class Parser(ABC):
943
817
  return data_type
944
818
  return None # pragma: no cover
945
819
 
946
- def __replace_unique_list_to_set(self, models: List[DataModel]) -> None:
820
+ def __replace_unique_list_to_set(self, models: list[DataModel]) -> None:
947
821
  for model in models:
948
822
  for model_field in model.fields:
949
823
  if not self.use_unique_items_as_set:
950
824
  continue
951
825
 
952
- if not (
953
- model_field.constraints and model_field.constraints.unique_items
954
- ):
826
+ if not (model_field.constraints and model_field.constraints.unique_items):
955
827
  continue
956
828
  set_data_type = self._create_set_from_list(model_field.data_type)
957
829
  if set_data_type: # pragma: no cover
@@ -960,30 +832,25 @@ class Parser(ABC):
960
832
  set_data_type.parent = model_field
961
833
 
962
834
  @classmethod
963
- def __set_reference_default_value_to_field(cls, models: List[DataModel]) -> None:
835
+ def __set_reference_default_value_to_field(cls, models: list[DataModel]) -> None:
964
836
  for model in models:
965
837
  for model_field in model.fields:
966
838
  if not model_field.data_type.reference or model_field.has_default:
967
839
  continue
968
- if isinstance(
969
- model_field.data_type.reference.source, DataModel
970
- ): # pragma: no cover
971
- if model_field.data_type.reference.source.default != UNDEFINED:
972
- model_field.default = (
973
- model_field.data_type.reference.source.default
974
- )
840
+ if (
841
+ isinstance(model_field.data_type.reference.source, DataModel)
842
+ and model_field.data_type.reference.source.default != UNDEFINED
843
+ ):
844
+ # pragma: no cover
845
+ model_field.default = model_field.data_type.reference.source.default
975
846
 
976
- def __reuse_model(
977
- self, models: List[DataModel], require_update_action_models: List[str]
978
- ) -> None:
847
+ def __reuse_model(self, models: list[DataModel], require_update_action_models: list[str]) -> None:
979
848
  if not self.reuse_model:
980
- return None
981
- model_cache: Dict[Tuple[str, ...], Reference] = {}
849
+ return
850
+ model_cache: dict[tuple[str, ...], Reference] = {}
982
851
  duplicates = []
983
- for model in models[:]:
984
- model_key = tuple(
985
- to_hashable(v) for v in (model.render(class_name='M'), model.imports)
986
- )
852
+ for model in models.copy():
853
+ model_key = tuple(to_hashable(v) for v in (model.render(class_name="M"), model.imports))
987
854
  cached_model_reference = model_cache.get(model_key)
988
855
  if cached_model_reference:
989
856
  if isinstance(model, Enum):
@@ -1002,9 +869,9 @@ class Parser(ABC):
1002
869
  description=model.description,
1003
870
  reference=Reference(
1004
871
  name=model.name,
1005
- path=model.reference.path + '/reuse',
872
+ path=model.reference.path + "/reuse",
1006
873
  ),
1007
- custom_template_dir=model._custom_template_dir,
874
+ custom_template_dir=model._custom_template_dir, # noqa: SLF001
1008
875
  )
1009
876
  if cached_model_reference.path in require_update_action_models:
1010
877
  require_update_action_models.append(inherited_model.path)
@@ -1017,23 +884,21 @@ class Parser(ABC):
1017
884
  for duplicate in duplicates:
1018
885
  models.remove(duplicate)
1019
886
 
1020
- def __collapse_root_models(
887
+ def __collapse_root_models( # noqa: PLR0912
1021
888
  self,
1022
- models: List[DataModel],
1023
- unused_models: List[DataModel],
889
+ models: list[DataModel],
890
+ unused_models: list[DataModel],
1024
891
  imports: Imports,
1025
892
  scoped_model_resolver: ModelResolver,
1026
893
  ) -> None:
1027
894
  if not self.collapse_root_models:
1028
- return None
895
+ return
1029
896
 
1030
- for model in models:
897
+ for model in models: # noqa: PLR1702
1031
898
  for model_field in model.fields:
1032
899
  for data_type in model_field.data_type.all_data_types:
1033
900
  reference = data_type.reference
1034
- if not reference or not isinstance(
1035
- reference.source, self.data_model_root_type
1036
- ):
901
+ if not reference or not isinstance(reference.source, self.data_model_root_type):
1037
902
  continue
1038
903
 
1039
904
  # Use root-type as model_field type
@@ -1044,11 +909,7 @@ class Parser(ABC):
1044
909
  self.field_constraints
1045
910
  and isinstance(root_type_field.constraints, ConstraintsBase)
1046
911
  and root_type_field.constraints.has_constraints
1047
- and any(
1048
- d
1049
- for d in model_field.data_type.all_data_types
1050
- if d.is_dict or d.is_union or d.is_list
1051
- )
912
+ and any(d for d in model_field.data_type.all_data_types if d.is_dict or d.is_union or d.is_list)
1052
913
  ):
1053
914
  continue # pragma: no cover
1054
915
 
@@ -1078,23 +939,19 @@ class Parser(ABC):
1078
939
  if isinstance(
1079
940
  root_type_field,
1080
941
  pydantic_model.DataModelField,
1081
- ) and not model_field.extras.get('discriminator'):
1082
- discriminator = root_type_field.extras.get('discriminator')
942
+ ) and not model_field.extras.get("discriminator"):
943
+ discriminator = root_type_field.extras.get("discriminator")
1083
944
  if discriminator:
1084
- model_field.extras['discriminator'] = discriminator
945
+ model_field.extras["discriminator"] = discriminator
1085
946
  assert isinstance(data_type.parent, DataType)
1086
- data_type.parent.data_types.remove(
1087
- data_type
1088
- ) # pragma: no cover
947
+ data_type.parent.data_types.remove(data_type) # pragma: no cover
1089
948
  data_type.parent.data_types.append(copied_data_type)
1090
949
 
1091
950
  elif isinstance(data_type.parent, DataType):
1092
951
  # for data_type
1093
952
  data_type_id = id(data_type)
1094
953
  data_type.parent.data_types = [
1095
- d
1096
- for d in (*data_type.parent.data_types, copied_data_type)
1097
- if id(d) != data_type_id
954
+ d for d in (*data_type.parent.data_types, copied_data_type) if id(d) != data_type_id
1098
955
  ]
1099
956
  else: # pragma: no cover
1100
957
  continue
@@ -1102,26 +959,22 @@ class Parser(ABC):
1102
959
  for d in root_type_field.data_type.data_types:
1103
960
  if d.reference is None:
1104
961
  continue
1105
- from_, import_ = full_path = relative(
1106
- model.module_name, d.full_name
1107
- )
962
+ from_, import_ = full_path = relative(model.module_name, d.full_name)
1108
963
  if from_ and import_:
1109
964
  alias = scoped_model_resolver.add(full_path, import_)
1110
965
  d.alias = (
1111
966
  alias.name
1112
967
  if d.reference.short_name == import_
1113
- else f'{alias.name}.{d.reference.short_name}'
1114
- )
1115
- imports.append(
1116
- [
1117
- Import(
1118
- from_=from_,
1119
- import_=import_,
1120
- alias=alias.name,
1121
- reference_path=d.reference.path,
1122
- )
1123
- ]
968
+ else f"{alias.name}.{d.reference.short_name}"
1124
969
  )
970
+ imports.append([
971
+ Import(
972
+ from_=from_,
973
+ import_=import_,
974
+ alias=alias.name,
975
+ reference_path=d.reference.path,
976
+ )
977
+ ])
1125
978
 
1126
979
  original_field = get_most_of_parent(data_type, DataModelFieldBase)
1127
980
  if original_field: # pragma: no cover
@@ -1131,42 +984,31 @@ class Parser(ABC):
1131
984
  data_type.remove_reference()
1132
985
 
1133
986
  root_type_model.reference.children = [
1134
- c
1135
- for c in root_type_model.reference.children
1136
- if getattr(c, 'parent', None)
987
+ c for c in root_type_model.reference.children if getattr(c, "parent", None)
1137
988
  ]
1138
989
 
1139
990
  imports.remove_referenced_imports(root_type_model.path)
1140
991
  if not root_type_model.reference.children:
1141
992
  unused_models.append(root_type_model)
1142
993
 
1143
- def __set_default_enum_member(
994
+ def __set_default_enum_member( # noqa: PLR0912
1144
995
  self,
1145
- models: List[DataModel],
996
+ models: list[DataModel],
1146
997
  ) -> None:
1147
998
  if not self.set_default_enum_member:
1148
- return None
1149
- for model in models:
999
+ return
1000
+ for model in models: # noqa: PLR1702
1150
1001
  for model_field in model.fields:
1151
1002
  if not model_field.default:
1152
1003
  continue
1153
1004
  for data_type in model_field.data_type.all_data_types:
1154
- if data_type.reference and isinstance(
1155
- data_type.reference.source, Enum
1156
- ): # pragma: no cover
1005
+ if data_type.reference and isinstance(data_type.reference.source, Enum): # pragma: no cover
1157
1006
  if isinstance(model_field.default, list):
1158
- enum_member: Union[List[Member], Optional[Member]] = [
1159
- e
1160
- for e in (
1161
- data_type.reference.source.find_member(d)
1162
- for d in model_field.default
1163
- )
1164
- if e
1007
+ enum_member: list[Member] | (Member | None) = [
1008
+ e for e in (data_type.reference.source.find_member(d) for d in model_field.default) if e
1165
1009
  ]
1166
1010
  else:
1167
- enum_member = data_type.reference.source.find_member(
1168
- model_field.default
1169
- )
1011
+ enum_member = data_type.reference.source.find_member(model_field.default)
1170
1012
  if not enum_member:
1171
1013
  continue
1172
1014
  model_field.default = enum_member
@@ -1179,7 +1021,7 @@ class Parser(ABC):
1179
1021
 
1180
1022
  def __override_required_field(
1181
1023
  self,
1182
- models: List[DataModel],
1024
+ models: list[DataModel],
1183
1025
  ) -> None:
1184
1026
  for model in models:
1185
1027
  if isinstance(model, (Enum, self.data_model_root_type)):
@@ -1187,7 +1029,7 @@ class Parser(ABC):
1187
1029
  for index, model_field in enumerate(model.fields[:]):
1188
1030
  data_type = model_field.data_type
1189
1031
  if (
1190
- not model_field.original_name
1032
+ not model_field.original_name # noqa: PLR0916
1191
1033
  or data_type.data_types
1192
1034
  or data_type.reference
1193
1035
  or data_type.type
@@ -1196,9 +1038,7 @@ class Parser(ABC):
1196
1038
  ):
1197
1039
  continue
1198
1040
 
1199
- original_field = _find_field(
1200
- model_field.original_name, _find_base_classes(model)
1201
- )
1041
+ original_field = _find_field(model_field.original_name, _find_base_classes(model))
1202
1042
  if not original_field: # pragma: no cover
1203
1043
  model.fields.remove(model_field)
1204
1044
  continue
@@ -1209,9 +1049,7 @@ class Parser(ABC):
1209
1049
  )
1210
1050
  elif original_field.data_type.data_types:
1211
1051
  data_type = original_field.data_type.copy()
1212
- data_type.data_types = _copy_data_types(
1213
- original_field.data_type.data_types
1214
- )
1052
+ data_type.data_types = _copy_data_types(original_field.data_type.data_types)
1215
1053
  for data_type_ in data_type.data_types:
1216
1054
  data_type_.parent = data_type
1217
1055
  else:
@@ -1225,7 +1063,7 @@ class Parser(ABC):
1225
1063
 
1226
1064
  def __sort_models(
1227
1065
  self,
1228
- models: List[DataModel],
1066
+ models: list[DataModel],
1229
1067
  imports: Imports,
1230
1068
  ) -> None:
1231
1069
  if not self.keep_model_order:
@@ -1234,7 +1072,7 @@ class Parser(ABC):
1234
1072
  models.sort(key=lambda x: x.class_name)
1235
1073
 
1236
1074
  imported = {i for v in imports.values() for i in v}
1237
- model_class_name_baseclasses: Dict[DataModel, Tuple[str, Set[str]]] = {}
1075
+ model_class_name_baseclasses: dict[DataModel, tuple[str, set[str]]] = {}
1238
1076
  for model in models:
1239
1077
  class_name = model.class_name
1240
1078
  model_class_name_baseclasses[model] = (
@@ -1255,9 +1093,9 @@ class Parser(ABC):
1255
1093
  models[i], models[i + 1] = models[i + 1], model
1256
1094
  changed = True
1257
1095
 
1258
- def __set_one_literal_on_default(self, models: List[DataModel]) -> None:
1096
+ def __set_one_literal_on_default(self, models: list[DataModel]) -> None:
1259
1097
  if not self.use_one_literal_as_default:
1260
- return None
1098
+ return
1261
1099
  for model in models:
1262
1100
  for model_field in model.fields:
1263
1101
  if not model_field.required or len(model_field.data_type.literals) != 1:
@@ -1268,41 +1106,39 @@ class Parser(ABC):
1268
1106
  model_field.nullable = False
1269
1107
 
1270
1108
  @classmethod
1271
- def __postprocess_result_modules(cls, results):
1272
- def process(input_tuple) -> Tuple[str, ...]:
1109
+ def __postprocess_result_modules(cls, results: dict[tuple[str, ...], Result]) -> dict[tuple[str, ...], Result]:
1110
+ def process(input_tuple: tuple[str, ...]) -> tuple[str, ...]:
1273
1111
  r = []
1274
1112
  for item in input_tuple:
1275
- p = item.split('.')
1113
+ p = item.split(".")
1276
1114
  if len(p) > 1:
1277
1115
  r.extend(p[:-1])
1278
1116
  r.append(p[-1])
1279
1117
  else:
1280
1118
  r.append(item)
1281
1119
 
1282
- r = r[:-2] + [f'{r[-2]}.{r[-1]}']
1120
+ r = r[:-2] + [f"{r[-2]}.{r[-1]}"]
1283
1121
  return tuple(r)
1284
1122
 
1285
1123
  results = {process(k): v for k, v in results.items()}
1286
1124
 
1287
- init_result = [v for k, v in results.items() if k[-1] == '__init__.py'][0]
1288
- folders = {t[:-1] if t[-1].endswith('.py') else t for t in results.keys()}
1125
+ init_result = next(v for k, v in results.items() if k[-1] == "__init__.py")
1126
+ folders = {t[:-1] if t[-1].endswith(".py") else t for t in results}
1289
1127
  for folder in folders:
1290
1128
  for i in range(len(folder)):
1291
1129
  subfolder = folder[: i + 1]
1292
- init_file = subfolder + ('__init__.py',)
1130
+ init_file = (*subfolder, "__init__.py")
1293
1131
  results.update({init_file: init_result})
1294
1132
  return results
1295
1133
 
1296
- def __change_imported_model_name(
1134
+ def __change_imported_model_name( # noqa: PLR6301
1297
1135
  self,
1298
- models: List[DataModel],
1136
+ models: list[DataModel],
1299
1137
  imports: Imports,
1300
1138
  scoped_model_resolver: ModelResolver,
1301
1139
  ) -> None:
1302
1140
  imported_names = {
1303
- imports.alias[from_][i]
1304
- if i in imports.alias[from_] and i != imports.alias[from_][i]
1305
- else i
1141
+ imports.alias[from_][i] if i in imports.alias[from_] and i != imports.alias[from_][i] else i
1306
1142
  for from_, import_ in imports.items()
1307
1143
  for i in import_
1308
1144
  }
@@ -1311,26 +1147,25 @@ class Parser(ABC):
1311
1147
  continue
1312
1148
 
1313
1149
  model.reference.name = scoped_model_resolver.add( # pragma: no cover
1314
- path=get_special_path('imported_name', model.path.split('/')),
1150
+ path=get_special_path("imported_name", model.path.split("/")),
1315
1151
  original_name=model.reference.name,
1316
1152
  unique=True,
1317
1153
  class_name=True,
1318
1154
  ).name
1319
1155
 
1320
- def parse(
1156
+ def parse( # noqa: PLR0912, PLR0914, PLR0915
1321
1157
  self,
1322
- with_import: Optional[bool] = True,
1323
- format_: Optional[bool] = True,
1324
- settings_path: Optional[Path] = None,
1325
- ) -> Union[str, Dict[Tuple[str, ...], Result]]:
1158
+ with_import: bool | None = True, # noqa: FBT001, FBT002
1159
+ format_: bool | None = True, # noqa: FBT001, FBT002
1160
+ settings_path: Path | None = None,
1161
+ ) -> str | dict[tuple[str, ...], Result]:
1326
1162
  self.parse_raw()
1327
1163
 
1328
1164
  if with_import:
1329
- if self.target_python_version != PythonVersion.PY_36:
1330
- self.imports.append(IMPORT_ANNOTATIONS)
1165
+ self.imports.append(IMPORT_ANNOTATIONS)
1331
1166
 
1332
1167
  if format_:
1333
- code_formatter: Optional[CodeFormatter] = CodeFormatter(
1168
+ code_formatter: CodeFormatter | None = CodeFormatter(
1334
1169
  self.target_python_version,
1335
1170
  settings_path,
1336
1171
  self.wrap_string_literal,
@@ -1342,16 +1177,14 @@ class Parser(ABC):
1342
1177
  else:
1343
1178
  code_formatter = None
1344
1179
 
1345
- _, sorted_data_models, require_update_action_models = sort_data_models(
1346
- self.results
1347
- )
1180
+ _, sorted_data_models, require_update_action_models = sort_data_models(self.results)
1348
1181
 
1349
- results: Dict[Tuple[str, ...], Result] = {}
1182
+ results: dict[tuple[str, ...], Result] = {}
1350
1183
 
1351
- def module_key(data_model: DataModel) -> Tuple[str, ...]:
1184
+ def module_key(data_model: DataModel) -> tuple[str, ...]:
1352
1185
  return tuple(data_model.module_path)
1353
1186
 
1354
- def sort_key(data_model: DataModel) -> Tuple[int, Tuple[str, ...]]:
1187
+ def sort_key(data_model: DataModel) -> tuple[int, tuple[str, ...]]:
1355
1188
  return (len(data_model.module_path), tuple(data_model.module_path))
1356
1189
 
1357
1190
  # process in reverse order to correctly establish module levels
@@ -1360,59 +1193,54 @@ class Parser(ABC):
1360
1193
  key=module_key,
1361
1194
  )
1362
1195
 
1363
- module_models: List[Tuple[Tuple[str, ...], List[DataModel]]] = []
1364
- unused_models: List[DataModel] = []
1365
- model_to_module_models: Dict[
1366
- DataModel, Tuple[Tuple[str, ...], List[DataModel]]
1367
- ] = {}
1368
- module_to_import: Dict[Tuple[str, ...], Imports] = {}
1196
+ module_models: list[tuple[tuple[str, ...], list[DataModel]]] = []
1197
+ unused_models: list[DataModel] = []
1198
+ model_to_module_models: dict[DataModel, tuple[tuple[str, ...], list[DataModel]]] = {}
1199
+ module_to_import: dict[tuple[str, ...], Imports] = {}
1369
1200
 
1370
- previous_module = () # type: Tuple[str, ...]
1201
+ previous_module: tuple[str, ...] = ()
1371
1202
  for module, models in ((k, [*v]) for k, v in grouped_models):
1372
1203
  for model in models:
1373
1204
  model_to_module_models[model] = module, models
1374
1205
  self.__delete_duplicate_models(models)
1375
1206
  self.__replace_duplicate_name_in_module(models)
1376
1207
  if len(previous_module) - len(module) > 1:
1377
- for parts in range(len(previous_module) - 1, len(module), -1):
1378
- module_models.append(
1379
- (
1380
- previous_module[:parts],
1381
- [],
1382
- )
1208
+ module_models.extend(
1209
+ (
1210
+ previous_module[:parts],
1211
+ [],
1383
1212
  )
1384
- module_models.append(
1385
- (
1386
- module,
1387
- models,
1213
+ for parts in range(len(previous_module) - 1, len(module), -1)
1388
1214
  )
1389
- )
1215
+ module_models.append((
1216
+ module,
1217
+ models,
1218
+ ))
1390
1219
  previous_module = module
1391
1220
 
1392
1221
  class Processed(NamedTuple):
1393
- module: Tuple[str, ...]
1394
- models: List[DataModel]
1222
+ module: tuple[str, ...]
1223
+ models: list[DataModel]
1395
1224
  init: bool
1396
1225
  imports: Imports
1397
1226
  scoped_model_resolver: ModelResolver
1398
1227
 
1399
- processed_models: List[Processed] = []
1228
+ processed_models: list[Processed] = []
1400
1229
 
1401
- for module, models in module_models:
1402
- imports = module_to_import[module] = Imports(self.use_exact_imports)
1230
+ for module_, models in module_models:
1231
+ imports = module_to_import[module_] = Imports(self.use_exact_imports)
1403
1232
  init = False
1404
- if module:
1405
- parent = (*module[:-1], '__init__.py')
1233
+ if module_:
1234
+ parent = (*module_[:-1], "__init__.py")
1406
1235
  if parent not in results:
1407
- results[parent] = Result(body='')
1408
- if (*module, '__init__.py') in results:
1409
- module = (*module, '__init__.py')
1236
+ results[parent] = Result(body="")
1237
+ if (*module_, "__init__.py") in results:
1238
+ module = (*module_, "__init__.py")
1410
1239
  init = True
1411
1240
  else:
1412
- module = (*module[:-1], f'{module[-1]}.py')
1413
- module = tuple(part.replace('-', '_') for part in module)
1241
+ module = tuple(part.replace("-", "_") for part in (*module_[:-1], f"{module_[-1]}.py"))
1414
1242
  else:
1415
- module = ('__init__.py',)
1243
+ module = ("__init__.py",)
1416
1244
 
1417
1245
  scoped_model_resolver = ModelResolver()
1418
1246
 
@@ -1422,17 +1250,13 @@ class Parser(ABC):
1422
1250
  self.__extract_inherited_enum(models)
1423
1251
  self.__set_reference_default_value_to_field(models)
1424
1252
  self.__reuse_model(models, require_update_action_models)
1425
- self.__collapse_root_models(
1426
- models, unused_models, imports, scoped_model_resolver
1427
- )
1253
+ self.__collapse_root_models(models, unused_models, imports, scoped_model_resolver)
1428
1254
  self.__set_default_enum_member(models)
1429
1255
  self.__sort_models(models, imports)
1430
1256
  self.__apply_discriminator_type(models, imports)
1431
1257
  self.__set_one_literal_on_default(models)
1432
1258
 
1433
- processed_models.append(
1434
- Processed(module, models, init, imports, scoped_model_resolver)
1435
- )
1259
+ processed_models.append(Processed(module, models, init, imports, scoped_model_resolver))
1436
1260
 
1437
1261
  for processed_model in processed_models:
1438
1262
  for model in processed_model.models:
@@ -1447,7 +1271,7 @@ class Parser(ABC):
1447
1271
 
1448
1272
  for processed_model in processed_models:
1449
1273
  # postprocess imports to remove unused imports.
1450
- model_code = str('\n'.join([str(m) for m in processed_model.models]))
1274
+ model_code = str("\n".join([str(m) for m in processed_model.models]))
1451
1275
  unused_imports = [
1452
1276
  (from_, import_)
1453
1277
  for from_, imports_ in processed_model.imports.items()
@@ -1457,56 +1281,44 @@ class Parser(ABC):
1457
1281
  for from_, import_ in unused_imports:
1458
1282
  processed_model.imports.remove(Import(from_=from_, import_=import_))
1459
1283
 
1460
- for module, models, init, imports, scoped_model_resolver in processed_models:
1284
+ for module, models, init, imports, scoped_model_resolver in processed_models: # noqa: B007
1461
1285
  # process after removing unused models
1462
1286
  self.__change_imported_model_name(models, imports, scoped_model_resolver)
1463
1287
 
1464
- for module, models, init, imports, scoped_model_resolver in processed_models:
1465
- result: List[str] = []
1288
+ for module, models, init, imports, scoped_model_resolver in processed_models: # noqa: B007
1289
+ result: list[str] = []
1466
1290
  if models:
1467
1291
  if with_import:
1468
- result += [str(self.imports), str(imports), '\n']
1292
+ result += [str(self.imports), str(imports), "\n"]
1469
1293
 
1470
1294
  code = dump_templates(models)
1471
1295
  result += [code]
1472
1296
 
1473
1297
  if self.dump_resolve_reference_action is not None:
1474
1298
  result += [
1475
- '\n',
1299
+ "\n",
1476
1300
  self.dump_resolve_reference_action(
1477
- m.reference.short_name
1478
- for m in models
1479
- if m.path in require_update_action_models
1301
+ m.reference.short_name for m in models if m.path in require_update_action_models
1480
1302
  ),
1481
1303
  ]
1482
1304
  if not result and not init:
1483
1305
  continue
1484
- body = '\n'.join(result)
1306
+ body = "\n".join(result)
1485
1307
  if code_formatter:
1486
1308
  body = code_formatter.format_code(body)
1487
1309
 
1488
- results[module] = Result(
1489
- body=body, source=models[0].file_path if models else None
1490
- )
1310
+ results[module] = Result(body=body, source=models[0].file_path if models else None)
1491
1311
 
1492
1312
  # retain existing behaviour
1493
- if [*results] == [('__init__.py',)]:
1494
- return results[('__init__.py',)].body
1313
+ if [*results] == [("__init__.py",)]:
1314
+ return results["__init__.py",].body
1495
1315
 
1496
- results = {tuple(i.replace('-', '_') for i in k): v for k, v in results.items()}
1497
- results = (
1316
+ results = {tuple(i.replace("-", "_") for i in k): v for k, v in results.items()}
1317
+ return (
1498
1318
  self.__postprocess_result_modules(results)
1499
1319
  if self.treat_dots_as_module
1500
1320
  else {
1501
- tuple(
1502
- (
1503
- part[: part.rfind('.')].replace('.', '_')
1504
- + part[part.rfind('.') :]
1505
- )
1506
- for part in k
1507
- ): v
1321
+ tuple((part[: part.rfind(".")].replace(".", "_") + part[part.rfind(".") :]) for part in k): v
1508
1322
  for k, v in results.items()
1509
1323
  }
1510
1324
  )
1511
-
1512
- return results