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
@@ -2,20 +2,13 @@ from __future__ import annotations
2
2
 
3
3
  from pathlib import Path
4
4
  from typing import (
5
+ TYPE_CHECKING,
5
6
  Any,
6
7
  Callable,
7
- DefaultDict,
8
- Dict,
9
8
  Iterable,
10
9
  Iterator,
11
- List,
12
10
  Mapping,
13
- Optional,
14
11
  Sequence,
15
- Set,
16
- Tuple,
17
- Type,
18
- Union,
19
12
  )
20
13
  from urllib.parse import ParseResult
21
14
 
@@ -41,13 +34,16 @@ from datamodel_code_generator.types import DataTypeManager, StrictTypes, Types
41
34
 
42
35
  try:
43
36
  import graphql
44
- except ImportError: # pragma: no cover
45
- raise Exception(
46
- "Please run `$pip install 'datamodel-code-generator[graphql]`' to generate data-model from a GraphQL schema."
47
- )
37
+ except ImportError as exc: # pragma: no cover
38
+ msg = "Please run `$pip install 'datamodel-code-generator[graphql]`' to generate data-model from a GraphQL schema."
39
+ raise Exception(msg) from exc # noqa: TRY002
40
+
48
41
 
49
42
  from datamodel_code_generator.format import DatetimeClassType
50
43
 
44
+ if TYPE_CHECKING:
45
+ from collections import defaultdict
46
+
51
47
  graphql_resolver = graphql.type.introspection.TypeResolvers()
52
48
 
53
49
 
@@ -57,26 +53,24 @@ def build_graphql_schema(schema_str: str) -> graphql.GraphQLSchema:
57
53
  return graphql.lexicographic_sort_schema(schema)
58
54
 
59
55
 
60
- @snooper_to_methods(max_variable_length=None)
56
+ @snooper_to_methods()
61
57
  class GraphQLParser(Parser):
62
58
  # raw graphql schema as `graphql-core` object
63
59
  raw_obj: graphql.GraphQLSchema
64
60
  # all processed graphql objects
65
61
  # mapper from an object name (unique) to an object
66
- all_graphql_objects: Dict[str, graphql.GraphQLNamedType]
62
+ all_graphql_objects: dict[str, graphql.GraphQLNamedType]
67
63
  # a reference for each object
68
64
  # mapper from an object name to his reference
69
- references: Dict[str, Reference] = {}
65
+ references: dict[str, Reference] = {} # noqa: RUF012
70
66
  # mapper from graphql type to all objects with this type
71
67
  # `graphql.type.introspection.TypeKind` -- an enum with all supported types
72
68
  # `graphql.GraphQLNamedType` -- base type for each graphql object
73
69
  # see `graphql-core` for more details
74
- support_graphql_types: Dict[
75
- graphql.type.introspection.TypeKind, List[graphql.GraphQLNamedType]
76
- ]
70
+ support_graphql_types: dict[graphql.type.introspection.TypeKind, list[graphql.GraphQLNamedType]]
77
71
  # graphql types order for render
78
72
  # may be as a parameter in the future
