datamodel-code-generator 0.27.3__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.
- datamodel_code_generator/__init__.py +10 -7
- datamodel_code_generator/__main__.py +18 -39
- datamodel_code_generator/arguments.py +2 -2
- datamodel_code_generator/format.py +9 -39
- datamodel_code_generator/http.py +4 -1
- datamodel_code_generator/imports.py +5 -4
- datamodel_code_generator/model/__init__.py +4 -2
- datamodel_code_generator/model/base.py +12 -23
- datamodel_code_generator/model/dataclass.py +7 -14
- datamodel_code_generator/model/enum.py +2 -2
- datamodel_code_generator/model/msgspec.py +9 -17
- datamodel_code_generator/model/pydantic/__init__.py +4 -1
- datamodel_code_generator/model/pydantic/base_model.py +4 -4
- datamodel_code_generator/model/pydantic/dataclass.py +2 -2
- datamodel_code_generator/model/pydantic/types.py +6 -3
- datamodel_code_generator/model/pydantic_v2/__init__.py +5 -2
- datamodel_code_generator/model/pydantic_v2/base_model.py +4 -12
- datamodel_code_generator/model/pydantic_v2/types.py +4 -1
- datamodel_code_generator/model/scalar.py +2 -2
- datamodel_code_generator/model/typed_dict.py +5 -16
- datamodel_code_generator/model/types.py +6 -3
- datamodel_code_generator/model/union.py +2 -2
- datamodel_code_generator/parser/__init__.py +6 -3
- datamodel_code_generator/parser/base.py +11 -27
- datamodel_code_generator/parser/graphql.py +7 -8
- datamodel_code_generator/parser/jsonschema.py +33 -44
- datamodel_code_generator/parser/openapi.py +20 -31
- datamodel_code_generator/reference.py +11 -27
- datamodel_code_generator/types.py +14 -45
- datamodel_code_generator/util.py +1 -10
- {datamodel_code_generator-0.27.3.dist-info → datamodel_code_generator-0.28.0.dist-info}/METADATA +4 -5
- datamodel_code_generator-0.28.0.dist-info/RECORD +59 -0
- datamodel_code_generator-0.27.3.dist-info/RECORD +0 -59
- {datamodel_code_generator-0.27.3.dist-info → datamodel_code_generator-0.28.0.dist-info}/WHEEL +0 -0
- {datamodel_code_generator-0.27.3.dist-info → datamodel_code_generator-0.28.0.dist-info}/entry_points.txt +0 -0
- {datamodel_code_generator-0.27.3.dist-info → datamodel_code_generator-0.28.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import contextlib
|
|
4
4
|
import os
|
|
5
5
|
import sys
|
|
6
|
+
from collections.abc import Iterator, Mapping, Sequence
|
|
6
7
|
from datetime import datetime, timezone
|
|
7
8
|
from enum import Enum
|
|
8
9
|
from pathlib import Path
|
|
@@ -11,10 +12,7 @@ from typing import (
|
|
|
11
12
|
TYPE_CHECKING,
|
|
12
13
|
Any,
|
|
13
14
|
Callable,
|
|
14
|
-
|
|
15
|
-
Iterator,
|
|
16
|
-
Mapping,
|
|
17
|
-
Sequence,
|
|
15
|
+
Final,
|
|
18
16
|
TextIO,
|
|
19
17
|
TypeVar,
|
|
20
18
|
cast,
|
|
@@ -24,10 +22,13 @@ from urllib.parse import ParseResult
|
|
|
24
22
|
import yaml
|
|
25
23
|
|
|
26
24
|
import datamodel_code_generator.pydantic_patch # noqa: F401
|
|
27
|
-
from datamodel_code_generator.format import DatetimeClassType, PythonVersion
|
|
25
|
+
from datamodel_code_generator.format import DatetimeClassType, PythonVersion, PythonVersionMin
|
|
28
26
|
from datamodel_code_generator.parser import DefaultPutDict, LiteralType
|
|
29
27
|
from datamodel_code_generator.util import SafeLoader
|
|
30
28
|
|
|
29
|
+
MIN_VERSION: Final[int] = 9
|
|
30
|
+
MAX_VERSION: Final[int] = 13
|
|
31
|
+
|
|
31
32
|
T = TypeVar("T")
|
|
32
33
|
|
|
33
34
|
try:
|
|
@@ -212,7 +213,7 @@ def generate( # noqa: PLR0912, PLR0913, PLR0914, PLR0915
|
|
|
212
213
|
input_file_type: InputFileType = InputFileType.Auto,
|
|
213
214
|
output: Path | None = None,
|
|
214
215
|
output_model_type: DataModelType = DataModelType.PydanticBaseModel,
|
|
215
|
-
target_python_version: PythonVersion =
|
|
216
|
+
target_python_version: PythonVersion = PythonVersionMin,
|
|
216
217
|
base_class: str = "",
|
|
217
218
|
additional_imports: list[str] | None = None,
|
|
218
219
|
custom_template_dir: Path | None = None,
|
|
@@ -367,7 +368,7 @@ def generate( # noqa: PLR0912, PLR0913, PLR0914, PLR0915
|
|
|
367
368
|
obj = (
|
|
368
369
|
ast.literal_eval(input_.read_text(encoding=encoding))
|
|
369
370
|
if isinstance(input_, Path)
|
|
370
|
-
else cast("
|
|
371
|
+
else cast("dict[Any, Any]", input_)
|
|
371
372
|
)
|
|
372
373
|
else: # pragma: no cover
|
|
373
374
|
msg = f"Unsupported input file type: {input_file_type}"
|
|
@@ -554,6 +555,8 @@ inferred_message = (
|
|
|
554
555
|
)
|
|
555
556
|
|
|
556
557
|
__all__ = [
|
|
558
|
+
"MAX_VERSION",
|
|
559
|
+
"MIN_VERSION",
|
|
557
560
|
"DefaultPutDict",
|
|
558
561
|
"Error",
|
|
559
562
|
"InputFileType",
|
|
@@ -9,20 +9,11 @@ import signal
|
|
|
9
9
|
import sys
|
|
10
10
|
import warnings
|
|
11
11
|
from collections import defaultdict
|
|
12
|
+
from collections.abc import Sequence # noqa: TC003 # pydantic needs it
|
|
12
13
|
from enum import IntEnum
|
|
13
14
|
from io import TextIOBase
|
|
14
15
|
from pathlib import Path
|
|
15
|
-
from typing import
|
|
16
|
-
TYPE_CHECKING,
|
|
17
|
-
Any,
|
|
18
|
-
List,
|
|
19
|
-
Optional,
|
|
20
|
-
Sequence,
|
|
21
|
-
Set,
|
|
22
|
-
Tuple,
|
|
23
|
-
Union,
|
|
24
|
-
cast,
|
|
25
|
-
)
|
|
16
|
+
from typing import TYPE_CHECKING, Any, Optional, Union, cast
|
|
26
17
|
from urllib.parse import ParseResult, urlparse
|
|
27
18
|
|
|
28
19
|
import argcomplete
|
|
@@ -47,6 +38,7 @@ from datamodel_code_generator.arguments import DEFAULT_ENCODING, arg_parser, nam
|
|
|
47
38
|
from datamodel_code_generator.format import (
|
|
48
39
|
DatetimeClassType,
|
|
49
40
|
PythonVersion,
|
|
41
|
+
PythonVersionMin,
|
|
50
42
|
is_supported_in_black,
|
|
51
43
|
)
|
|
52
44
|
from datamodel_code_generator.model.pydantic_v2 import UnionMode # noqa: TC001 # needed for pydantic
|
|
@@ -142,34 +134,21 @@ class Config(BaseModel):
|
|
|
142
134
|
msg = f"This protocol doesn't support only http/https. --input={value}"
|
|
143
135
|
raise Error(msg) # pragma: no cover
|
|
144
136
|
|
|
145
|
-
@model_validator(
|
|
146
|
-
def validate_use_generic_container_types(cls, values: dict[str, Any]) -> dict[str, Any]: # noqa: N805
|
|
147
|
-
if values.get("use_generic_container_types"):
|
|
148
|
-
target_python_version: PythonVersion = values["target_python_version"]
|
|
149
|
-
if target_python_version == target_python_version.PY_36:
|
|
150
|
-
msg = (
|
|
151
|
-
f"`--use-generic-container-types` can not be used with `--target-python-version` "
|
|
152
|
-
f"{target_python_version.PY_36.value}.\n"
|
|
153
|
-
" The version will be not supported in a future version"
|
|
154
|
-
)
|
|
155
|
-
raise Error(msg)
|
|
156
|
-
return values
|
|
157
|
-
|
|
158
|
-
@model_validator(mode="after")
|
|
137
|
+
@model_validator()
|
|
159
138
|
def validate_original_field_name_delimiter(cls, values: dict[str, Any]) -> dict[str, Any]: # noqa: N805
|
|
160
139
|
if values.get("original_field_name_delimiter") is not None and not values.get("snake_case_field"):
|
|
161
140
|
msg = "`--original-field-name-delimiter` can not be used without `--snake-case-field`."
|
|
162
141
|
raise Error(msg)
|
|
163
142
|
return values
|
|
164
143
|
|
|
165
|
-
@model_validator(
|
|
144
|
+
@model_validator()
|
|
166
145
|
def validate_custom_file_header(cls, values: dict[str, Any]) -> dict[str, Any]: # noqa: N805
|
|
167
146
|
if values.get("custom_file_header") and values.get("custom_file_header_path"):
|
|
168
147
|
msg = "`--custom_file_header_path` can not be used with `--custom_file_header`."
|
|
169
148
|
raise Error(msg) # pragma: no cover
|
|
170
149
|
return values
|
|
171
150
|
|
|
172
|
-
@model_validator(
|
|
151
|
+
@model_validator()
|
|
173
152
|
def validate_keyword_only(cls, values: dict[str, Any]) -> dict[str, Any]: # noqa: N805
|
|
174
153
|
output_model_type: DataModelType = values.get("output_model_type") # pyright: ignore[reportAssignmentType]
|
|
175
154
|
python_target: PythonVersion = values.get("target_python_version") # pyright: ignore[reportAssignmentType]
|
|
@@ -182,7 +161,7 @@ class Config(BaseModel):
|
|
|
182
161
|
raise Error(msg)
|
|
183
162
|
return values
|
|
184
163
|
|
|
185
|
-
@model_validator(
|
|
164
|
+
@model_validator()
|
|
186
165
|
def validate_output_datetime_class(cls, values: dict[str, Any]) -> dict[str, Any]: # noqa: N805
|
|
187
166
|
datetime_class_type: DatetimeClassType | None = values.get("output_datetime_class")
|
|
188
167
|
if (
|
|
@@ -246,7 +225,7 @@ class Config(BaseModel):
|
|
|
246
225
|
|
|
247
226
|
if PYDANTIC_V2:
|
|
248
227
|
|
|
249
|
-
@model_validator(
|
|
228
|
+
@model_validator() # pyright: ignore[reportArgumentType]
|
|
250
229
|
def validate_root(self: Self) -> Self:
|
|
251
230
|
if self.use_annotated:
|
|
252
231
|
self.field_constraints = True
|
|
@@ -254,7 +233,7 @@ class Config(BaseModel):
|
|
|
254
233
|
|
|
255
234
|
else:
|
|
256
235
|
|
|
257
|
-
@model_validator(
|
|
236
|
+
@model_validator()
|
|
258
237
|
def validate_root(cls, values: Any) -> Any: # noqa: N805
|
|
259
238
|
if values.get("use_annotated"):
|
|
260
239
|
values["field_constraints"] = True
|
|
@@ -266,9 +245,9 @@ class Config(BaseModel):
|
|
|
266
245
|
output: Optional[Path] = None # noqa: UP045
|
|
267
246
|
debug: bool = False
|
|
268
247
|
disable_warnings: bool = False
|
|
269
|
-
target_python_version: PythonVersion =
|
|
248
|
+
target_python_version: PythonVersion = PythonVersionMin
|
|
270
249
|
base_class: str = ""
|
|
271
|
-
additional_imports: Optional[
|
|
250
|
+
additional_imports: Optional[list[str]] = None # noqa: UP045
|
|
272
251
|
custom_template_dir: Optional[Path] = None # noqa: UP045
|
|
273
252
|
extra_template_data: Optional[TextIOBase] = None # noqa: UP045
|
|
274
253
|
validation: bool = False
|
|
@@ -299,17 +278,17 @@ class Config(BaseModel):
|
|
|
299
278
|
enable_faux_immutability: bool = False
|
|
300
279
|
url: Optional[ParseResult] = None # noqa: UP045
|
|
301
280
|
disable_appending_item_suffix: bool = False
|
|
302
|
-
strict_types:
|
|
281
|
+
strict_types: list[StrictTypes] = []
|
|
303
282
|
empty_enum_field_name: Optional[str] = None # noqa: UP045
|
|
304
|
-
field_extra_keys: Optional[
|
|
283
|
+
field_extra_keys: Optional[set[str]] = None # noqa: UP045
|
|
305
284
|
field_include_all_keys: bool = False
|
|
306
|
-
field_extra_keys_without_x_prefix: Optional[
|
|
307
|
-
openapi_scopes: Optional[
|
|
285
|
+
field_extra_keys_without_x_prefix: Optional[set[str]] = None # noqa: UP045
|
|
286
|
+
openapi_scopes: Optional[list[OpenAPIScope]] = [OpenAPIScope.Schemas] # noqa: UP045
|
|
308
287
|
wrap_string_literal: Optional[bool] = None # noqa: UP045
|
|
309
288
|
use_title_as_name: bool = False
|
|
310
289
|
use_operation_id_as_name: bool = False
|
|
311
290
|
use_unique_items_as_set: bool = False
|
|
312
|
-
http_headers: Optional[Sequence[
|
|
291
|
+
http_headers: Optional[Sequence[tuple[str, str]]] = None # noqa: UP045
|
|
313
292
|
http_ignore_tls: bool = False
|
|
314
293
|
use_annotated: bool = False
|
|
315
294
|
use_non_positive_negative_number_constrained_types: bool = False
|
|
@@ -322,10 +301,10 @@ class Config(BaseModel):
|
|
|
322
301
|
keep_model_order: bool = False
|
|
323
302
|
custom_file_header: Optional[str] = None # noqa: UP045
|
|
324
303
|
custom_file_header_path: Optional[Path] = None # noqa: UP045
|
|
325
|
-
custom_formatters: Optional[
|
|
304
|
+
custom_formatters: Optional[list[str]] = None # noqa: UP045
|
|
326
305
|
custom_formatters_kwargs: Optional[TextIOBase] = None # noqa: UP045
|
|
327
306
|
use_pendulum: bool = False
|
|
328
|
-
http_query_parameters: Optional[Sequence[
|
|
307
|
+
http_query_parameters: Optional[Sequence[tuple[str, str]]] = None # noqa: UP045
|
|
329
308
|
treat_dot_as_module: bool = False
|
|
330
309
|
use_exact_imports: bool = False
|
|
331
310
|
union_mode: Optional[UnionMode] = None # noqa: UP045
|
|
@@ -13,7 +13,7 @@ from datamodel_code_generator.types import StrictTypes
|
|
|
13
13
|
|
|
14
14
|
if TYPE_CHECKING:
|
|
15
15
|
from argparse import Action
|
|
16
|
-
from
|
|
16
|
+
from collections.abc import Iterable
|
|
17
17
|
|
|
18
18
|
DEFAULT_ENCODING = locale.getpreferredencoding()
|
|
19
19
|
|
|
@@ -161,7 +161,7 @@ model_options.add_argument(
|
|
|
161
161
|
)
|
|
162
162
|
model_options.add_argument(
|
|
163
163
|
"--target-python-version",
|
|
164
|
-
help="target python version
|
|
164
|
+
help="target python version",
|
|
165
165
|
choices=[v.value for v in PythonVersion],
|
|
166
166
|
)
|
|
167
167
|
model_options.add_argument(
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from enum import Enum
|
|
4
|
+
from functools import cached_property
|
|
4
5
|
from importlib import import_module
|
|
5
6
|
from pathlib import Path
|
|
6
|
-
from typing import TYPE_CHECKING, Any
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
7
8
|
from warnings import warn
|
|
8
9
|
|
|
9
10
|
import black
|
|
10
11
|
import isort
|
|
11
12
|
|
|
12
|
-
from datamodel_code_generator.util import
|
|
13
|
+
from datamodel_code_generator.util import load_toml
|
|
13
14
|
|
|
14
15
|
try:
|
|
15
16
|
import black.mode
|
|
@@ -24,58 +25,24 @@ class DatetimeClassType(Enum):
|
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class PythonVersion(Enum):
|
|
27
|
-
PY_36 = "3.6"
|
|
28
|
-
PY_37 = "3.7"
|
|
29
|
-
PY_38 = "3.8"
|
|
30
28
|
PY_39 = "3.9"
|
|
31
29
|
PY_310 = "3.10"
|
|
32
30
|
PY_311 = "3.11"
|
|
33
31
|
PY_312 = "3.12"
|
|
34
32
|
PY_313 = "3.13"
|
|
35
33
|
|
|
36
|
-
@cached_property
|
|
37
|
-
def _is_py_38_or_later(self) -> bool: # pragma: no cover
|
|
38
|
-
return self.value not in {self.PY_36.value, self.PY_37.value}
|
|
39
|
-
|
|
40
|
-
@cached_property
|
|
41
|
-
def _is_py_39_or_later(self) -> bool: # pragma: no cover
|
|
42
|
-
return self.value not in {self.PY_36.value, self.PY_37.value, self.PY_38.value}
|
|
43
|
-
|
|
44
34
|
@cached_property
|
|
45
35
|
def _is_py_310_or_later(self) -> bool: # pragma: no cover
|
|
46
|
-
return self.value
|
|
47
|
-
self.PY_36.value,
|
|
48
|
-
self.PY_37.value,
|
|
49
|
-
self.PY_38.value,
|
|
50
|
-
self.PY_39.value,
|
|
51
|
-
}
|
|
36
|
+
return self.value != self.PY_39.value
|
|
52
37
|
|
|
53
38
|
@cached_property
|
|
54
39
|
def _is_py_311_or_later(self) -> bool: # pragma: no cover
|
|
55
|
-
return self.value not in {
|
|
56
|
-
self.PY_36.value,
|
|
57
|
-
self.PY_37.value,
|
|
58
|
-
self.PY_38.value,
|
|
59
|
-
self.PY_39.value,
|
|
60
|
-
self.PY_310.value,
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
@property
|
|
64
|
-
def has_literal_type(self) -> bool:
|
|
65
|
-
return self._is_py_38_or_later
|
|
40
|
+
return self.value not in {self.PY_39.value, self.PY_310.value}
|
|
66
41
|
|
|
67
42
|
@property
|
|
68
43
|
def has_union_operator(self) -> bool: # pragma: no cover
|
|
69
44
|
return self._is_py_310_or_later
|
|
70
45
|
|
|
71
|
-
@property
|
|
72
|
-
def has_annotated_type(self) -> bool:
|
|
73
|
-
return self._is_py_39_or_later
|
|
74
|
-
|
|
75
|
-
@property
|
|
76
|
-
def has_typed_dict(self) -> bool:
|
|
77
|
-
return self._is_py_38_or_later
|
|
78
|
-
|
|
79
46
|
@property
|
|
80
47
|
def has_typed_dict_non_required(self) -> bool:
|
|
81
48
|
return self._is_py_311_or_later
|
|
@@ -85,7 +52,10 @@ class PythonVersion(Enum):
|
|
|
85
52
|
return self._is_py_310_or_later
|
|
86
53
|
|
|
87
54
|
|
|
55
|
+
PythonVersionMin = PythonVersion.PY_39
|
|
56
|
+
|
|
88
57
|
if TYPE_CHECKING:
|
|
58
|
+
from collections.abc import Sequence
|
|
89
59
|
|
|
90
60
|
class _TargetVersion(Enum): ...
|
|
91
61
|
|
|
@@ -104,7 +74,7 @@ def is_supported_in_black(python_version: PythonVersion) -> bool: # pragma: no
|
|
|
104
74
|
|
|
105
75
|
def black_find_project_root(sources: Sequence[Path]) -> Path:
|
|
106
76
|
if TYPE_CHECKING:
|
|
107
|
-
from
|
|
77
|
+
from collections.abc import Iterable # noqa: PLC0415
|
|
108
78
|
|
|
109
79
|
def _find_project_root(
|
|
110
80
|
srcs: Sequence[str] | Iterable[str],
|
datamodel_code_generator/http.py
CHANGED
|
@@ -3,10 +3,13 @@ from __future__ import annotations
|
|
|
3
3
|
from collections import defaultdict
|
|
4
4
|
from functools import lru_cache
|
|
5
5
|
from itertools import starmap
|
|
6
|
-
from typing import
|
|
6
|
+
from typing import TYPE_CHECKING, Optional
|
|
7
7
|
|
|
8
8
|
from datamodel_code_generator.util import BaseModel
|
|
9
9
|
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from collections.abc import Iterable
|
|
12
|
+
|
|
10
13
|
|
|
11
14
|
class Import(BaseModel):
|
|
12
15
|
from_: Optional[str] = None # noqa: UP045
|
|
@@ -21,7 +24,7 @@ class Import(BaseModel):
|
|
|
21
24
|
return Import(from_=".".join(split_class_path[:-1]) or None, import_=split_class_path[-1])
|
|
22
25
|
|
|
23
26
|
|
|
24
|
-
class Imports(
|
|
27
|
+
class Imports(defaultdict[Optional[str], set[str]]):
|
|
25
28
|
def __str__(self) -> str:
|
|
26
29
|
return self.dump()
|
|
27
30
|
|
|
@@ -89,7 +92,6 @@ class Imports(DefaultDict[Optional[str], Set[str]]):
|
|
|
89
92
|
|
|
90
93
|
|
|
91
94
|
IMPORT_ANNOTATED = Import.from_full_path("typing.Annotated")
|
|
92
|
-
IMPORT_ANNOTATED_BACKPORT = Import.from_full_path("typing_extensions.Annotated")
|
|
93
95
|
IMPORT_ANY = Import.from_full_path("typing.Any")
|
|
94
96
|
IMPORT_LIST = Import.from_full_path("typing.List")
|
|
95
97
|
IMPORT_SET = Import.from_full_path("typing.Set")
|
|
@@ -97,7 +99,6 @@ IMPORT_UNION = Import.from_full_path("typing.Union")
|
|
|
97
99
|
IMPORT_OPTIONAL = Import.from_full_path("typing.Optional")
|
|
98
100
|
IMPORT_LITERAL = Import.from_full_path("typing.Literal")
|
|
99
101
|
IMPORT_TYPE_ALIAS = Import.from_full_path("typing.TypeAlias")
|
|
100
|
-
IMPORT_LITERAL_BACKPORT = Import.from_full_path("typing_extensions.Literal")
|
|
101
102
|
IMPORT_SEQUENCE = Import.from_full_path("typing.Sequence")
|
|
102
103
|
IMPORT_FROZEN_SET = Import.from_full_path("typing.FrozenSet")
|
|
103
104
|
IMPORT_MAPPING = Import.from_full_path("typing.Mapping")
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import sys
|
|
4
|
-
from typing import TYPE_CHECKING, Callable,
|
|
4
|
+
from typing import TYPE_CHECKING, Callable, NamedTuple
|
|
5
5
|
|
|
6
6
|
from datamodel_code_generator import DatetimeClassType, PythonVersion
|
|
7
7
|
|
|
8
8
|
from .base import ConstraintsBase, DataModel, DataModelFieldBase
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
|
+
from collections.abc import Iterable
|
|
12
|
+
|
|
11
13
|
from datamodel_code_generator import DataModelType
|
|
12
14
|
from datamodel_code_generator.types import DataTypeManager as DataTypeManagerABC
|
|
13
15
|
|
|
@@ -62,7 +64,7 @@ def get_data_model_types(
|
|
|
62
64
|
)
|
|
63
65
|
if data_model_type == DataModelType.TypingTypedDict:
|
|
64
66
|
return DataModelSet(
|
|
65
|
-
data_model=
|
|
67
|
+
data_model=typed_dict.TypedDict,
|
|
66
68
|
root_model=rootmodel.RootModel,
|
|
67
69
|
field_model=(
|
|
68
70
|
typed_dict.DataModelField
|
|
@@ -3,19 +3,9 @@ from __future__ import annotations
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
4
|
from collections import defaultdict
|
|
5
5
|
from copy import deepcopy
|
|
6
|
-
from functools import lru_cache
|
|
6
|
+
from functools import cached_property, lru_cache
|
|
7
7
|
from pathlib import Path
|
|
8
|
-
from typing import
|
|
9
|
-
TYPE_CHECKING,
|
|
10
|
-
Any,
|
|
11
|
-
ClassVar,
|
|
12
|
-
Dict,
|
|
13
|
-
Iterator,
|
|
14
|
-
Optional,
|
|
15
|
-
Set,
|
|
16
|
-
Tuple,
|
|
17
|
-
TypeVar,
|
|
18
|
-
)
|
|
8
|
+
from typing import TYPE_CHECKING, Any, ClassVar, Optional, TypeVar
|
|
19
9
|
from warnings import warn
|
|
20
10
|
|
|
21
11
|
from jinja2 import Environment, FileSystemLoader, Template
|
|
@@ -23,7 +13,6 @@ from pydantic import Field
|
|
|
23
13
|
|
|
24
14
|
from datamodel_code_generator.imports import (
|
|
25
15
|
IMPORT_ANNOTATED,
|
|
26
|
-
IMPORT_ANNOTATED_BACKPORT,
|
|
27
16
|
IMPORT_OPTIONAL,
|
|
28
17
|
IMPORT_UNION,
|
|
29
18
|
Import,
|
|
@@ -38,7 +27,10 @@ from datamodel_code_generator.types import (
|
|
|
38
27
|
chain_as_tuple,
|
|
39
28
|
get_optional_type,
|
|
40
29
|
)
|
|
41
|
-
from datamodel_code_generator.util import PYDANTIC_V2, ConfigDict
|
|
30
|
+
from datamodel_code_generator.util import PYDANTIC_V2, ConfigDict
|
|
31
|
+
|
|
32
|
+
if TYPE_CHECKING:
|
|
33
|
+
from collections.abc import Iterator
|
|
42
34
|
|
|
43
35
|
TEMPLATE_DIR: Path = Path(__file__).parents[0] / "template"
|
|
44
36
|
|
|
@@ -49,7 +41,7 @@ ConstraintsBaseT = TypeVar("ConstraintsBaseT", bound="ConstraintsBase")
|
|
|
49
41
|
|
|
50
42
|
class ConstraintsBase(_BaseModel):
|
|
51
43
|
unique_items: Optional[bool] = Field(None, alias="uniqueItems") # noqa: UP045
|
|
52
|
-
_exclude_fields: ClassVar[
|
|
44
|
+
_exclude_fields: ClassVar[set[str]] = {"has_constraints"}
|
|
53
45
|
if PYDANTIC_V2:
|
|
54
46
|
model_config = ConfigDict( # pyright: ignore[reportAssignmentType]
|
|
55
47
|
arbitrary_types_allowed=True, ignored_types=(cached_property,)
|
|
@@ -98,7 +90,7 @@ class DataModelFieldBase(_BaseModel):
|
|
|
98
90
|
strip_default_none: bool = False
|
|
99
91
|
nullable: Optional[bool] = None # noqa: UP045
|
|
100
92
|
parent: Optional[Any] = None # noqa: UP045
|
|
101
|
-
extras:
|
|
93
|
+
extras: dict[str, Any] = {} # noqa: RUF012
|
|
102
94
|
use_annotated: bool = False
|
|
103
95
|
has_default: bool = False
|
|
104
96
|
use_field_description: bool = False
|
|
@@ -106,8 +98,8 @@ class DataModelFieldBase(_BaseModel):
|
|
|
106
98
|
original_name: Optional[str] = None # noqa: UP045
|
|
107
99
|
use_default_kwarg: bool = False
|
|
108
100
|
use_one_literal_as_default: bool = False
|
|
109
|
-
_exclude_fields: ClassVar[
|
|
110
|
-
_pass_fields: ClassVar[
|
|
101
|
+
_exclude_fields: ClassVar[set[str]] = {"parent"}
|
|
102
|
+
_pass_fields: ClassVar[set[str]] = {"parent", "data_type"}
|
|
111
103
|
can_have_extra_keys: ClassVar[bool] = True
|
|
112
104
|
type_has_null: Optional[bool] = None # noqa: UP045
|
|
113
105
|
|
|
@@ -163,10 +155,7 @@ class DataModelFieldBase(_BaseModel):
|
|
|
163
155
|
elif self.nullable and not self.data_type.use_union_operator: # pragma: no cover
|
|
164
156
|
imports.append((IMPORT_OPTIONAL,))
|
|
165
157
|
if self.use_annotated and self.annotated:
|
|
166
|
-
|
|
167
|
-
IMPORT_ANNOTATED if self.data_type.python_version.has_annotated_type else IMPORT_ANNOTATED_BACKPORT
|
|
168
|
-
)
|
|
169
|
-
imports.append((import_annotated,))
|
|
158
|
+
imports.append((IMPORT_ANNOTATED,))
|
|
170
159
|
return chain_as_tuple(*imports)
|
|
171
160
|
|
|
172
161
|
@property
|
|
@@ -258,7 +247,7 @@ UNDEFINED: Any = object()
|
|
|
258
247
|
class DataModel(TemplateBase, Nullable, ABC):
|
|
259
248
|
TEMPLATE_FILE_PATH: ClassVar[str] = ""
|
|
260
249
|
BASE_CLASS: ClassVar[str] = ""
|
|
261
|
-
DEFAULT_IMPORTS: ClassVar[
|
|
250
|
+
DEFAULT_IMPORTS: ClassVar[tuple[Import, ...]] = ()
|
|
262
251
|
|
|
263
252
|
def __init__( # noqa: PLR0913
|
|
264
253
|
self,
|
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import
|
|
4
|
-
TYPE_CHECKING,
|
|
5
|
-
Any,
|
|
6
|
-
ClassVar,
|
|
7
|
-
Optional,
|
|
8
|
-
Sequence,
|
|
9
|
-
Set,
|
|
10
|
-
Tuple,
|
|
11
|
-
)
|
|
3
|
+
from typing import TYPE_CHECKING, Any, ClassVar, Optional
|
|
12
4
|
|
|
13
|
-
from datamodel_code_generator import DatetimeClassType, PythonVersion
|
|
5
|
+
from datamodel_code_generator import DatetimeClassType, PythonVersion, PythonVersionMin
|
|
14
6
|
from datamodel_code_generator.imports import (
|
|
15
7
|
IMPORT_DATE,
|
|
16
8
|
IMPORT_DATETIME,
|
|
@@ -27,6 +19,7 @@ from datamodel_code_generator.types import DataType, StrictTypes, Types, chain_a
|
|
|
27
19
|
|
|
28
20
|
if TYPE_CHECKING:
|
|
29
21
|
from collections import defaultdict
|
|
22
|
+
from collections.abc import Sequence
|
|
30
23
|
from pathlib import Path
|
|
31
24
|
|
|
32
25
|
from datamodel_code_generator.reference import Reference
|
|
@@ -42,7 +35,7 @@ def _has_field_assignment(field: DataModelFieldBase) -> bool:
|
|
|
42
35
|
|
|
43
36
|
class DataClass(DataModel):
|
|
44
37
|
TEMPLATE_FILE_PATH: ClassVar[str] = "dataclass.jinja2"
|
|
45
|
-
DEFAULT_IMPORTS: ClassVar[
|
|
38
|
+
DEFAULT_IMPORTS: ClassVar[tuple[Import, ...]] = (IMPORT_DATACLASS,)
|
|
46
39
|
|
|
47
40
|
def __init__( # noqa: PLR0913
|
|
48
41
|
self,
|
|
@@ -63,7 +56,7 @@ class DataClass(DataModel):
|
|
|
63
56
|
) -> None:
|
|
64
57
|
super().__init__(
|
|
65
58
|
reference=reference,
|
|
66
|
-
fields=sorted(fields, key=_has_field_assignment
|
|
59
|
+
fields=sorted(fields, key=_has_field_assignment),
|
|
67
60
|
decorators=decorators,
|
|
68
61
|
base_classes=base_classes,
|
|
69
62
|
custom_base_class=custom_base_class,
|
|
@@ -79,7 +72,7 @@ class DataClass(DataModel):
|
|
|
79
72
|
|
|
80
73
|
|
|
81
74
|
class DataModelField(DataModelFieldBase):
|
|
82
|
-
_FIELD_KEYS: ClassVar[
|
|
75
|
+
_FIELD_KEYS: ClassVar[set[str]] = {
|
|
83
76
|
"default_factory",
|
|
84
77
|
"init",
|
|
85
78
|
"repr",
|
|
@@ -143,7 +136,7 @@ class DataModelField(DataModelFieldBase):
|
|
|
143
136
|
class DataTypeManager(_DataTypeManager):
|
|
144
137
|
def __init__( # noqa: PLR0913, PLR0917
|
|
145
138
|
self,
|
|
146
|
-
python_version: PythonVersion =
|
|
139
|
+
python_version: PythonVersion = PythonVersionMin,
|
|
147
140
|
use_standard_collections: bool = False, # noqa: FBT001, FBT002
|
|
148
141
|
use_generic_container_types: bool = False, # noqa: FBT001, FBT002
|
|
149
142
|
strict_types: Sequence[StrictTypes] | None = None,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING, Any, ClassVar, Optional
|
|
3
|
+
from typing import TYPE_CHECKING, Any, ClassVar, Optional
|
|
4
4
|
|
|
5
5
|
from datamodel_code_generator.imports import IMPORT_ANY, IMPORT_ENUM, Import
|
|
6
6
|
from datamodel_code_generator.model import DataModel, DataModelFieldBase
|
|
@@ -33,7 +33,7 @@ SUBCLASS_BASE_CLASSES: dict[Types, str] = {
|
|
|
33
33
|
class Enum(DataModel):
|
|
34
34
|
TEMPLATE_FILE_PATH: ClassVar[str] = "Enum.jinja2"
|
|
35
35
|
BASE_CLASS: ClassVar[str] = "enum.Enum"
|
|
36
|
-
DEFAULT_IMPORTS: ClassVar[
|
|
36
|
+
DEFAULT_IMPORTS: ClassVar[tuple[Import, ...]] = (IMPORT_ENUM,)
|
|
37
37
|
|
|
38
38
|
def __init__( # noqa: PLR0913
|
|
39
39
|
self,
|
|
@@ -1,20 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from functools import wraps
|
|
4
|
-
from typing import
|
|
5
|
-
TYPE_CHECKING,
|
|
6
|
-
Any,
|
|
7
|
-
ClassVar,
|
|
8
|
-
Optional,
|
|
9
|
-
Sequence,
|
|
10
|
-
Set,
|
|
11
|
-
Tuple,
|
|
12
|
-
TypeVar,
|
|
13
|
-
)
|
|
4
|
+
from typing import TYPE_CHECKING, Any, ClassVar, Optional, TypeVar
|
|
14
5
|
|
|
15
6
|
from pydantic import Field
|
|
16
7
|
|
|
17
|
-
from datamodel_code_generator import DatetimeClassType, PythonVersion
|
|
8
|
+
from datamodel_code_generator import DatetimeClassType, PythonVersion, PythonVersionMin
|
|
18
9
|
from datamodel_code_generator.imports import (
|
|
19
10
|
IMPORT_DATE,
|
|
20
11
|
IMPORT_DATETIME,
|
|
@@ -46,6 +37,7 @@ from datamodel_code_generator.types import (
|
|
|
46
37
|
|
|
47
38
|
if TYPE_CHECKING:
|
|
48
39
|
from collections import defaultdict
|
|
40
|
+
from collections.abc import Sequence
|
|
49
41
|
from pathlib import Path
|
|
50
42
|
|
|
51
43
|
from datamodel_code_generator.reference import Reference
|
|
@@ -87,7 +79,7 @@ class RootModel(_RootModel):
|
|
|
87
79
|
class Struct(DataModel):
|
|
88
80
|
TEMPLATE_FILE_PATH: ClassVar[str] = "msgspec.jinja2"
|
|
89
81
|
BASE_CLASS: ClassVar[str] = "msgspec.Struct"
|
|
90
|
-
DEFAULT_IMPORTS: ClassVar[
|
|
82
|
+
DEFAULT_IMPORTS: ClassVar[tuple[Import, ...]] = ()
|
|
91
83
|
|
|
92
84
|
def __init__( # noqa: PLR0913
|
|
93
85
|
self,
|
|
@@ -108,7 +100,7 @@ class Struct(DataModel):
|
|
|
108
100
|
) -> None:
|
|
109
101
|
super().__init__(
|
|
110
102
|
reference=reference,
|
|
111
|
-
fields=sorted(fields, key=_has_field_assignment
|
|
103
|
+
fields=sorted(fields, key=_has_field_assignment),
|
|
112
104
|
decorators=decorators,
|
|
113
105
|
base_classes=base_classes,
|
|
114
106
|
custom_base_class=custom_base_class,
|
|
@@ -137,11 +129,11 @@ class Constraints(_Constraints):
|
|
|
137
129
|
|
|
138
130
|
@import_extender
|
|
139
131
|
class DataModelField(DataModelFieldBase):
|
|
140
|
-
_FIELD_KEYS: ClassVar[
|
|
132
|
+
_FIELD_KEYS: ClassVar[set[str]] = {
|
|
141
133
|
"default",
|
|
142
134
|
"default_factory",
|
|
143
135
|
}
|
|
144
|
-
_META_FIELD_KEYS: ClassVar[
|
|
136
|
+
_META_FIELD_KEYS: ClassVar[set[str]] = {
|
|
145
137
|
"title",
|
|
146
138
|
"description",
|
|
147
139
|
"gt",
|
|
@@ -158,7 +150,7 @@ class DataModelField(DataModelFieldBase):
|
|
|
158
150
|
# 'unique_items', # not supported by msgspec
|
|
159
151
|
}
|
|
160
152
|
_PARSE_METHOD = "convert"
|
|
161
|
-
_COMPARE_EXPRESSIONS: ClassVar[
|
|
153
|
+
_COMPARE_EXPRESSIONS: ClassVar[set[str]] = {"gt", "ge", "lt", "le", "multiple_of"}
|
|
162
154
|
constraints: Optional[Constraints] = None # noqa: UP045
|
|
163
155
|
|
|
164
156
|
def self_reference(self) -> bool: # pragma: no cover
|
|
@@ -287,7 +279,7 @@ class DataModelField(DataModelFieldBase):
|
|
|
287
279
|
class DataTypeManager(_DataTypeManager):
|
|
288
280
|
def __init__( # noqa: PLR0913, PLR0917
|
|
289
281
|
self,
|
|
290
|
-
python_version: PythonVersion =
|
|
282
|
+
python_version: PythonVersion = PythonVersionMin,
|
|
291
283
|
use_standard_collections: bool = False, # noqa: FBT001, FBT002
|
|
292
284
|
use_generic_container_types: bool = False, # noqa: FBT001, FBT002
|
|
293
285
|
strict_types: Sequence[StrictTypes] | None = None,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import
|
|
3
|
+
from typing import TYPE_CHECKING, Optional
|
|
4
4
|
|
|
5
5
|
from pydantic import BaseModel as _BaseModel
|
|
6
6
|
|
|
@@ -9,6 +9,9 @@ from .custom_root_type import CustomRootType
|
|
|
9
9
|
from .dataclass import DataClass
|
|
10
10
|
from .types import DataTypeManager
|
|
11
11
|
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from collections.abc import Iterable
|
|
14
|
+
|
|
12
15
|
|
|
13
16
|
def dump_resolve_reference_action(class_names: Iterable[str]) -> str:
|
|
14
17
|
return "\n".join(f"{class_name}.update_forward_refs()" for class_name in class_names)
|