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,17 +1,8 @@
1
- from pathlib import Path
2
- from typing import (
3
- Any,
4
- ClassVar,
5
- DefaultDict,
6
- Dict,
7
- List,
8
- Optional,
9
- Sequence,
10
- Set,
11
- Tuple,
12
- )
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any, ClassVar, Optional
13
4
 
14
- from datamodel_code_generator import DatetimeClassType, PythonVersion
5
+ from datamodel_code_generator import DatetimeClassType, PythonVersion, PythonVersionMin
15
6
  from datamodel_code_generator.imports import (
16
7
  IMPORT_DATE,
17
8
  IMPORT_DATETIME,
@@ -22,44 +13,50 @@ from datamodel_code_generator.imports import (
22
13
  from datamodel_code_generator.model import DataModel, DataModelFieldBase
23
14
  from datamodel_code_generator.model.base import UNDEFINED
24
15
  from datamodel_code_generator.model.imports import IMPORT_DATACLASS, IMPORT_FIELD
25
- from datamodel_code_generator.model.pydantic.base_model import Constraints
26
16
  from datamodel_code_generator.model.types import DataTypeManager as _DataTypeManager
27
17
  from datamodel_code_generator.model.types import type_map_factory
28
- from datamodel_code_generator.reference import Reference
29
18
  from datamodel_code_generator.types import DataType, StrictTypes, Types, chain_as_tuple
30
19
 
20
+ if TYPE_CHECKING:
21
+ from collections import defaultdict
22
+ from collections.abc import Sequence
23
+ from pathlib import Path
24
+
25
+ from datamodel_code_generator.reference import Reference
26
+
27
+ from datamodel_code_generator.model.pydantic.base_model import Constraints # noqa: TC001
28
+
31
29
 
32
30
  def _has_field_assignment(field: DataModelFieldBase) -> bool:
33
31
  return bool(field.field) or not (
34
- field.required
35
- or (field.represented_default == 'None' and field.strip_default_none)
32
+ field.required or (field.represented_default == "None" and field.strip_default_none)
36
33
  )
37
34
 
38
35
 
39
36
  class DataClass(DataModel):
40
- TEMPLATE_FILE_PATH: ClassVar[str] = 'dataclass.jinja2'
41
- DEFAULT_IMPORTS: ClassVar[Tuple[Import, ...]] = (IMPORT_DATACLASS,)
37
+ TEMPLATE_FILE_PATH: ClassVar[str] = "dataclass.jinja2"
38
+ DEFAULT_IMPORTS: ClassVar[tuple[Import, ...]] = (IMPORT_DATACLASS,)
42
39
 
43
- def __init__(
40
+ def __init__( # noqa: PLR0913
44
41
  self,
45
42
  *,
46
43
  reference: Reference,
47
- fields: List[DataModelFieldBase],
48
- decorators: Optional[List[str]] = None,
49
- base_classes: Optional[List[Reference]] = None,
50
- custom_base_class: Optional[str] = None,
51
- custom_template_dir: Optional[Path] = None,
52
- extra_template_data: Optional[DefaultDict[str, Dict[str, Any]]] = None,
53
- methods: Optional[List[str]] = None,
54
- path: Optional[Path] = None,
55
- description: Optional[str] = None,
44
+ fields: list[DataModelFieldBase],
45
+ decorators: list[str] | None = None,
46
+ base_classes: list[Reference] | None = None,
47
+ custom_base_class: str | None = None,
48
+ custom_template_dir: Path | None = None,
49
+ extra_template_data: defaultdict[str, dict[str, Any]] | None = None,
50
+ methods: list[str] | None = None,
51
+ path: Path | None = None,
52
+ description: str | None = None,
56
53
  default: Any = UNDEFINED,
57
54
  nullable: bool = False,
58
55
  keyword_only: bool = False,
59
56
  ) -> None:
60
57
  super().__init__(
61
58
  reference=reference,
62
- fields=sorted(fields, key=_has_field_assignment, reverse=False),
59
+ fields=sorted(fields, key=_has_field_assignment),
63
60
  decorators=decorators,
64
61
  base_classes=base_classes,
65
62
  custom_base_class=custom_base_class,
@@ -75,21 +72,21 @@ class DataClass(DataModel):
75
72
 
76
73
 
77
74
  class DataModelField(DataModelFieldBase):
78
- _FIELD_KEYS: ClassVar[Set[str]] = {
79
- 'default_factory',
80
- 'init',
81
- 'repr',
82
- 'hash',
83
- 'compare',
84
- 'metadata',
85
- 'kw_only',
75
+ _FIELD_KEYS: ClassVar[set[str]] = {
76
+ "default_factory",
77
+ "init",
78
+ "repr",
79
+ "hash",
80
+ "compare",
81
+ "metadata",
82
+ "kw_only",
86
83
  }
87
- constraints: Optional[Constraints] = None
84
+ constraints: Optional[Constraints] = None # noqa: UP045
88
85
 
89
86
  @property
90
- def imports(self) -> Tuple[Import, ...]:
87
+ def imports(self) -> tuple[Import, ...]:
91
88
  field = self.field
92
- if field and field.startswith('field('):
89
+ if field and field.startswith("field("):
93
90
  return chain_as_tuple(super().imports, (IMPORT_FIELD,))
94
91
  return super().imports
95
92
 
@@ -99,60 +96,55 @@ class DataModelField(DataModelFieldBase):
99
96
  }
100
97
 
101
98
  @property
102
- def field(self) -> Optional[str]:
99
+ def field(self) -> str | None:
103
100
  """for backwards compatibility"""
104
101
  result = str(self)
105
- if result == '':
102
+ if not result:
106
103
  return None
107
-
108
104
  return result
109
105
 
110
106
  def __str__(self) -> str:
111
- data: Dict[str, Any] = {
112
- k: v for k, v in self.extras.items() if k in self._FIELD_KEYS
113
- }
107
+ data: dict[str, Any] = {k: v for k, v in self.extras.items() if k in self._FIELD_KEYS}
114
108
 
115
109
  if self.default != UNDEFINED and self.default is not None:
116
- data['default'] = self.default
110
+ data["default"] = self.default
117
111
 
118
112
  if self.required:
119
113
  data = {
120
114
  k: v
121
115
  for k, v in data.items()
122
116
  if k
123
- not in (
124
- 'default',
125
- 'default_factory',
126
- )
117
+ not in {
118
+ "default",
119
+ "default_factory",
120
+ }
127
121
  }
128
122
 
129
123
  if not data:
130
- return ''
124
+ return ""
131
125
 
132
- if len(data) == 1 and 'default' in data:
133
- default = data['default']
126
+ if len(data) == 1 and "default" in data:
127
+ default = data["default"]
134
128
 
135
129
  if isinstance(default, (list, dict)):
136
- return f'field(default_factory=lambda :{repr(default)})'
130
+ return f"field(default_factory=lambda :{default!r})"
137
131
  return repr(default)
138
- kwargs = [
139
- f'{k}={v if k == "default_factory" else repr(v)}' for k, v in data.items()
140
- ]
141
- return f'field({", ".join(kwargs)})'
132
+ kwargs = [f"{k}={v if k == 'default_factory' else repr(v)}" for k, v in data.items()]
133
+ return f"field({', '.join(kwargs)})"
142
134
 
143
135
 
144
136
  class DataTypeManager(_DataTypeManager):
145
- def __init__(
137
+ def __init__( # noqa: PLR0913, PLR0917
146
138
  self,
147
- python_version: PythonVersion = PythonVersion.PY_38,
148
- use_standard_collections: bool = False,
149
- use_generic_container_types: bool = False,
150
- strict_types: Optional[Sequence[StrictTypes]] = None,
151
- use_non_positive_negative_number_constrained_types: bool = False,
152
- use_union_operator: bool = False,
153
- use_pendulum: bool = False,
139
+ python_version: PythonVersion = PythonVersionMin,
140
+ use_standard_collections: bool = False, # noqa: FBT001, FBT002
141
+ use_generic_container_types: bool = False, # noqa: FBT001, FBT002
142
+ strict_types: Sequence[StrictTypes] | None = None,
143
+ use_non_positive_negative_number_constrained_types: bool = False, # noqa: FBT001, FBT002
144
+ use_union_operator: bool = False, # noqa: FBT001, FBT002
145
+ use_pendulum: bool = False, # noqa: FBT001, FBT002
154
146
  target_datetime_class: DatetimeClassType = DatetimeClassType.Datetime,
155
- ):
147
+ ) -> None:
156
148
  super().__init__(
157
149
  python_version,
158
150
  use_standard_collections,
@@ -175,7 +167,7 @@ class DataTypeManager(_DataTypeManager):
175
167
  else {}
176
168
  )
177
169
 
178
- self.type_map: Dict[Types, DataType] = {
170
+ self.type_map: dict[Types, DataType] = {
179
171
  **type_map_factory(self.data_type),
180
172
  **datetime_map,
181
173
  }
@@ -1,20 +1,24 @@
1
1
  from __future__ import annotations
2
2
 
3
- from pathlib import Path
4
- from typing import Any, ClassVar, DefaultDict, Dict, List, Optional, Tuple
3
+ from typing import TYPE_CHECKING, Any, ClassVar, Optional
5
4
 
6
5
  from datamodel_code_generator.imports import IMPORT_ANY, IMPORT_ENUM, Import
7
6
  from datamodel_code_generator.model import DataModel, DataModelFieldBase
8
7
  from datamodel_code_generator.model.base import UNDEFINED, BaseClassDataType
9
- from datamodel_code_generator.reference import Reference
10
8
  from datamodel_code_generator.types import DataType, Types
11
9
 
12
- _INT: str = 'int'
13
- _FLOAT: str = 'float'
14
- _BYTES: str = 'bytes'
15
- _STR: str = 'str'
10
+ if TYPE_CHECKING:
11
+ from collections import defaultdict
12
+ from pathlib import Path
16
13
 
17
- SUBCLASS_BASE_CLASSES: Dict[Types, str] = {
14
+ from datamodel_code_generator.reference import Reference
15
+
16
+ _INT: str = "int"
17
+ _FLOAT: str = "float"
18
+ _BYTES: str = "bytes"
19
+ _STR: str = "str"
20
+
21
+ SUBCLASS_BASE_CLASSES: dict[Types, str] = {
18
22
  Types.int32: _INT,
19
23
  Types.int64: _INT,
20
24
  Types.integer: _INT,
@@ -27,28 +31,28 @@ SUBCLASS_BASE_CLASSES: Dict[Types, str] = {
27
31
 
28
32
 
29
33
  class Enum(DataModel):
30
- TEMPLATE_FILE_PATH: ClassVar[str] = 'Enum.jinja2'
31
- BASE_CLASS: ClassVar[str] = 'enum.Enum'
32
- DEFAULT_IMPORTS: ClassVar[Tuple[Import, ...]] = (IMPORT_ENUM,)
34
+ TEMPLATE_FILE_PATH: ClassVar[str] = "Enum.jinja2"
35
+ BASE_CLASS: ClassVar[str] = "enum.Enum"
36
+ DEFAULT_IMPORTS: ClassVar[tuple[Import, ...]] = (IMPORT_ENUM,)
33
37
 
34
- def __init__(
38
+ def __init__( # noqa: PLR0913
35
39
  self,
36
40
  *,
37
41
  reference: Reference,
38
- fields: List[DataModelFieldBase],
39
- decorators: Optional[List[str]] = None,
40
- base_classes: Optional[List[Reference]] = None,
41
- custom_base_class: Optional[str] = None,
42
- custom_template_dir: Optional[Path] = None,
43
- extra_template_data: Optional[DefaultDict[str, Dict[str, Any]]] = None,
44
- methods: Optional[List[str]] = None,
45
- path: Optional[Path] = None,
46
- description: Optional[str] = None,
47
- type_: Optional[Types] = None,
42
+ fields: list[DataModelFieldBase],
43
+ decorators: list[str] | None = None,
44
+ base_classes: list[Reference] | None = None,
45
+ custom_base_class: str | None = None,
46
+ custom_template_dir: Path | None = None,
47
+ extra_template_data: defaultdict[str, dict[str, Any]] | None = None,
48
+ methods: list[str] | None = None,
49
+ path: Path | None = None,
50
+ description: str | None = None,
51
+ type_: Types | None = None,
48
52
  default: Any = UNDEFINED,
49
53
  nullable: bool = False,
50
54
  keyword_only: bool = False,
51
- ):
55
+ ) -> None:
52
56
  super().__init__(
53
57
  reference=reference,
54
58
  fields=fields,
@@ -68,7 +72,7 @@ class Enum(DataModel):
68
72
  if not base_classes and type_:
69
73
  base_class = SUBCLASS_BASE_CLASSES.get(type_)
70
74
  if base_class:
71
- self.base_classes: List[BaseClassDataType] = [
75
+ self.base_classes: list[BaseClassDataType] = [
72
76
  BaseClassDataType(type=base_class),
73
77
  *self.base_classes,
74
78
  ]
@@ -80,14 +84,14 @@ class Enum(DataModel):
80
84
  def get_member(self, field: DataModelFieldBase) -> Member:
81
85
  return Member(self, field)
82
86
 
83
- def find_member(self, value: Any) -> Optional[Member]:
87
+ def find_member(self, value: Any) -> Member | None:
84
88
  repr_value = repr(value)
85
89
  # Remove surrounding quotes from the string representation
86
- str_value = str(value).strip('\'"')
90
+ str_value = str(value).strip("'\"")
87
91
 
88
92
  for field in self.fields:
89
93
  # Remove surrounding quotes from field default value
90
- field_default = (field.default or '').strip('\'"')
94
+ field_default = (field.default or "").strip("'\"")
91
95
 
92
96
  # Compare values after removing quotes
93
97
  if field_default == str_value:
@@ -100,7 +104,7 @@ class Enum(DataModel):
100
104
  return None
101
105
 
102
106
  @property
103
- def imports(self) -> Tuple[Import, ...]:
107
+ def imports(self) -> tuple[Import, ...]:
104
108
  return tuple(i for i in super().imports if i != IMPORT_ANY)
105
109
 
106
110
 
@@ -108,7 +112,7 @@ class Member:
108
112
  def __init__(self, enum: Enum, field: DataModelFieldBase) -> None:
109
113
  self.enum: Enum = enum
110
114
  self.field: DataModelFieldBase = field
111
- self.alias: Optional[str] = None
115
+ self.alias: Optional[str] = None # noqa: UP045
112
116
 
113
117
  def __repr__(self) -> str:
114
- return f'{self.alias or self.enum.name}.{self.field.name}'
118
+ return f"{self.alias or self.enum.name}.{self.field.name}"
@@ -1,13 +1,15 @@
1
+ from __future__ import annotations
2
+
1
3
  from datamodel_code_generator.imports import Import
2
4
 
3
- IMPORT_DATACLASS = Import.from_full_path('dataclasses.dataclass')
4
- IMPORT_FIELD = Import.from_full_path('dataclasses.field')
5
- IMPORT_CLASSVAR = Import.from_full_path('typing.ClassVar')
6
- IMPORT_TYPED_DICT = Import.from_full_path('typing.TypedDict')
7
- IMPORT_TYPED_DICT_BACKPORT = Import.from_full_path('typing_extensions.TypedDict')
8
- IMPORT_NOT_REQUIRED = Import.from_full_path('typing.NotRequired')
9
- IMPORT_NOT_REQUIRED_BACKPORT = Import.from_full_path('typing_extensions.NotRequired')
10
- IMPORT_MSGSPEC_STRUCT = Import.from_full_path('msgspec.Struct')
11
- IMPORT_MSGSPEC_FIELD = Import.from_full_path('msgspec.field')
12
- IMPORT_MSGSPEC_META = Import.from_full_path('msgspec.Meta')
13
- IMPORT_MSGSPEC_CONVERT = Import.from_full_path('msgspec.convert')
5
+ IMPORT_DATACLASS = Import.from_full_path("dataclasses.dataclass")
6
+ IMPORT_FIELD = Import.from_full_path("dataclasses.field")
7
+ IMPORT_CLASSVAR = Import.from_full_path("typing.ClassVar")
8
+ IMPORT_TYPED_DICT = Import.from_full_path("typing.TypedDict")
9
+ IMPORT_TYPED_DICT_BACKPORT = Import.from_full_path("typing_extensions.TypedDict")
10
+ IMPORT_NOT_REQUIRED = Import.from_full_path("typing.NotRequired")
11
+ IMPORT_NOT_REQUIRED_BACKPORT = Import.from_full_path("typing_extensions.NotRequired")
12
+ IMPORT_MSGSPEC_STRUCT = Import.from_full_path("msgspec.Struct")
13
+ IMPORT_MSGSPEC_FIELD = Import.from_full_path("msgspec.field")
14
+ IMPORT_MSGSPEC_META = Import.from_full_path("msgspec.Meta")
15
+ IMPORT_MSGSPEC_CONVERT = Import.from_full_path("msgspec.convert")