79
- parse_order: List[graphql.type.introspection.TypeKind] = [
73
+ parse_order: list[graphql.type.introspection.TypeKind] = [ # noqa: RUF012
80
74
  graphql.type.introspection.TypeKind.SCALAR,
81
75
  graphql.type.introspection.TypeKind.ENUM,
82
76
  graphql.type.introspection.TypeKind.INTERFACE,
@@ -85,79 +79,79 @@ class GraphQLParser(Parser):
85
79
  graphql.type.introspection.TypeKind.UNION,
86
80
  ]
87
81
 
88
- def __init__(
82
+ def __init__( # noqa: PLR0913
89
83
  self,
90
- source: Union[str, Path, ParseResult],
84
+ source: str | Path | ParseResult,
91
85
  *,
92
- data_model_type: Type[DataModel] = pydantic_model.BaseModel,
93
- data_model_root_type: Type[DataModel] = pydantic_model.CustomRootType,
94
- data_model_scalar_type: Type[DataModel] = DataTypeScalar,
95
- data_model_union_type: Type[DataModel] = DataTypeUnion,
96
- data_type_manager_type: Type[DataTypeManager] = pydantic_model.DataTypeManager,
97
- data_model_field_type: Type[DataModelFieldBase] = pydantic_model.DataModelField,
98
- base_class: Optional[str] = None,
99
- additional_imports: Optional[List[str]] = None,
100
- custom_template_dir: Optional[Path] = None,
101
- extra_template_data: Optional[DefaultDict[str, Dict[str, Any]]] = None,
86
+ data_model_type: type[DataModel] = pydantic_model.BaseModel,
87
+ data_model_root_type: type[DataModel] = pydantic_model.CustomRootType,
88
+ data_model_scalar_type: type[DataModel] = DataTypeScalar,
89
+ data_model_union_type: type[DataModel] = DataTypeUnion,
90
+ data_type_manager_type: type[DataTypeManager] = pydantic_model.DataTypeManager,
91
+ data_model_field_type: type[DataModelFieldBase] = pydantic_model.DataModelField,
92
+ base_class: str | None = None,
93
+ additional_imports: list[str] | None = None,
94
+ custom_template_dir: Path | None = None,
95
+ extra_template_data: defaultdict[str, dict[str, Any]] | None = None,
102
96
  target_python_version: PythonVersion = PythonVersion.PY_38,
103
- dump_resolve_reference_action: Optional[Callable[[Iterable[str]], str]] = None,
97
+ dump_resolve_reference_action: Callable[[Iterable[str]], str] | None = None,
104
98
  validation: bool = False,
105
99
  field_constraints: bool = False,
106
100
  snake_case_field: bool = False,
107
101
  strip_default_none: bool = False,
108
- aliases: Optional[Mapping[str, str]] = None,
102
+ aliases: Mapping[str, str] | None = None,
109
103
  allow_population_by_field_name: bool = False,
110
104
  apply_default_values_for_required_fields: bool = False,
111
105
  allow_extra_fields: bool = False,
112
106
  force_optional_for_required_fields: bool = False,
113
- class_name: Optional[str] = None,
107
+ class_name: str | None = None,
114
108
  use_standard_collections: bool = False,
115
- base_path: Optional[Path] = None,
109
+ base_path: Path | None = None,
116
110
  use_schema_description: bool = False,
117
111
  use_field_description: bool = False,
118
112
  use_default_kwarg: bool = False,
119
113
  reuse_model: bool = False,
120
- encoding: str = 'utf-8',
121
- enum_field_as_literal: Optional[LiteralType] = None,
114
+ encoding: str = "utf-8",
115
+ enum_field_as_literal: LiteralType | None = None,
122
116
  set_default_enum_member: bool = False,
123
117
  use_subclass_enum: bool = False,
124
118
  strict_nullable: bool = False,
125
119
  use_generic_container_types: bool = False,
126
120
  enable_faux_immutability: bool = False,
127
- remote_text_cache: Optional[DefaultPutDict[str, str]] = None,
121
+ remote_text_cache: DefaultPutDict[str, str] | None = None,
128
122
  disable_appending_item_suffix: bool = False,
129
- strict_types: Optional[Sequence[StrictTypes]] = None,
130
- empty_enum_field_name: Optional[str] = None,
131
- custom_class_name_generator: Optional[Callable[[str], str]] = None,
132
- field_extra_keys: Optional[Set[str]] = None,
123
+ strict_types: Sequence[StrictTypes] | None = None,
124
+ empty_enum_field_name: str | None = None,
125
+ custom_class_name_generator: Callable[[str], str] | None = None,
126
+ field_extra_keys: set[str] | None = None,
133
127
  field_include_all_keys: bool = False,
134
- field_extra_keys_without_x_prefix: Optional[Set[str]] = None,
135
- wrap_string_literal: Optional[bool] = None,
128
+ field_extra_keys_without_x_prefix: set[str] | None = None,
129
+ wrap_string_literal: bool | None = None,
136
130
  use_title_as_name: bool = False,
137
131
  use_operation_id_as_name: bool = False,
138
132
  use_unique_items_as_set: bool = False,
139
- http_headers: Optional[Sequence[Tuple[str, str]]] = None,
133
+ http_headers: Sequence[tuple[str, str]] | None = None,
140
134
  http_ignore_tls: bool = False,
141
135
  use_annotated: bool = False,
142
136
  use_non_positive_negative_number_constrained_types: bool = False,
143
- original_field_name_delimiter: Optional[str] = None,
137
+ original_field_name_delimiter: str | None = None,
144
138
  use_double_quotes: bool = False,
145
139
  use_union_operator: bool = False,
146
140
  allow_responses_without_content: bool = False,
147
141
  collapse_root_models: bool = False,
148
- special_field_name_prefix: Optional[str] = None,
142
+ special_field_name_prefix: str | None = None,
149
143
  remove_special_field_name_prefix: bool = False,
150
144
  capitalise_enum_members: bool = False,
151
145
  keep_model_order: bool = False,
152
146
  use_one_literal_as_default: bool = False,
153
- known_third_party: Optional[List[str]] = None,
154
- custom_formatters: Optional[List[str]] = None,
155
- custom_formatters_kwargs: Optional[Dict[str, Any]] = None,
147
+ known_third_party: list[str] | None = None,
148
+ custom_formatters: list[str] | None = None,
149
+ custom_formatters_kwargs: dict[str, Any] | None = None,
156
150
  use_pendulum: bool = False,
157
- http_query_parameters: Optional[Sequence[Tuple[str, str]]] = None,
151
+ http_query_parameters: Sequence[tuple[str, str]] | None = None,
158
152
  treat_dots_as_module: bool = False,
159
153
  use_exact_imports: bool = False,
160
- default_field_extras: Optional[Dict[str, Any]] = None,
154
+ default_field_extras: dict[str, Any] | None = None,
161
155
  target_datetime_class: DatetimeClassType = DatetimeClassType.Datetime,
162
156
  keyword_only: bool = False,
163
157
  no_alias: bool = False,
@@ -241,7 +235,7 @@ class GraphQLParser(Parser):
241
235
  self.use_standard_collections = use_standard_collections
242
236
  self.use_union_operator = use_union_operator
243
237
 
244
- def _get_context_source_path_parts(self) -> Iterator[Tuple[Source, List[str]]]:
238
+ def _get_context_source_path_parts(self) -> Iterator[tuple[Source, list[str]]]:
245
239
  # TODO (denisart): Temporarily this method duplicates
246
240
  # the method `datamodel_code_generator.parser.jsonschema.JsonSchemaParser._get_context_source_path_parts`.
247
241
 
@@ -250,8 +244,7 @@ class GraphQLParser(Parser):
250
244
  ): # pragma: no cover
251
245
  self.current_source_path = Path()
252
246
  self.model_resolver.after_load_files = {
253
- self.base_path.joinpath(s.path).resolve().as_posix()
254
- for s in self.iter_source
247
+ self.base_path.joinpath(s.path).resolve().as_posix() for s in self.iter_source
255
248
  }
256
249
 
257
250
  for source in self.iter_source:
@@ -266,12 +259,12 @@ class GraphQLParser(Parser):
266
259
  ), self.model_resolver.current_root_context(path_parts):
267
260
  yield source, path_parts
268
261
 
269
- def _resolve_types(self, paths: List[str], schema: graphql.GraphQLSchema) -> None:
262
+ def _resolve_types(self, paths: list[str], schema: graphql.GraphQLSchema) -> None:
270
263
  for type_name, type_ in schema.type_map.items():
271
- if type_name.startswith('__'):
264
+ if type_name.startswith("__"):
272
265
  continue
273
266
 
274
- if type_name in ['Query', 'Mutation']:
267
+ if type_name in {"Query", "Mutation"}:
275
268
  continue
276
269
 
277
270
  resolved_type = graphql_resolver.kind(type_, None)
@@ -280,7 +273,7 @@ class GraphQLParser(Parser):
280
273
  self.all_graphql_objects[type_.name] = type_
281
274
  # TODO: need a special method for each graph type
282
275
  self.references[type_.name] = Reference(
283
- path=f'{str(*paths)}/{resolved_type.value}/{type_.name}',
276
+ path=f"{paths!s}/{resolved_type.value}/{type_.name}",
284
277
  name=type_.name,
285
278
  original_name=type_.name,
286
279
  )
@@ -289,7 +282,7 @@ class GraphQLParser(Parser):
289
282
 
290
283
  def _typename_field(self, name: str) -> DataModelFieldBase:
291
284
  return self.data_model_field_type(
292
- name='typename__',
285
+ name="typename__",
293
286
  data_type=DataType(
294
287
  literals=[name],
295
288
  use_union_operator=self.use_union_operator,
@@ -298,24 +291,23 @@ class GraphQLParser(Parser):
298
291
  default=name,
299
292
  use_annotated=self.use_annotated,
300
293
  required=False,
301
- alias='__typename',
294
+ alias="__typename",
302
295
  use_one_literal_as_default=True,
303
296
  has_default=True,
304
297
  )
305
298
 
306
- def _get_default(
299
+ def _get_default( # noqa: PLR6301
307
300
  self,
308
- field: Union[graphql.GraphQLField, graphql.GraphQLInputField],
301
+ field: graphql.GraphQLField | graphql.GraphQLInputField,
309
302
  final_data_type: DataType,
310
- required: bool,
303
+ required: bool, # noqa: FBT001
311
304
  ) -> Any:
312
305
  if isinstance(field, graphql.GraphQLInputField): # pragma: no cover
313
306
  if field.default_value == graphql.pyutils.Undefined: # pragma: no cover
314
307
  return None
315
308
  return field.default_value
316
- if required is False:
317
- if final_data_type.is_list:
318
- return None
309
+ if required is False and final_data_type.is_list:
310
+ return None
319
311
 
320
312
  return None
321
313
 
@@ -331,15 +323,11 @@ class GraphQLParser(Parser):
331
323
  )
332
324
 
333
325
  def parse_enum(self, enum_object: graphql.GraphQLEnumType) -> None:
334
- enum_fields: List[DataModelFieldBase] = []
335
- exclude_field_names: Set[str] = set()
326
+ enum_fields: list[DataModelFieldBase] = []
327
+ exclude_field_names: set[str] = set()
336
328
 
337
329
  for value_name, value in enum_object.values.items():
338
- default = (
339
- f"'{value_name.translate(escape_characters)}'"
340
- if isinstance(value_name, str)
341
- else value_name
342
- )
330
+ default = f"'{value_name.translate(escape_characters)}'" if isinstance(value_name, str) else value_name
343
331
 
344
332
  field_name = self.model_resolver.get_valid_field_name(
345
333
  value_name, excludes=exclude_field_names, model_type=ModelType.ENUM
@@ -373,8 +361,8 @@ class GraphQLParser(Parser):
373
361
  def parse_field(
374
362
  self,
375
363
  field_name: str,
376
- alias: Optional[str],
377
- field: Union[graphql.GraphQLField, graphql.GraphQLInputField],
364
+ alias: str | None,
365
+ field: graphql.GraphQLField | graphql.GraphQLInputField,
378
366
  ) -> DataModelFieldBase:
379
367
  final_data_type = DataType(
380
368
  is_optional=True,
@@ -399,23 +387,17 @@ class GraphQLParser(Parser):
399
387
  elif graphql.is_non_null_type(obj): # pragma: no cover
400
388
  data_type.is_optional = False
401
389
 
402
- obj = obj.of_type # pyright: ignore [reportAttributeAccessIssue]
390
+ obj = obj.of_type # pyright: ignore[reportAttributeAccessIssue]
403
391
 
404
- data_type.type = obj.name # pyright: ignore [reportAttributeAccessIssue]
392
+ data_type.type = obj.name # pyright: ignore[reportAttributeAccessIssue]
405
393
 
406
- required = (not self.force_optional_for_required_fields) and (
407
- not final_data_type.is_optional
408
- )
394
+ required = (not self.force_optional_for_required_fields) and (not final_data_type.is_optional)
409
395
 
410
396
  default = self._get_default(field, final_data_type, required)
411
- extras = (
412
- {}
413
- if self.default_field_extras is None
414
- else self.default_field_extras.copy()
415
- )
397
+ extras = {} if self.default_field_extras is None else self.default_field_extras.copy()
416
398
 
417
399
  if field.description is not None: # pragma: no cover
418
- extras['description'] = field.description
400
+ extras["description"] = field.description
419
401
 
420
402
  return self.data_model_field_type(
421
403
  name=field_name,
@@ -434,14 +416,10 @@ class GraphQLParser(Parser):
434
416
 
435
417
  def parse_object_like(
436
418
  self,
437
- obj: Union[
438
- graphql.GraphQLInterfaceType,
439
- graphql.GraphQLObjectType,
440
- graphql.GraphQLInputObjectType,
441
- ],
419
+ obj: graphql.GraphQLInterfaceType | graphql.GraphQLObjectType | graphql.GraphQLInputObjectType,
442
420
  ) -> None:
443
421
  fields = []
444
- exclude_field_names: Set[str] = set()
422
+ exclude_field_names: set[str] = set()
445
423
 
446
424
  for field_name, field in obj.fields.items():
447
425
  field_name_, alias = self.model_resolver.get_valid_field_name_and_alias(
@@ -455,8 +433,8 @@ class GraphQLParser(Parser):
455
433
  fields.append(self._typename_field(obj.name))
456
434
 
457
435
  base_classes = []
458
- if hasattr(obj, 'interfaces'): # pragma: no cover
459
- base_classes = [self.references[i.name] for i in obj.interfaces] # pyright: ignore [reportAttributeAccessIssue]
436
+ if hasattr(obj, "interfaces"): # pragma: no cover
437
+ base_classes = [self.references[i.name] for i in obj.interfaces] # pyright: ignore[reportAttributeAccessIssue]
460
438
 
461
439
  data_model_type = self.data_model_type(
462
440
  reference=self.references[obj.name],
@@ -471,26 +449,17 @@ class GraphQLParser(Parser):
471
449
  )
472
450
  self.results.append(data_model_type)
473
451
 
474
- def parse_interface(
475
- self, interface_graphql_object: graphql.GraphQLInterfaceType
476
- ) -> None:
452
+ def parse_interface(self, interface_graphql_object: graphql.GraphQLInterfaceType) -> None:
477
453
  self.parse_object_like(interface_graphql_object)
478
454
 
479
455
  def parse_object(self, graphql_object: graphql.GraphQLObjectType) -> None:
480
456
  self.parse_object_like(graphql_object)
481
457
 
482
- def parse_input_object(
483
- self, input_graphql_object: graphql.GraphQLInputObjectType
484
- ) -> None:
458
+ def parse_input_object(self, input_graphql_object: graphql.GraphQLInputObjectType) -> None:
485
459
  self.parse_object_like(input_graphql_object) # pragma: no cover
486
460
 
487
461
  def parse_union(self, union_object: graphql.GraphQLUnionType) -> None:
488
- fields = []
489
-
490
- for type_ in union_object.types:
491
- fields.append(
492
- self.data_model_field_type(name=type_.name, data_type=DataType())
493
- )
462
+ fields = [self.data_model_field_type(name=type_.name, data_type=DataType()) for type_ in union_object.types]
494
463
 
495
464
  data_model_type = self.data_model_union_type(
496
465
  reference=self.references[union_object.name],
@@ -505,7 +474,7 @@ class GraphQLParser(Parser):
505
474
 
506
475
  def parse_raw(self) -> None:
507
476
  self.all_graphql_objects = {}
508
- self.references: Dict[str, Reference] = {}
477
+ self.references: dict[str, Reference] = {}
509
478
 
510
479
  self.support_graphql_types = {
511
480
  graphql.type.introspection.TypeKind.SCALAR: [],
@@ -517,7 +486,7 @@ class GraphQLParser(Parser):
517
486
  }
518
487
 
519
488
  # may be as a parameter in the future (??)
520
- _mapper_from_graphql_type_to_parser_method = {
489
+ mapper_from_graphql_type_to_parser_method = {
521
490
  graphql.type.introspection.TypeKind.SCALAR: self.parse_scalar,
522
491
  graphql.type.introspection.TypeKind.ENUM: self.parse_enum,
523
492
  graphql.type.introspection.TypeKind.INTERFACE: self.parse_interface,
@@ -534,5 +503,5 @@ class GraphQLParser(Parser):
534
503
 
535
504
  for next_type in self.parse_order:
536
505
  for obj in self.support_graphql_types[next_type]:
537
- parser_ = _mapper_from_graphql_type_to_parser_method[next_type]
538
- parser_(obj) # type: ignore
506
+ parser_ = mapper_from_graphql_type_to_parser_method[next_type]
507
+ parser_(obj)