-
Notifications
You must be signed in to change notification settings - Fork 12
/
pydantic.py
96 lines (85 loc) · 2.95 KB
/
pydantic.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
from typing import List, Optional, Tuple
from .base import GenericModelCodeGenerator, KWAGRS_TEMPLATE, sort_kwargs, template
from ..dynamic_typing import (
DDict,
DList,
DOptional,
ImportPathList,
MetaData,
ModelMeta,
Null,
StringLiteral,
StringSerializable,
Unknown
)
DEFAULT_ORDER = (
"*",
)
class PydanticModelCodeGenerator(GenericModelCodeGenerator):
PYDANTIC_FIELD = template("Field({{ default }}{% if kwargs %}, KWAGRS_TEMPLATE{% endif %})"
.replace('KWAGRS_TEMPLATE', KWAGRS_TEMPLATE))
default_types_style = {
StringSerializable: {
StringSerializable.TypeStyle.use_actual_type: True
},
StringLiteral: {
StringLiteral.TypeStyle.use_literals: True
}
}
def __init__(self, model: ModelMeta, **kwargs):
"""
:param model: ModelMeta instance
:param kwargs:
"""
kwargs['post_init_converters'] = False
super().__init__(model, **kwargs)
def generate(self, nested_classes: List[str] = None, extra: str = "", **kwargs) \
-> Tuple[ImportPathList, str]:
imports, body = super(PydanticModelCodeGenerator, self).generate(
bases='BaseModel',
nested_classes=nested_classes,
extra=extra
)
imports.append(('pydantic', ['BaseModel', 'Field']))
return imports, body
def _filter_fields(self, fields):
fields = super()._filter_fields(fields)
filtered = []
for field in fields:
field_type = self.model.type[field]
if field_type in (Unknown, Null):
continue
filtered.append(field)
return filtered
def field_data(self, name: str, meta: MetaData, optional: bool) -> Tuple[ImportPathList, dict]:
"""
Form field data for template
:param name: Original field name
:param meta: Field metadata
:param optional: Is field optional
:return: imports, field data
"""
imports, data = super().field_data(name, meta, optional)
default: Optional[str] = None
if optional:
meta: DOptional
if isinstance(meta.type, DList):
default = "[]"
elif isinstance(meta.type, DDict):
default = "{}"
else:
default = "None"
body_kwargs = self._get_field_kwargs(name, meta, optional, data)
if body_kwargs:
data["body"] = self.PYDANTIC_FIELD.render(
default=default or '...',
kwargs=sort_kwargs(body_kwargs, DEFAULT_ORDER)
)
elif default is not None:
data["body"] = default
return imports, data
def _get_field_kwargs(self, name: str, meta: MetaData, optional: bool, data: dict):
body_kwargs = {}
if name != data["name"]:
body_kwargs["alias"] = f'"{name}"'
return body_kwargs