datamodel-code-generator 0.21.2__tar.gz → 0.21.4__tar.gz
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-0.21.2 → datamodel_code_generator-0.21.4}/PKG-INFO +3 -3
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/README.md +1 -1
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/__init__.py +1 -1
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/__main__.py +23 -24
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/__init__.py +1 -1
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/base.py +27 -10
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/dataclass.py +1 -1
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/pydantic/types.py +14 -3
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/pydantic_v2/__init__.py +12 -2
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/pydantic_v2/base_model.py +11 -0
- datamodel_code_generator-0.21.4/datamodel_code_generator/model/pydantic_v2/root_model.py +21 -0
- datamodel_code_generator-0.21.4/datamodel_code_generator/model/pydantic_v2/types.py +30 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/typed_dict.py +5 -1
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/parser/base.py +18 -7
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/parser/jsonschema.py +5 -1
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/parser/openapi.py +5 -1
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/types.py +9 -1
- datamodel_code_generator-0.21.4/datamodel_code_generator/version.py +1 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/pyproject.toml +2 -2
- datamodel_code_generator-0.21.2/datamodel_code_generator/model/pydantic_v2/root_model.py +0 -10
- datamodel_code_generator-0.21.2/datamodel_code_generator/model/pydantic_v2/types.py +0 -9
- datamodel_code_generator-0.21.2/datamodel_code_generator/version.py +0 -1
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/LICENSE +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/format.py +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/http.py +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/imports.py +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/enum.py +0 -0
- /datamodel_code_generator-0.21.2/datamodel_code_generator/model/improts.py → /datamodel_code_generator-0.21.4/datamodel_code_generator/model/imports.py +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/pydantic/__init__.py +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/pydantic/base_model.py +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/pydantic/custom_root_type.py +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/pydantic/dataclass.py +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/pydantic/imports.py +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/pydantic_v2/imports.py +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/rootmodel.py +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/template/Enum.jinja2 +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/template/TypedDict.jinja2 +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/template/TypedDictClass.jinja2 +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/template/TypedDictFunction.jinja2 +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/template/dataclass.jinja2 +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/template/pydantic/BaseModel.jinja2 +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/template/pydantic/BaseModel_root.jinja2 +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/template/pydantic/Config.jinja2 +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/template/pydantic/dataclass.jinja2 +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/template/pydantic_v2/BaseModel.jinja2 +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/template/pydantic_v2/ConfigDict.jinja2 +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/template/pydantic_v2/RootModel.jinja2 +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/template/root.jinja2 +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/model/types.py +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/parser/__init__.py +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/py.typed +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/reference.py +0 -0
- {datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/util.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: datamodel-code-generator
|
|
3
|
-
Version: 0.21.
|
|
3
|
+
Version: 0.21.4
|
|
4
4
|
Summary: Datamodel Code Generator
|
|
5
5
|
Home-page: https://github.com/koxudaxi/datamodel-code-generator
|
|
6
6
|
License: MIT
|
|
@@ -26,7 +26,7 @@ Requires-Dist: httpx ; extra == "http"
|
|
|
26
26
|
Requires-Dist: inflect (>=4.1.0,<6.0)
|
|
27
27
|
Requires-Dist: isort (>=4.3.21,<6.0)
|
|
28
28
|
Requires-Dist: jinja2 (>=2.10.1,<4.0)
|
|
29
|
-
Requires-Dist: openapi-spec-validator (>=0.2.8,<=0.5.
|
|
29
|
+
Requires-Dist: openapi-spec-validator (>=0.2.8,<=0.5.7)
|
|
30
30
|
Requires-Dist: packaging
|
|
31
31
|
Requires-Dist: prance (>=0.18.2)
|
|
32
32
|
Requires-Dist: pydantic[email] (>=1.10.0,<3.0) ; python_version >= "3.11" and python_version < "4.0"
|
|
@@ -321,7 +321,7 @@ $ docker pull koxudaxi/datamodel-code-generator
|
|
|
321
321
|
```
|
|
322
322
|
|
|
323
323
|
## Advanced Uses
|
|
324
|
-
You can
|
|
324
|
+
You can generate models from a URL.
|
|
325
325
|
```bash
|
|
326
326
|
$ datamodel-codegen --url https://<INPUT FILE URL> --output model.py
|
|
327
327
|
```
|
|
@@ -283,7 +283,7 @@ $ docker pull koxudaxi/datamodel-code-generator
|
|
|
283
283
|
```
|
|
284
284
|
|
|
285
285
|
## Advanced Uses
|
|
286
|
-
You can
|
|
286
|
+
You can generate models from a URL.
|
|
287
287
|
```bash
|
|
288
288
|
$ datamodel-codegen --url https://<INPUT FILE URL> --output model.py
|
|
289
289
|
```
|
|
@@ -224,7 +224,7 @@ def generate(
|
|
|
224
224
|
output: Optional[Path] = None,
|
|
225
225
|
output_model_type: DataModelType = DataModelType.PydanticBaseModel,
|
|
226
226
|
target_python_version: PythonVersion = PythonVersion.PY_37,
|
|
227
|
-
base_class: str =
|
|
227
|
+
base_class: str = '',
|
|
228
228
|
additional_imports: Optional[List[str]] = None,
|
|
229
229
|
custom_template_dir: Optional[Path] = None,
|
|
230
230
|
extra_template_data: Optional[DefaultDict[str, Dict[str, Any]]] = None,
|
|
@@ -36,8 +36,10 @@ import black
|
|
|
36
36
|
import toml
|
|
37
37
|
from pydantic import BaseModel
|
|
38
38
|
|
|
39
|
+
if TYPE_CHECKING:
|
|
40
|
+
from typing_extensions import Self
|
|
41
|
+
|
|
39
42
|
from datamodel_code_generator import (
|
|
40
|
-
DEFAULT_BASE_CLASS,
|
|
41
43
|
DataModelType,
|
|
42
44
|
Error,
|
|
43
45
|
InputFileType,
|
|
@@ -470,9 +472,6 @@ class Config(BaseModel):
|
|
|
470
472
|
def __getitem__(self, item: str) -> Any:
|
|
471
473
|
return self.get(item)
|
|
472
474
|
|
|
473
|
-
def __setitem__(self, key: str, value: Any) -> None:
|
|
474
|
-
setattr(self, key, value)
|
|
475
|
-
|
|
476
475
|
if TYPE_CHECKING:
|
|
477
476
|
|
|
478
477
|
@classmethod
|
|
@@ -580,23 +579,21 @@ class Config(BaseModel):
|
|
|
580
579
|
return [validate_each_item(each_item) for each_item in value]
|
|
581
580
|
return value # pragma: no cover
|
|
582
581
|
|
|
583
|
-
|
|
584
|
-
def validate_root(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
|
585
|
-
values = cls._validate_use_annotated(values)
|
|
586
|
-
return cls._validate_base_class(values)
|
|
587
|
-
|
|
588
|
-
@classmethod
|
|
589
|
-
def _validate_use_annotated(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
|
590
|
-
if values.get('use_annotated'):
|
|
591
|
-
values['field_constraints'] = True
|
|
592
|
-
return values
|
|
582
|
+
if PYDANTIC_V2:
|
|
593
583
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
584
|
+
@model_validator(mode='after') # type: ignore
|
|
585
|
+
def validate_root(self: Self) -> Self:
|
|
586
|
+
if self.use_annotated:
|
|
587
|
+
self.field_constraints = True
|
|
588
|
+
return self
|
|
589
|
+
|
|
590
|
+
else:
|
|
591
|
+
|
|
592
|
+
@model_validator(mode='after')
|
|
593
|
+
def validate_root(cls, values: Any) -> Any:
|
|
594
|
+
if values.get('use_annotated'):
|
|
595
|
+
values['field_constraints'] = True
|
|
596
|
+
return values
|
|
600
597
|
|
|
601
598
|
input: Optional[Union[Path, str]] = None
|
|
602
599
|
input_file_type: InputFileType = InputFileType.Auto
|
|
@@ -605,7 +602,7 @@ class Config(BaseModel):
|
|
|
605
602
|
debug: bool = False
|
|
606
603
|
disable_warnings: bool = False
|
|
607
604
|
target_python_version: PythonVersion = PythonVersion.PY_37
|
|
608
|
-
base_class: str =
|
|
605
|
+
base_class: str = ''
|
|
609
606
|
custom_template_dir: Optional[Path] = None
|
|
610
607
|
extra_template_data: Optional[TextIOBase] = None
|
|
611
608
|
validation: bool = False
|
|
@@ -666,9 +663,11 @@ class Config(BaseModel):
|
|
|
666
663
|
for f in self.get_fields()
|
|
667
664
|
if getattr(args, f) is not None
|
|
668
665
|
}
|
|
669
|
-
|
|
670
|
-
set_args
|
|
671
|
-
|
|
666
|
+
|
|
667
|
+
if set_args.get('use_annotated'):
|
|
668
|
+
set_args['field_constraints'] = True
|
|
669
|
+
|
|
670
|
+
parsed_args = Config.parse_obj(set_args)
|
|
672
671
|
for field_name in set_args:
|
|
673
672
|
setattr(self, field_name, getattr(parsed_args, field_name))
|
|
674
673
|
|
|
@@ -38,7 +38,7 @@ def get_data_model_types(
|
|
|
38
38
|
root_model=pydantic_v2.RootModel,
|
|
39
39
|
field_model=pydantic_v2.DataModelField,
|
|
40
40
|
data_type_manager=pydantic_v2.DataTypeManager,
|
|
41
|
-
dump_resolve_reference_action=
|
|
41
|
+
dump_resolve_reference_action=pydantic_v2.dump_resolve_reference_action,
|
|
42
42
|
)
|
|
43
43
|
elif data_model_type == DataModelType.DataclassesDataclass:
|
|
44
44
|
return DataModelSet(
|
|
@@ -92,11 +92,15 @@ class DataModelFieldBase(_BaseModel):
|
|
|
92
92
|
super().__init__(**data)
|
|
93
93
|
if self.data_type.reference or self.data_type.data_types:
|
|
94
94
|
self.data_type.parent = self
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
self.process_const()
|
|
96
|
+
|
|
97
|
+
def process_const(self) -> None:
|
|
98
|
+
if 'const' not in self.extras:
|
|
99
|
+
return None
|
|
100
|
+
self.default = self.extras['const']
|
|
101
|
+
self.const = True
|
|
102
|
+
self.required = False
|
|
103
|
+
self.nullable = False
|
|
100
104
|
|
|
101
105
|
@property
|
|
102
106
|
def type_hint(self) -> str:
|
|
@@ -114,7 +118,10 @@ class DataModelFieldBase(_BaseModel):
|
|
|
114
118
|
return type_hint
|
|
115
119
|
elif self.required:
|
|
116
120
|
return type_hint
|
|
117
|
-
|
|
121
|
+
elif self.fall_back_to_nullable:
|
|
122
|
+
return get_optional_type(type_hint, self.data_type.use_union_operator)
|
|
123
|
+
else:
|
|
124
|
+
return type_hint
|
|
118
125
|
|
|
119
126
|
@property
|
|
120
127
|
def imports(self) -> Tuple[Import, ...]:
|
|
@@ -128,10 +135,16 @@ class DataModelFieldBase(_BaseModel):
|
|
|
128
135
|
)
|
|
129
136
|
]
|
|
130
137
|
|
|
131
|
-
if
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
138
|
+
if self.fall_back_to_nullable:
|
|
139
|
+
if (
|
|
140
|
+
self.nullable or (self.nullable is None and not self.required)
|
|
141
|
+
) and not self.data_type.use_union_operator:
|
|
142
|
+
imports.append((IMPORT_OPTIONAL,))
|
|
143
|
+
else:
|
|
144
|
+
if (
|
|
145
|
+
self.nullable and not self.data_type.use_union_operator
|
|
146
|
+
): # pragma: no cover
|
|
147
|
+
imports.append((IMPORT_OPTIONAL,))
|
|
135
148
|
if self.use_annotated:
|
|
136
149
|
import_annotated = (
|
|
137
150
|
IMPORT_ANNOTATED
|
|
@@ -174,6 +187,10 @@ class DataModelFieldBase(_BaseModel):
|
|
|
174
187
|
def has_default_factory(self) -> bool:
|
|
175
188
|
return 'default_factory' in self.extras
|
|
176
189
|
|
|
190
|
+
@property
|
|
191
|
+
def fall_back_to_nullable(self) -> bool:
|
|
192
|
+
return True
|
|
193
|
+
|
|
177
194
|
|
|
178
195
|
@lru_cache()
|
|
179
196
|
def get_template(template_file_path: Path) -> Template:
|
|
@@ -6,7 +6,7 @@ from typing import Any, ClassVar, DefaultDict, Dict, List, Optional, Set, Tuple
|
|
|
6
6
|
from datamodel_code_generator.imports import Import
|
|
7
7
|
from datamodel_code_generator.model import DataModel, DataModelFieldBase
|
|
8
8
|
from datamodel_code_generator.model.base import UNDEFINED
|
|
9
|
-
from datamodel_code_generator.model.
|
|
9
|
+
from datamodel_code_generator.model.imports import IMPORT_DATACLASS, IMPORT_FIELD
|
|
10
10
|
from datamodel_code_generator.model.pydantic.base_model import Constraints
|
|
11
11
|
from datamodel_code_generator.reference import Reference
|
|
12
12
|
from datamodel_code_generator.types import chain_as_tuple
|
|
@@ -44,7 +44,7 @@ from datamodel_code_generator.model.pydantic.imports import (
|
|
|
44
44
|
IMPORT_UUID4,
|
|
45
45
|
IMPORT_UUID5,
|
|
46
46
|
)
|
|
47
|
-
from datamodel_code_generator.types import DataType, StrictTypes, Types
|
|
47
|
+
from datamodel_code_generator.types import DataType, StrictTypes, Types, UnionIntFloat
|
|
48
48
|
from datamodel_code_generator.types import DataTypeManager as _DataTypeManager
|
|
49
49
|
|
|
50
50
|
|
|
@@ -155,7 +155,7 @@ class DataTypeManager(_DataTypeManager):
|
|
|
155
155
|
use_union_operator,
|
|
156
156
|
)
|
|
157
157
|
|
|
158
|
-
self.type_map: Dict[Types, DataType] = type_map_factory(
|
|
158
|
+
self.type_map: Dict[Types, DataType] = self.type_map_factory(
|
|
159
159
|
self.data_type,
|
|
160
160
|
strict_types=self.strict_types,
|
|
161
161
|
pattern_key=self.PATTERN_KEY,
|
|
@@ -177,6 +177,14 @@ class DataTypeManager(_DataTypeManager):
|
|
|
177
177
|
'pattern': self.PATTERN_KEY,
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
def type_map_factory(
|
|
181
|
+
self,
|
|
182
|
+
data_type: Type[DataType],
|
|
183
|
+
strict_types: Sequence[StrictTypes],
|
|
184
|
+
pattern_key: str,
|
|
185
|
+
) -> Dict[Types, DataType]:
|
|
186
|
+
return type_map_factory(data_type, strict_types, pattern_key)
|
|
187
|
+
|
|
180
188
|
def transform_kwargs(
|
|
181
189
|
self, kwargs: Dict[str, Any], filter_: Set[str]
|
|
182
190
|
) -> Dict[str, str]:
|
|
@@ -253,7 +261,10 @@ class DataTypeManager(_DataTypeManager):
|
|
|
253
261
|
if data_type_kwargs:
|
|
254
262
|
return self.data_type.from_import(
|
|
255
263
|
IMPORT_CONDECIMAL,
|
|
256
|
-
kwargs={
|
|
264
|
+
kwargs={
|
|
265
|
+
k: Decimal(str(v) if isinstance(v, UnionIntFloat) else v)
|
|
266
|
+
for k, v in data_type_kwargs.items()
|
|
267
|
+
},
|
|
257
268
|
)
|
|
258
269
|
return self.type_map[types]
|
|
259
270
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import Optional
|
|
3
|
+
from typing import Iterable, Optional
|
|
4
4
|
|
|
5
5
|
from pydantic import BaseModel as _BaseModel
|
|
6
6
|
|
|
@@ -9,6 +9,10 @@ from .root_model import RootModel
|
|
|
9
9
|
from .types import DataTypeManager
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
def dump_resolve_reference_action(class_names: Iterable[str]) -> str:
|
|
13
|
+
return '\n'.join(f'{class_name}.model_rebuild()' for class_name in class_names)
|
|
14
|
+
|
|
15
|
+
|
|
12
16
|
class ConfigDict(_BaseModel):
|
|
13
17
|
extra: Optional[str] = None
|
|
14
18
|
title: Optional[str] = None
|
|
@@ -18,4 +22,10 @@ class ConfigDict(_BaseModel):
|
|
|
18
22
|
arbitrary_types_allowed: Optional[bool] = None
|
|
19
23
|
|
|
20
24
|
|
|
21
|
-
__all__ = [
|
|
25
|
+
__all__ = [
|
|
26
|
+
'BaseModel',
|
|
27
|
+
'DataModelField',
|
|
28
|
+
'RootModel',
|
|
29
|
+
'dump_resolve_reference_action',
|
|
30
|
+
'DataTypeManager',
|
|
31
|
+
]
|
|
@@ -61,6 +61,17 @@ class DataModelField(DataModelFieldV1):
|
|
|
61
61
|
constraints: Optional[Constraints] = None
|
|
62
62
|
_PARSE_METHOD: ClassVar[str] = 'model_validate'
|
|
63
63
|
|
|
64
|
+
def process_const(self) -> None:
|
|
65
|
+
if 'const' not in self.extras:
|
|
66
|
+
return None
|
|
67
|
+
self.const = True
|
|
68
|
+
self.nullable = False
|
|
69
|
+
const = self.extras['const']
|
|
70
|
+
if self.data_type.type == 'str' and isinstance(
|
|
71
|
+
const, str
|
|
72
|
+
): # pragma: no cover # Literal supports only str
|
|
73
|
+
self.data_type = self.data_type.__class__(literals=[const])
|
|
74
|
+
|
|
64
75
|
def _process_data_in_str(self, data: Dict[str, Any]) -> None:
|
|
65
76
|
if self.const:
|
|
66
77
|
# const is removed in pydantic 2.0
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, ClassVar
|
|
4
|
+
|
|
5
|
+
from datamodel_code_generator.model.pydantic_v2.base_model import BaseModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class RootModel(BaseModel):
|
|
9
|
+
TEMPLATE_FILE_PATH: ClassVar[str] = 'pydantic_v2/RootModel.jinja2'
|
|
10
|
+
BASE_CLASS: ClassVar[str] = 'pydantic.RootModel'
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
**kwargs: Any,
|
|
15
|
+
) -> None:
|
|
16
|
+
# Remove custom_base_class for Pydantic V2 models; behaviour is different from Pydantic V1 as it will not
|
|
17
|
+
# be treated as a root model. custom_base_class cannot both implement BaseModel and RootModel!
|
|
18
|
+
if 'custom_base_class' in kwargs:
|
|
19
|
+
kwargs.pop('custom_base_class')
|
|
20
|
+
|
|
21
|
+
super().__init__(**kwargs)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import ClassVar, Dict, Sequence, Type
|
|
4
|
+
|
|
5
|
+
from datamodel_code_generator.model.pydantic import DataTypeManager as _DataTypeManager
|
|
6
|
+
from datamodel_code_generator.model.pydantic.imports import IMPORT_CONSTR
|
|
7
|
+
from datamodel_code_generator.types import DataType, StrictTypes, Types
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class DataTypeManager(_DataTypeManager):
|
|
11
|
+
PATTERN_KEY: ClassVar[str] = 'pattern'
|
|
12
|
+
|
|
13
|
+
def type_map_factory(
|
|
14
|
+
self,
|
|
15
|
+
data_type: Type[DataType],
|
|
16
|
+
strict_types: Sequence[StrictTypes],
|
|
17
|
+
pattern_key: str,
|
|
18
|
+
) -> Dict[Types, DataType]:
|
|
19
|
+
return {
|
|
20
|
+
**super().type_map_factory(data_type, strict_types, pattern_key),
|
|
21
|
+
Types.hostname: self.data_type.from_import(
|
|
22
|
+
IMPORT_CONSTR,
|
|
23
|
+
strict=StrictTypes.str in strict_types,
|
|
24
|
+
# https://github.com/horejsek/python-fastjsonschema/blob/61c6997a8348b8df9b22e029ca2ba35ef441fbb8/fastjsonschema/draft04.py#L31
|
|
25
|
+
kwargs={
|
|
26
|
+
pattern_key: r"r'^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]{0,61}[A-Za-z0-9])$'",
|
|
27
|
+
**({'strict': True} if StrictTypes.str in strict_types else {}),
|
|
28
|
+
},
|
|
29
|
+
),
|
|
30
|
+
}
|
|
@@ -16,7 +16,7 @@ from typing import (
|
|
|
16
16
|
from datamodel_code_generator.imports import Import
|
|
17
17
|
from datamodel_code_generator.model import DataModel, DataModelFieldBase
|
|
18
18
|
from datamodel_code_generator.model.base import UNDEFINED
|
|
19
|
-
from datamodel_code_generator.model.
|
|
19
|
+
from datamodel_code_generator.model.imports import (
|
|
20
20
|
IMPORT_NOT_REQUIRED,
|
|
21
21
|
IMPORT_NOT_REQUIRED_BACKPORT,
|
|
22
22
|
IMPORT_TYPED_DICT,
|
|
@@ -139,6 +139,10 @@ class DataModelField(DataModelFieldBase):
|
|
|
139
139
|
def _not_required(self) -> bool:
|
|
140
140
|
return not self.required and isinstance(self.parent, TypedDict)
|
|
141
141
|
|
|
142
|
+
@property
|
|
143
|
+
def fall_back_to_nullable(self) -> bool:
|
|
144
|
+
return not self._not_required
|
|
145
|
+
|
|
142
146
|
@property
|
|
143
147
|
def imports(self) -> Tuple[Import, ...]:
|
|
144
148
|
return (
|
|
@@ -28,7 +28,6 @@ from pydantic import BaseModel
|
|
|
28
28
|
from datamodel_code_generator.format import CodeFormatter, PythonVersion
|
|
29
29
|
from datamodel_code_generator.imports import IMPORT_ANNOTATIONS, Import, Imports
|
|
30
30
|
from datamodel_code_generator.model import pydantic as pydantic_model
|
|
31
|
-
from datamodel_code_generator.model import pydantic_v2 as pydantic_v2_model
|
|
32
31
|
from datamodel_code_generator.model.base import (
|
|
33
32
|
ALL_MODEL,
|
|
34
33
|
UNDEFINED,
|
|
@@ -38,6 +37,7 @@ from datamodel_code_generator.model.base import (
|
|
|
38
37
|
DataModelFieldBase,
|
|
39
38
|
)
|
|
40
39
|
from datamodel_code_generator.model.enum import Enum, Member
|
|
40
|
+
from datamodel_code_generator.model.pydantic_v2 import RootModel
|
|
41
41
|
from datamodel_code_generator.parser import DefaultPutDict, LiteralType
|
|
42
42
|
from datamodel_code_generator.reference import ModelResolver, Reference
|
|
43
43
|
from datamodel_code_generator.types import DataType, DataTypeManager, StrictTypes
|
|
@@ -723,10 +723,7 @@ class Parser(ABC):
|
|
|
723
723
|
def __replace_unique_list_to_set(self, models: List[DataModel]) -> None:
|
|
724
724
|
for model in models:
|
|
725
725
|
for model_field in model.fields:
|
|
726
|
-
if not
|
|
727
|
-
isinstance(model_field, pydantic_v2_model.DataModelField)
|
|
728
|
-
or self.use_unique_items_as_set
|
|
729
|
-
):
|
|
726
|
+
if not self.use_unique_items_as_set:
|
|
730
727
|
continue
|
|
731
728
|
|
|
732
729
|
if not (
|
|
@@ -797,10 +794,11 @@ class Parser(ABC):
|
|
|
797
794
|
models.remove(duplicate)
|
|
798
795
|
|
|
799
796
|
def __collapse_root_models(
|
|
800
|
-
self, models: List[DataModel], unused_models: List[DataModel]
|
|
797
|
+
self, models: List[DataModel], unused_models: List[DataModel], imports: Imports
|
|
801
798
|
) -> None:
|
|
802
799
|
if not self.collapse_root_models:
|
|
803
800
|
return None
|
|
801
|
+
unused_model_count = len(unused_models)
|
|
804
802
|
for model in models:
|
|
805
803
|
for model_field in model.fields:
|
|
806
804
|
for data_type in model_field.data_type.all_data_types:
|
|
@@ -834,6 +832,8 @@ class Parser(ABC):
|
|
|
834
832
|
model_field.extras = dict(
|
|
835
833
|
root_type_field.extras, **model_field.extras
|
|
836
834
|
)
|
|
835
|
+
model_field.process_const()
|
|
836
|
+
|
|
837
837
|
if self.field_constraints:
|
|
838
838
|
if isinstance(
|
|
839
839
|
root_type_field.constraints, ConstraintsBase
|
|
@@ -876,6 +876,17 @@ class Parser(ABC):
|
|
|
876
876
|
if not root_type_model.reference.children:
|
|
877
877
|
unused_models.append(root_type_model)
|
|
878
878
|
|
|
879
|
+
if self.data_model_root_type == RootModel and unused_model_count != len(
|
|
880
|
+
unused_models
|
|
881
|
+
):
|
|
882
|
+
if {m for m in models if isinstance(m, RootModel)} - { # pragma: no cover
|
|
883
|
+
m for m in unused_models if isinstance(m, RootModel)
|
|
884
|
+
}:
|
|
885
|
+
return None # pragma: no cover
|
|
886
|
+
|
|
887
|
+
if 'RootModel' in imports['pydantic']: # pragma: no cover
|
|
888
|
+
imports['pydantic'].remove('RootModel')
|
|
889
|
+
|
|
879
890
|
def __set_default_enum_member(
|
|
880
891
|
self,
|
|
881
892
|
models: List[DataModel],
|
|
@@ -1096,7 +1107,7 @@ class Parser(ABC):
|
|
|
1096
1107
|
self.__extract_inherited_enum(models)
|
|
1097
1108
|
self.__set_reference_default_value_to_field(models)
|
|
1098
1109
|
self.__reuse_model(models, require_update_action_models)
|
|
1099
|
-
self.__collapse_root_models(models, unused_models)
|
|
1110
|
+
self.__collapse_root_models(models, unused_models, imports)
|
|
1100
1111
|
self.__set_default_enum_member(models)
|
|
1101
1112
|
self.__override_required_field(models)
|
|
1102
1113
|
self.__sort_models(models, imports)
|
|
@@ -173,6 +173,10 @@ class JsonSchemaObject(BaseModel):
|
|
|
173
173
|
def get_fields(cls) -> Dict[str, Any]:
|
|
174
174
|
return cls.__fields__
|
|
175
175
|
|
|
176
|
+
@classmethod
|
|
177
|
+
def model_rebuild(cls) -> None:
|
|
178
|
+
cls.update_forward_refs()
|
|
179
|
+
|
|
176
180
|
__constraint_fields__: Set[str] = {
|
|
177
181
|
'exclusiveMinimum',
|
|
178
182
|
'minimum',
|
|
@@ -339,7 +343,7 @@ def _get_type(type_: str, format__: Optional[str] = None) -> Types:
|
|
|
339
343
|
return json_schema_data_formats[type_]['default']
|
|
340
344
|
|
|
341
345
|
|
|
342
|
-
JsonSchemaObject.
|
|
346
|
+
JsonSchemaObject.model_rebuild()
|
|
343
347
|
|
|
344
348
|
DEFAULT_FIELD_KEYS: Set[str] = {
|
|
345
349
|
'example',
|
|
@@ -479,7 +479,11 @@ class OpenAPIParser(JsonSchemaParser):
|
|
|
479
479
|
|
|
480
480
|
if OpenAPIScope.Parameters in self.open_api_scopes and fields:
|
|
481
481
|
self.results.append(
|
|
482
|
-
self.data_model_type(
|
|
482
|
+
self.data_model_type(
|
|
483
|
+
fields=fields,
|
|
484
|
+
reference=reference,
|
|
485
|
+
custom_base_class=self.base_class,
|
|
486
|
+
)
|
|
483
487
|
)
|
|
484
488
|
|
|
485
489
|
def parse_operation(
|
|
@@ -110,6 +110,9 @@ class UnionIntFloat:
|
|
|
110
110
|
def __float__(self) -> float:
|
|
111
111
|
return float(self.value)
|
|
112
112
|
|
|
113
|
+
def __str__(self) -> str:
|
|
114
|
+
return str(self.value)
|
|
115
|
+
|
|
113
116
|
@classmethod
|
|
114
117
|
def __get_validators__(cls) -> Iterator[Callable[[Any], Any]]:
|
|
115
118
|
yield cls.validate
|
|
@@ -234,6 +237,11 @@ class DataType(_BaseModel):
|
|
|
234
237
|
revalidate_instances='never',
|
|
235
238
|
)
|
|
236
239
|
else:
|
|
240
|
+
if not TYPE_CHECKING:
|
|
241
|
+
|
|
242
|
+
@classmethod
|
|
243
|
+
def model_rebuild(cls) -> None:
|
|
244
|
+
cls.update_forward_refs()
|
|
237
245
|
|
|
238
246
|
class Config:
|
|
239
247
|
extra = 'forbid'
|
|
@@ -498,7 +506,7 @@ class DataType(_BaseModel):
|
|
|
498
506
|
return len(self.data_types) > 1
|
|
499
507
|
|
|
500
508
|
|
|
501
|
-
DataType.
|
|
509
|
+
DataType.model_rebuild()
|
|
502
510
|
|
|
503
511
|
DataTypeT = TypeVar('DataTypeT', bound=DataType)
|
|
504
512
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version: str = '0.21.4'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "datamodel-code-generator"
|
|
3
|
-
version = "0.21.
|
|
3
|
+
version = "0.21.4"
|
|
4
4
|
description = "Datamodel Code Generator"
|
|
5
5
|
authors = ["Koudai Aono <koxudaxi@gmail.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -48,7 +48,7 @@ pydantic = [
|
|
|
48
48
|
]
|
|
49
49
|
argcomplete = ">=1.10,<4.0"
|
|
50
50
|
prance = ">=0.18.2"
|
|
51
|
-
openapi-spec-validator = ">=0.2.8,<=0.5.
|
|
51
|
+
openapi-spec-validator = ">=0.2.8,<=0.5.7"
|
|
52
52
|
jinja2 = ">=2.10.1,<4.0"
|
|
53
53
|
inflect = ">=4.1.0,<6.0"
|
|
54
54
|
black = ">=19.10b0"
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import ClassVar
|
|
4
|
-
|
|
5
|
-
from datamodel_code_generator.model.pydantic_v2.base_model import BaseModel
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class RootModel(BaseModel):
|
|
9
|
-
TEMPLATE_FILE_PATH: ClassVar[str] = 'pydantic_v2/RootModel.jinja2'
|
|
10
|
-
BASE_CLASS: ClassVar[str] = 'pydantic.RootModel'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
version: str = '0.21.2'
|
|
File without changes
|
|
File without changes
|
{datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/http.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datamodel_code_generator-0.21.2 → datamodel_code_generator-0.21.4}/datamodel_code_generator/util.py
RENAMED
|
File without changes
|