@autorest/python 6.1.5 → 6.1.7
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.
- package/autorest/__init__.py +10 -3
- package/autorest/black/__init__.py +2 -8
- package/autorest/codegen/__init__.py +4 -2
- package/autorest/codegen/models/__init__.py +1 -1
- package/autorest/codegen/models/base_builder.py +4 -1
- package/autorest/codegen/models/client.py +5 -3
- package/autorest/codegen/models/combined_type.py +6 -4
- package/autorest/codegen/models/enum_type.py +6 -4
- package/autorest/codegen/models/model_type.py +30 -9
- package/autorest/codegen/models/operation.py +32 -0
- package/autorest/codegen/models/operation_group.py +11 -7
- package/autorest/codegen/models/parameter.py +44 -0
- package/autorest/codegen/models/property.py +8 -15
- package/autorest/codegen/models/request_builder_parameter.py +4 -2
- package/autorest/codegen/serializers/__init__.py +18 -2
- package/autorest/codegen/serializers/builder_serializer.py +64 -22
- package/autorest/codegen/serializers/client_serializer.py +3 -4
- package/autorest/codegen/serializers/general_serializer.py +8 -0
- package/autorest/codegen/serializers/model_serializer.py +159 -61
- package/autorest/codegen/templates/model_base.py.jinja2 +636 -0
- package/autorest/codegen/templates/model_container.py.jinja2 +6 -2
- package/autorest/codegen/templates/model_dpg.py.jinja2 +62 -0
- package/autorest/codegen/templates/model_init.py.jinja2 +0 -5
- package/autorest/codegen/templates/{model.py.jinja2 → model_msrest.py.jinja2} +1 -1
- package/autorest/codegen/templates/operation_group.py.jinja2 +1 -1
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/validation.py.jinja2 +38 -0
- package/package.json +9 -10
- package/ChangeLog.md +0 -1284
|
@@ -173,6 +173,22 @@ def _get_json_response_template_to_status_codes(
|
|
|
173
173
|
return retval
|
|
174
174
|
|
|
175
175
|
|
|
176
|
+
def _api_version_validation(builder: OperationType) -> str:
|
|
177
|
+
retval: List[str] = []
|
|
178
|
+
if builder.added_on:
|
|
179
|
+
retval.append(f' method_added_on="{builder.added_on}",')
|
|
180
|
+
params_added_on = defaultdict(list)
|
|
181
|
+
for parameter in builder.parameters:
|
|
182
|
+
if parameter.added_on:
|
|
183
|
+
params_added_on[parameter.added_on].append(parameter.client_name)
|
|
184
|
+
if params_added_on:
|
|
185
|
+
retval.append(f" params_added_on={dict(params_added_on)},")
|
|
186
|
+
if retval:
|
|
187
|
+
retval_str = "\n".join(retval)
|
|
188
|
+
return f"@api_version_validation(\n{retval_str}\n)"
|
|
189
|
+
return ""
|
|
190
|
+
|
|
191
|
+
|
|
176
192
|
class _BuilderBaseSerializer(Generic[BuilderType]): # pylint: disable=abstract-method
|
|
177
193
|
def __init__(self, code_model: CodeModel, async_mode: bool) -> None:
|
|
178
194
|
self.code_model = code_model
|
|
@@ -590,8 +606,10 @@ class _OperationSerializer(
|
|
|
590
606
|
|
|
591
607
|
def decorators(self, builder: OperationType) -> List[str]:
|
|
592
608
|
"""Decorators for the method"""
|
|
593
|
-
|
|
594
|
-
|
|
609
|
+
retval = super().decorators(builder)
|
|
610
|
+
if _api_version_validation(builder):
|
|
611
|
+
retval.append(_api_version_validation(builder))
|
|
612
|
+
return retval
|
|
595
613
|
|
|
596
614
|
def param_description(
|
|
597
615
|
self, builder: OperationType
|
|
@@ -656,7 +674,7 @@ class _OperationSerializer(
|
|
|
656
674
|
ser_ctxt_name = "serialization_ctxt"
|
|
657
675
|
if xml_serialization_ctxt and self.code_model.options["models_mode"]:
|
|
658
676
|
retval.append(f'{ser_ctxt_name} = {{"xml": {{{xml_serialization_ctxt}}}}}')
|
|
659
|
-
if self.code_model.options["models_mode"]:
|
|
677
|
+
if self.code_model.options["models_mode"] == "msrest":
|
|
660
678
|
is_xml_cmd = ", is_xml=True" if send_xml else ""
|
|
661
679
|
serialization_ctxt_cmd = (
|
|
662
680
|
f", {ser_ctxt_name}={ser_ctxt_name}" if xml_serialization_ctxt else ""
|
|
@@ -665,6 +683,8 @@ class _OperationSerializer(
|
|
|
665
683
|
f"_{body_kwarg_name} = self._serialize.body({body_param.client_name}, "
|
|
666
684
|
f"'{body_param.type.serialization_type}'{is_xml_cmd}{serialization_ctxt_cmd})"
|
|
667
685
|
)
|
|
686
|
+
elif self.code_model.options["models_mode"] == "dpg":
|
|
687
|
+
create_body_call = f"_{body_kwarg_name} = json.dumps({body_param.client_name}, cls=AzureJSONEncoder)"
|
|
668
688
|
else:
|
|
669
689
|
create_body_call = f"_{body_kwarg_name} = {body_param.client_name}"
|
|
670
690
|
if body_param.optional:
|
|
@@ -729,10 +749,12 @@ class _OperationSerializer(
|
|
|
729
749
|
0
|
|
730
750
|
].parameters.body_parameter.default_content_type
|
|
731
751
|
retval.append(f'content_type = content_type or "{default_content_type}"')
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
752
|
+
client_names = [
|
|
753
|
+
overload.request_builder.parameters.body_parameter.client_name
|
|
754
|
+
for overload in builder.overloads
|
|
755
|
+
]
|
|
756
|
+
for v in sorted(set(client_names), key=client_names.index):
|
|
757
|
+
retval.append(f"_{v} = None")
|
|
736
758
|
try:
|
|
737
759
|
# if there is a binary overload, we do a binary check first.
|
|
738
760
|
binary_overload = cast(
|
|
@@ -941,10 +963,16 @@ class _OperationSerializer(
|
|
|
941
963
|
)
|
|
942
964
|
)
|
|
943
965
|
elif response.type:
|
|
944
|
-
if self.code_model.options["models_mode"]:
|
|
966
|
+
if self.code_model.options["models_mode"] == "msrest":
|
|
945
967
|
retval.append(
|
|
946
968
|
f"deserialized = self._deserialize('{response.serialization_type}', pipeline_response)"
|
|
947
969
|
)
|
|
970
|
+
elif self.code_model.options["models_mode"] == "dpg" and isinstance(
|
|
971
|
+
response.type, ModelType
|
|
972
|
+
):
|
|
973
|
+
retval.append(
|
|
974
|
+
f"deserialized = _deserialize({response.serialization_type}, response.json())"
|
|
975
|
+
)
|
|
948
976
|
else:
|
|
949
977
|
deserialized_value = (
|
|
950
978
|
"ET.fromstring(response.text())"
|
|
@@ -969,10 +997,15 @@ class _OperationSerializer(
|
|
|
969
997
|
builder.default_error_deserialization
|
|
970
998
|
and self.code_model.options["models_mode"]
|
|
971
999
|
):
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
1000
|
+
if self.code_model.options["models_mode"] == "dpg":
|
|
1001
|
+
retval.append(
|
|
1002
|
+
f" error = _deserialize({builder.default_error_deserialization}, response.json())"
|
|
1003
|
+
)
|
|
1004
|
+
else:
|
|
1005
|
+
retval.append(
|
|
1006
|
+
f" error = self._deserialize.failsafe_deserialize({builder.default_error_deserialization}, "
|
|
1007
|
+
"pipeline_response)"
|
|
1008
|
+
)
|
|
976
1009
|
error_model = ", model=error"
|
|
977
1010
|
retval.append(
|
|
978
1011
|
" raise HttpResponseError(response=response{}{})".format(
|
|
@@ -1047,11 +1080,14 @@ class _OperationSerializer(
|
|
|
1047
1080
|
retval.append(" 304: ResourceNotModifiedError,")
|
|
1048
1081
|
for excep in builder.non_default_errors:
|
|
1049
1082
|
error_model_str = ""
|
|
1050
|
-
if (
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1083
|
+
if isinstance(excep.type, ModelType):
|
|
1084
|
+
if self.code_model.options["models_mode"] == "msrest":
|
|
1085
|
+
error_model_str = (
|
|
1086
|
+
f", model=self._deserialize("
|
|
1087
|
+
f"_models.{excep.type.serialization_type}, response)"
|
|
1088
|
+
)
|
|
1089
|
+
elif self.code_model.options["models_mode"] == "dpg":
|
|
1090
|
+
error_model_str = f", model=_deserialize(_models.{excep.type.name}, response.json())"
|
|
1055
1091
|
error_format_str = (
|
|
1056
1092
|
", error_format=ARMErrorFormat"
|
|
1057
1093
|
if self.code_model.options["azure_arm"]
|
|
@@ -1138,6 +1174,8 @@ class _PagingOperationSerializer(
|
|
|
1138
1174
|
return ["@overload"]
|
|
1139
1175
|
if self.code_model.options["tracing"] and builder.want_tracing:
|
|
1140
1176
|
retval.append("@distributed_trace")
|
|
1177
|
+
if _api_version_validation(builder):
|
|
1178
|
+
retval.append(_api_version_validation(builder))
|
|
1141
1179
|
return retval
|
|
1142
1180
|
|
|
1143
1181
|
def call_next_link_request_builder(self, builder: PagingOperationType) -> List[str]:
|
|
@@ -1218,11 +1256,15 @@ class _PagingOperationSerializer(
|
|
|
1218
1256
|
f"{'async ' if self.async_mode else ''}def extract_data(pipeline_response):"
|
|
1219
1257
|
]
|
|
1220
1258
|
response = builder.responses[0]
|
|
1221
|
-
deserialized = (
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1259
|
+
deserialized = "pipeline_response.http_response.json()"
|
|
1260
|
+
if self.code_model.options["models_mode"] == "msrest":
|
|
1261
|
+
deserialized = (
|
|
1262
|
+
f'self._deserialize("{response.serialization_type}", pipeline_response)'
|
|
1263
|
+
)
|
|
1264
|
+
elif self.code_model.options["models_mode"] == "dpg":
|
|
1265
|
+
deserialized = (
|
|
1266
|
+
f"_deserialize({response.serialization_type}, pipeline_response)"
|
|
1267
|
+
)
|
|
1226
1268
|
retval.append(f" deserialized = {deserialized}")
|
|
1227
1269
|
item_name = builder.item_name
|
|
1228
1270
|
list_of_elem = (
|
|
@@ -125,11 +125,10 @@ class ClientSerializer:
|
|
|
125
125
|
)
|
|
126
126
|
else:
|
|
127
127
|
client_models_value = "{} # type: Dict[str, Any]"
|
|
128
|
-
|
|
128
|
+
is_msrest_model = self.code_model.options["models_mode"] == "msrest"
|
|
129
|
+
if is_msrest_model:
|
|
129
130
|
retval.append(f"client_models = {client_models_value}")
|
|
130
|
-
client_models_str =
|
|
131
|
-
"client_models" if self.code_model.options["models_mode"] else ""
|
|
132
|
-
)
|
|
131
|
+
client_models_str = "client_models" if is_msrest_model else ""
|
|
133
132
|
retval.append(f"self._serialize = Serializer({client_models_str})")
|
|
134
133
|
retval.append(f"self._deserialize = Deserializer({client_models_str})")
|
|
135
134
|
if not self.code_model.options["client_side_validation"]:
|
|
@@ -120,3 +120,11 @@ class GeneralSerializer:
|
|
|
120
120
|
def serialize_serialization_file(self) -> str:
|
|
121
121
|
template = self.env.get_template("serialization.py.jinja2")
|
|
122
122
|
return template.render(code_model=self.code_model)
|
|
123
|
+
|
|
124
|
+
def serialize_model_base_file(self) -> str:
|
|
125
|
+
template = self.env.get_template("model_base.py.jinja2")
|
|
126
|
+
return template.render(code_model=self.code_model)
|
|
127
|
+
|
|
128
|
+
def serialize_validation_file(self) -> str:
|
|
129
|
+
template = self.env.get_template("validation.py.jinja2")
|
|
130
|
+
return template.render(code_model=self.code_model)
|
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from typing import cast, List
|
|
7
|
+
from abc import ABC, abstractmethod
|
|
7
8
|
from jinja2 import Environment
|
|
8
9
|
from ..models import ModelType, CodeModel, Property
|
|
9
|
-
from ..models.imports import FileImport, TypingSection, MsrestImportType
|
|
10
|
+
from ..models.imports import FileImport, TypingSection, MsrestImportType, ImportType
|
|
10
11
|
from .import_serializer import FileImportSerializer
|
|
11
12
|
|
|
12
13
|
|
|
@@ -26,11 +27,15 @@ def _documentation_string(
|
|
|
26
27
|
return retval
|
|
27
28
|
|
|
28
29
|
|
|
29
|
-
class
|
|
30
|
+
class _ModelSerializer(ABC):
|
|
30
31
|
def __init__(self, code_model: CodeModel, env: Environment) -> None:
|
|
31
32
|
self.code_model = code_model
|
|
32
33
|
self.env = env
|
|
33
34
|
|
|
35
|
+
@abstractmethod
|
|
36
|
+
def imports(self) -> FileImport:
|
|
37
|
+
...
|
|
38
|
+
|
|
34
39
|
def serialize(self) -> str:
|
|
35
40
|
# Generate the models
|
|
36
41
|
template = self.env.get_template("model_container.py.jinja2")
|
|
@@ -41,46 +46,13 @@ class ModelSerializer:
|
|
|
41
46
|
serializer=self,
|
|
42
47
|
)
|
|
43
48
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
self.code_model, "..", MsrestImportType.Module, TypingSection.REGULAR
|
|
48
|
-
)
|
|
49
|
-
for model in self.code_model.model_types:
|
|
50
|
-
file_import.merge(model.imports(is_operation_file=False))
|
|
51
|
-
init_line_parameters = [
|
|
52
|
-
p for p in model.properties if not p.readonly and not p.is_discriminator
|
|
53
|
-
]
|
|
54
|
-
for param in init_line_parameters:
|
|
55
|
-
file_import.merge(param.imports())
|
|
56
|
-
return file_import
|
|
49
|
+
@abstractmethod
|
|
50
|
+
def declare_model(self, model: ModelType) -> str:
|
|
51
|
+
...
|
|
57
52
|
|
|
58
53
|
@staticmethod
|
|
59
|
-
def
|
|
60
|
-
|
|
61
|
-
properties_to_initialize = list(
|
|
62
|
-
{
|
|
63
|
-
p.client_name: p
|
|
64
|
-
for bm in model.parents
|
|
65
|
-
for p in model.properties
|
|
66
|
-
if p not in cast(ModelType, bm).properties
|
|
67
|
-
or p.is_discriminator
|
|
68
|
-
or p.constant
|
|
69
|
-
}.values()
|
|
70
|
-
)
|
|
71
|
-
else:
|
|
72
|
-
properties_to_initialize = model.properties
|
|
73
|
-
return properties_to_initialize
|
|
74
|
-
|
|
75
|
-
def declare_model(self, model: ModelType) -> str:
|
|
76
|
-
basename = (
|
|
77
|
-
"msrest.serialization.Model"
|
|
78
|
-
if self.code_model.options["client_side_validation"]
|
|
79
|
-
else "_serialization.Model"
|
|
80
|
-
)
|
|
81
|
-
if model.parents:
|
|
82
|
-
basename = ", ".join([cast(ModelType, m).name for m in model.parents])
|
|
83
|
-
return f"class {model.name}({basename}):{model.pylint_disable}"
|
|
54
|
+
def escape_dot(s: str):
|
|
55
|
+
return s.replace(".", "\\\\.")
|
|
84
56
|
|
|
85
57
|
@staticmethod
|
|
86
58
|
def input_documentation_string(prop: Property) -> List[str]:
|
|
@@ -94,27 +66,16 @@ class ModelSerializer:
|
|
|
94
66
|
def super_call(self, model: ModelType):
|
|
95
67
|
return f"super().__init__({self.properties_to_pass_to_super(model)})"
|
|
96
68
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
typing = "Optional[str]"
|
|
108
|
-
else:
|
|
109
|
-
typing = "str"
|
|
110
|
-
init_args.append(
|
|
111
|
-
f"self.{prop.client_name} = {discriminator_value} # type: {typing}"
|
|
112
|
-
)
|
|
113
|
-
elif prop.readonly:
|
|
114
|
-
init_args.append(f"self.{prop.client_name} = None")
|
|
115
|
-
elif not prop.constant:
|
|
116
|
-
init_args.append(f"self.{prop.client_name} = {prop.client_name}")
|
|
117
|
-
return init_args
|
|
69
|
+
@staticmethod
|
|
70
|
+
def initialize_discriminator_property(model: ModelType, prop: Property) -> str:
|
|
71
|
+
discriminator_value = (
|
|
72
|
+
f"'{model.discriminator_value}'" if model.discriminator_value else None
|
|
73
|
+
)
|
|
74
|
+
if not discriminator_value:
|
|
75
|
+
typing = "Optional[str]"
|
|
76
|
+
else:
|
|
77
|
+
typing = "str"
|
|
78
|
+
return f"self.{prop.client_name} = {discriminator_value} # type: {typing}"
|
|
118
79
|
|
|
119
80
|
@staticmethod
|
|
120
81
|
def initialize_standard_property(prop: Property):
|
|
@@ -163,3 +124,140 @@ class ModelSerializer:
|
|
|
163
124
|
)
|
|
164
125
|
properties_to_pass_to_super.append("**kwargs")
|
|
165
126
|
return ", ".join(properties_to_pass_to_super)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class MsrestModelSerializer(_ModelSerializer):
|
|
130
|
+
def imports(self) -> FileImport:
|
|
131
|
+
file_import = FileImport()
|
|
132
|
+
file_import.add_msrest_import(
|
|
133
|
+
self.code_model, "..", MsrestImportType.Module, TypingSection.REGULAR
|
|
134
|
+
)
|
|
135
|
+
for model in self.code_model.model_types:
|
|
136
|
+
file_import.merge(model.imports(is_operation_file=False))
|
|
137
|
+
init_line_parameters = [
|
|
138
|
+
p for p in model.properties if not p.readonly and not p.is_discriminator
|
|
139
|
+
]
|
|
140
|
+
for param in init_line_parameters:
|
|
141
|
+
file_import.merge(param.imports())
|
|
142
|
+
return file_import
|
|
143
|
+
|
|
144
|
+
def declare_model(self, model: ModelType) -> str:
|
|
145
|
+
basename = (
|
|
146
|
+
"msrest.serialization.Model"
|
|
147
|
+
if self.code_model.options["client_side_validation"]
|
|
148
|
+
else "_serialization.Model"
|
|
149
|
+
)
|
|
150
|
+
if model.parents:
|
|
151
|
+
basename = ", ".join([cast(ModelType, m).name for m in model.parents])
|
|
152
|
+
return f"class {model.name}({basename}):{model.pylint_disable}"
|
|
153
|
+
|
|
154
|
+
@staticmethod
|
|
155
|
+
def get_properties_to_initialize(model: ModelType) -> List[Property]:
|
|
156
|
+
if model.parents:
|
|
157
|
+
properties_to_initialize = list(
|
|
158
|
+
{
|
|
159
|
+
p.client_name: p
|
|
160
|
+
for bm in model.parents
|
|
161
|
+
for p in model.properties
|
|
162
|
+
if p not in cast(ModelType, bm).properties
|
|
163
|
+
or p.is_discriminator
|
|
164
|
+
or p.constant
|
|
165
|
+
}.values()
|
|
166
|
+
)
|
|
167
|
+
else:
|
|
168
|
+
properties_to_initialize = model.properties
|
|
169
|
+
return properties_to_initialize
|
|
170
|
+
|
|
171
|
+
def initialize_properties(self, model: ModelType) -> List[str]:
|
|
172
|
+
init_args = []
|
|
173
|
+
for prop in self.get_properties_to_initialize(model):
|
|
174
|
+
if prop.is_discriminator:
|
|
175
|
+
init_args.append(self.initialize_discriminator_property(model, prop))
|
|
176
|
+
elif prop.readonly:
|
|
177
|
+
init_args.append(f"self.{prop.client_name} = None")
|
|
178
|
+
elif not prop.constant:
|
|
179
|
+
init_args.append(f"self.{prop.client_name} = {prop.client_name}")
|
|
180
|
+
return init_args
|
|
181
|
+
|
|
182
|
+
@staticmethod
|
|
183
|
+
def declare_property(prop: Property) -> str:
|
|
184
|
+
if prop.flattened_names:
|
|
185
|
+
attribute_key = ".".join(
|
|
186
|
+
_ModelSerializer.escape_dot(n) for n in prop.flattened_names
|
|
187
|
+
)
|
|
188
|
+
else:
|
|
189
|
+
attribute_key = _ModelSerializer.escape_dot(prop.rest_api_name)
|
|
190
|
+
if prop.type.xml_serialization_ctxt:
|
|
191
|
+
xml_metadata = f", 'xml': {{{prop.type.xml_serialization_ctxt}}}"
|
|
192
|
+
else:
|
|
193
|
+
xml_metadata = ""
|
|
194
|
+
return f'"{prop.client_name}": {{"key": "{attribute_key}", "type": "{prop.serialization_type}"{xml_metadata}}},'
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
class DpgModelSerializer(_ModelSerializer):
|
|
198
|
+
def imports(self) -> FileImport:
|
|
199
|
+
file_import = FileImport()
|
|
200
|
+
file_import.add_submodule_import(
|
|
201
|
+
"..",
|
|
202
|
+
"_model_base",
|
|
203
|
+
ImportType.LOCAL,
|
|
204
|
+
TypingSection.REGULAR,
|
|
205
|
+
)
|
|
206
|
+
file_import.add_submodule_import("typing", "overload", ImportType.STDLIB)
|
|
207
|
+
file_import.add_submodule_import("typing", "Mapping", ImportType.STDLIB)
|
|
208
|
+
file_import.add_submodule_import("typing", "Any", ImportType.STDLIB)
|
|
209
|
+
|
|
210
|
+
for model in self.code_model.model_types:
|
|
211
|
+
file_import.merge(model.imports(is_operation_file=False))
|
|
212
|
+
for param in model.properties:
|
|
213
|
+
file_import.merge(param.imports())
|
|
214
|
+
return file_import
|
|
215
|
+
|
|
216
|
+
def declare_model(self, model: ModelType) -> str:
|
|
217
|
+
basename = "_model_base.Model"
|
|
218
|
+
if model.parents:
|
|
219
|
+
basename = ", ".join([cast(ModelType, m).name for m in model.parents])
|
|
220
|
+
if model.discriminator_value:
|
|
221
|
+
basename += f", discriminator='{model.discriminator_value}'"
|
|
222
|
+
return f"class {model.name}({basename}):{model.pylint_disable}"
|
|
223
|
+
|
|
224
|
+
@staticmethod
|
|
225
|
+
def get_properties_to_initialize(model: ModelType) -> List[Property]:
|
|
226
|
+
if model.parents:
|
|
227
|
+
properties_to_declare = [
|
|
228
|
+
p
|
|
229
|
+
for bm in model.parents
|
|
230
|
+
for p in model.properties
|
|
231
|
+
if p not in cast(ModelType, bm).properties
|
|
232
|
+
]
|
|
233
|
+
|
|
234
|
+
else:
|
|
235
|
+
properties_to_declare = model.properties
|
|
236
|
+
if any(p for p in properties_to_declare if p.client_name == "_"):
|
|
237
|
+
raise ValueError("We do not generate anonymous properties")
|
|
238
|
+
return [
|
|
239
|
+
p
|
|
240
|
+
for p in properties_to_declare
|
|
241
|
+
if (not p.is_discriminator or p.is_polymorphic)
|
|
242
|
+
]
|
|
243
|
+
|
|
244
|
+
@staticmethod
|
|
245
|
+
def declare_property(prop: Property) -> List[str]:
|
|
246
|
+
attribute_key = _ModelSerializer.escape_dot(prop.rest_api_name)
|
|
247
|
+
args = []
|
|
248
|
+
if prop.client_name != attribute_key:
|
|
249
|
+
args.append(f'name="{attribute_key}"')
|
|
250
|
+
if prop.readonly:
|
|
251
|
+
args.append("readonly=True")
|
|
252
|
+
if prop.client_default_value is not None:
|
|
253
|
+
args.append(f"default={prop.client_default_value_declaration}")
|
|
254
|
+
|
|
255
|
+
field = "rest_discriminator" if prop.is_discriminator else "rest_field"
|
|
256
|
+
ret = [
|
|
257
|
+
f"{prop.client_name}: {prop.type_annotation()} ="
|
|
258
|
+
f' {field}({", ".join(args)})'
|
|
259
|
+
]
|
|
260
|
+
comment = prop.description(is_operation_file=False).replace('"', '\\"')
|
|
261
|
+
if comment:
|
|
262
|
+
ret.append(f'"""{comment}"""')
|
|
263
|
+
return ret
|