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