@autorest/python 6.1.6 → 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/codegen/__init__.py +4 -2
- package/autorest/codegen/models/__init__.py +1 -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 +21 -0
- package/autorest/codegen/models/operation_group.py +6 -7
- package/autorest/codegen/models/parameter.py +37 -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 +12 -2
- package/autorest/codegen/serializers/builder_serializer.py +42 -20
- package/autorest/codegen/serializers/client_serializer.py +3 -4
- package/autorest/codegen/serializers/general_serializer.py +4 -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/package.json +9 -10
- package/ChangeLog.md +0 -1299
|
@@ -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
|