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.
- datamodel_code_generator/__init__.py +168 -196
- datamodel_code_generator/__main__.py +146 -189
- datamodel_code_generator/arguments.py +227 -230
- datamodel_code_generator/format.py +77 -129
- datamodel_code_generator/http.py +12 -10
- datamodel_code_generator/imports.py +59 -65
- datamodel_code_generator/model/__init__.py +28 -31
- datamodel_code_generator/model/base.py +100 -144
- datamodel_code_generator/model/dataclass.py +62 -70
- datamodel_code_generator/model/enum.py +34 -30
- datamodel_code_generator/model/imports.py +13 -11
- datamodel_code_generator/model/msgspec.py +116 -138
- datamodel_code_generator/model/pydantic/__init__.py +18 -28
- datamodel_code_generator/model/pydantic/base_model.py +121 -140
- datamodel_code_generator/model/pydantic/custom_root_type.py +2 -2
- datamodel_code_generator/model/pydantic/dataclass.py +6 -4
- datamodel_code_generator/model/pydantic/imports.py +35 -33
- datamodel_code_generator/model/pydantic/types.py +91 -119
- datamodel_code_generator/model/pydantic_v2/__init__.py +21 -18
- datamodel_code_generator/model/pydantic_v2/base_model.py +118 -127
- datamodel_code_generator/model/pydantic_v2/imports.py +5 -3
- datamodel_code_generator/model/pydantic_v2/root_model.py +6 -6
- datamodel_code_generator/model/pydantic_v2/types.py +11 -7
- datamodel_code_generator/model/rootmodel.py +1 -1
- datamodel_code_generator/model/scalar.py +33 -32
- datamodel_code_generator/model/typed_dict.py +41 -51
- datamodel_code_generator/model/types.py +24 -19
- datamodel_code_generator/model/union.py +21 -17
- datamodel_code_generator/parser/__init__.py +16 -12
- datamodel_code_generator/parser/base.py +327 -515
- datamodel_code_generator/parser/graphql.py +87 -119
- datamodel_code_generator/parser/jsonschema.py +438 -607
- datamodel_code_generator/parser/openapi.py +180 -220
- datamodel_code_generator/pydantic_patch.py +8 -9
- datamodel_code_generator/reference.py +199 -297
- datamodel_code_generator/types.py +149 -215
- datamodel_code_generator/util.py +23 -36
- {datamodel_code_generator-0.27.2.dist-info → datamodel_code_generator-0.28.0.dist-info}/METADATA +10 -5
- datamodel_code_generator-0.28.0.dist-info/RECORD +59 -0
- datamodel_code_generator-0.27.2.dist-info/RECORD +0 -59
- {datamodel_code_generator-0.27.2.dist-info → datamodel_code_generator-0.28.0.dist-info}/WHEEL +0 -0
- {datamodel_code_generator-0.27.2.dist-info → datamodel_code_generator-0.28.0.dist-info}/entry_points.txt +0 -0
- {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
|
|
2
|
-
|
|
3
|
-
|
|
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] =
|
|
41
|
-
DEFAULT_IMPORTS: ClassVar[
|
|
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:
|
|
48
|
-
decorators:
|
|
49
|
-
base_classes:
|
|
50
|
-
custom_base_class:
|
|
51
|
-
custom_template_dir:
|
|
52
|
-
extra_template_data:
|
|
53
|
-
methods:
|
|
54
|
-
path:
|
|
55
|
-
description:
|
|
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
|
|
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[
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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) ->
|
|
87
|
+
def imports(self) -> tuple[Import, ...]:
|
|
91
88
|
field = self.field
|
|
92
|
-
if field and field.startswith(
|
|
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) ->
|
|
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:
|
|
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[
|
|
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
|
-
|
|
125
|
-
|
|
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
|
|
133
|
-
default = data[
|
|
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
|
|
130
|
+
return f"field(default_factory=lambda :{default!r})"
|
|
137
131
|
return repr(default)
|
|
138
|
-
kwargs = [
|
|
139
|
-
|
|
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 =
|
|
148
|
-
use_standard_collections: bool = False,
|
|
149
|
-
use_generic_container_types: bool = False,
|
|
150
|
-
strict_types:
|
|
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:
|
|
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
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
_STR: str = 'str'
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from collections import defaultdict
|
|
12
|
+
from pathlib import Path
|
|
16
13
|
|
|
17
|
-
|
|
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] =
|
|
31
|
-
BASE_CLASS: ClassVar[str] =
|
|
32
|
-
DEFAULT_IMPORTS: ClassVar[
|
|
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:
|
|
39
|
-
decorators:
|
|
40
|
-
base_classes:
|
|
41
|
-
custom_base_class:
|
|
42
|
-
custom_template_dir:
|
|
43
|
-
extra_template_data:
|
|
44
|
-
methods:
|
|
45
|
-
path:
|
|
46
|
-
description:
|
|
47
|
-
type_:
|
|
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:
|
|
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) ->
|
|
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
|
|
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) ->
|
|
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
|
|
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(
|
|
4
|
-
IMPORT_FIELD = Import.from_full_path(
|
|
5
|
-
IMPORT_CLASSVAR = Import.from_full_path(
|
|
6
|
-
IMPORT_TYPED_DICT = Import.from_full_path(
|
|
7
|
-
IMPORT_TYPED_DICT_BACKPORT = Import.from_full_path(
|
|
8
|
-
IMPORT_NOT_REQUIRED = Import.from_full_path(
|
|
9
|
-
IMPORT_NOT_REQUIRED_BACKPORT = Import.from_full_path(
|
|
10
|
-
IMPORT_MSGSPEC_STRUCT = Import.from_full_path(
|
|
11
|
-
IMPORT_MSGSPEC_FIELD = Import.from_full_path(
|
|
12
|
-
IMPORT_MSGSPEC_META = Import.from_full_path(
|
|
13
|
-
IMPORT_MSGSPEC_CONVERT = Import.from_full_path(
|
|
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")
|