@autorest/python 5.12.4 → 5.13.0
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/ChangeLog.md +173 -109
- package/autorest/black/__init__.py +7 -1
- package/autorest/codegen/__init__.py +12 -2
- package/autorest/codegen/models/__init__.py +2 -1
- package/autorest/codegen/models/client.py +22 -19
- package/autorest/codegen/models/constant_schema.py +0 -4
- package/autorest/codegen/models/credential_schema.py +3 -3
- package/autorest/codegen/models/dictionary_schema.py +1 -1
- package/autorest/codegen/models/enum_schema.py +2 -2
- package/autorest/codegen/models/imports.py +90 -50
- package/autorest/codegen/models/list_schema.py +1 -1
- package/autorest/codegen/models/lro_operation.py +15 -9
- package/autorest/codegen/models/object_schema.py +2 -2
- package/autorest/codegen/models/operation.py +39 -30
- package/autorest/codegen/models/operation_group.py +5 -14
- package/autorest/codegen/models/paging_operation.py +9 -9
- package/autorest/codegen/models/parameter.py +37 -11
- package/autorest/codegen/models/parameter_list.py +11 -4
- package/autorest/codegen/models/primitive_schemas.py +2 -2
- package/autorest/codegen/models/property.py +1 -1
- package/autorest/codegen/models/request_builder.py +7 -6
- package/autorest/codegen/models/request_builder_parameter.py +5 -0
- package/autorest/codegen/models/request_builder_parameter_list.py +1 -0
- package/autorest/codegen/models/schema_response.py +1 -1
- package/autorest/codegen/serializers/__init__.py +75 -71
- package/autorest/codegen/serializers/builder_serializer.py +68 -37
- package/autorest/codegen/serializers/client_serializer.py +14 -3
- package/autorest/codegen/serializers/general_serializer.py +7 -7
- package/autorest/codegen/serializers/import_serializer.py +44 -46
- package/autorest/codegen/serializers/metadata_serializer.py +12 -10
- package/autorest/codegen/serializers/utils.py +5 -1
- package/autorest/codegen/templates/config.py.jinja2 +2 -7
- package/autorest/codegen/templates/lro_operation.py.jinja2 +3 -1
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +2 -0
- package/autorest/codegen/templates/operation.py.jinja2 +8 -2
- package/autorest/codegen/templates/operation_group.py.jinja2 +2 -1
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -0
- package/autorest/codegen/templates/operation_tools.jinja2 +3 -2
- package/autorest/codegen/templates/paging_operation.py.jinja2 +3 -1
- package/autorest/codegen/templates/request_builder.py.jinja2 +2 -7
- package/autorest/codegen/templates/service_client.py.jinja2 +1 -1
- package/autorest/multiapi/models/imports.py +1 -1
- package/autorest/multiapi/serializers/import_serializer.py +1 -1
- package/autorest/namer/name_converter.py +1 -1
- package/package.json +2 -2
- package/run-python3.js +1 -7
- package/venvtools.py +2 -2
|
@@ -27,12 +27,16 @@ from ..models import (
|
|
|
27
27
|
SchemaResponse,
|
|
28
28
|
IOSchema,
|
|
29
29
|
ParameterStyle,
|
|
30
|
+
ParameterLocation
|
|
30
31
|
)
|
|
31
32
|
from . import utils
|
|
32
33
|
|
|
33
34
|
T = TypeVar("T")
|
|
34
35
|
OrderedSet = Dict[T, None]
|
|
35
36
|
|
|
37
|
+
def _escape_str(input_str: str) -> str:
|
|
38
|
+
replace = input_str.replace("'", "\\'")
|
|
39
|
+
return f'"{replace}"'
|
|
36
40
|
|
|
37
41
|
def _improve_json_string(template_representation: str) -> Any:
|
|
38
42
|
origin = template_representation.split('\n')
|
|
@@ -110,7 +114,7 @@ def _pop_parameters_kwarg(
|
|
|
110
114
|
function_name: str,
|
|
111
115
|
kwarg_name: str,
|
|
112
116
|
) -> str:
|
|
113
|
-
return f'{function_name}_parameters = kwargs.pop("{kwarg_name}", {{}}) # type: Dict[str, Any]'
|
|
117
|
+
return f'_{function_name}_parameters = kwargs.pop("{kwarg_name}", {{}}) # type: Dict[str, Any]'
|
|
114
118
|
|
|
115
119
|
def _serialize_grouped_body(builder) -> List[str]:
|
|
116
120
|
retval: List[str] = []
|
|
@@ -149,12 +153,21 @@ def _serialize_flattened_body(builder) -> List[str]:
|
|
|
149
153
|
return retval
|
|
150
154
|
|
|
151
155
|
def _content_type_docstring(builder) -> str:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
+
content_types = [f'"{c}"' for c in builder.parameters.content_types]
|
|
157
|
+
if len(content_types) == 2:
|
|
158
|
+
possible_values_str = " or ".join(content_types)
|
|
159
|
+
else:
|
|
160
|
+
possible_values_str = ", ".join(
|
|
161
|
+
content_types[: len(content_types) - 1]
|
|
162
|
+
) + f", and {content_types[-1]}"
|
|
163
|
+
default_value = next(
|
|
164
|
+
p for p in builder.parameters.method if p.rest_api_name == "Content-Type"
|
|
165
|
+
).default_value_declaration
|
|
166
|
+
return (
|
|
167
|
+
":keyword content_type: Media type of the body sent to the API. " +
|
|
168
|
+
f"Possible values are: {possible_values_str}. " +
|
|
169
|
+
f"Default value is {default_value}."
|
|
156
170
|
)
|
|
157
|
-
return content_type_str
|
|
158
171
|
|
|
159
172
|
class _BuilderSerializerProtocol(ABC):
|
|
160
173
|
@property
|
|
@@ -180,11 +193,6 @@ class _BuilderSerializerProtocol(ABC):
|
|
|
180
193
|
"""Whether you want inline type hints. If false, your type hints will be commented'"""
|
|
181
194
|
...
|
|
182
195
|
|
|
183
|
-
@abstractmethod
|
|
184
|
-
def _method_signature(self, builder) -> str:
|
|
185
|
-
"""Signature of the builder. Does not include return type annotation"""
|
|
186
|
-
...
|
|
187
|
-
|
|
188
196
|
@abstractmethod
|
|
189
197
|
def _response_type_annotation(self, builder, modify_if_head_as_boolean: bool = True) -> str:
|
|
190
198
|
"""The mypy type annotation for the response"""
|
|
@@ -266,20 +274,22 @@ class _BuilderBaseSerializer(_BuilderSerializerProtocol): # pylint: disable=abs
|
|
|
266
274
|
def _cls_docstring_rtype(self) -> str:
|
|
267
275
|
return "" if self.code_model.options["version_tolerant"] else " or the result of cls(response)"
|
|
268
276
|
|
|
269
|
-
def _method_signature(self, builder) -> str:
|
|
277
|
+
def _method_signature(self, builder: Operation, response_type_annotation: str) -> str:
|
|
270
278
|
return utils.serialize_method(
|
|
271
279
|
function_def=self._function_definition,
|
|
272
280
|
method_name=builder.name,
|
|
273
281
|
is_in_class=self._is_in_class,
|
|
274
282
|
method_param_signatures=builder.parameters.method_signature(self._want_inline_type_hints),
|
|
283
|
+
ignore_inconsistent_return_statements=(response_type_annotation == "None")
|
|
275
284
|
)
|
|
276
285
|
|
|
277
286
|
def _response_type_annotation_wrapper(self, builder) -> List[str]:
|
|
278
287
|
return []
|
|
279
288
|
|
|
280
289
|
def method_signature_and_response_type_annotation(self, builder) -> str:
|
|
281
|
-
method_signature = self._method_signature(builder)
|
|
282
290
|
response_type_annotation = self._response_type_annotation(builder)
|
|
291
|
+
# want pre-wrapped response type. As long as it's None, pylint will get mad about inconsistent return types
|
|
292
|
+
method_signature = self._method_signature(builder, response_type_annotation)
|
|
283
293
|
for wrapper in self._response_type_annotation_wrapper(builder)[::-1]:
|
|
284
294
|
response_type_annotation = f"{wrapper}[{response_type_annotation}]"
|
|
285
295
|
return self._method_signature_and_response_type_annotation_template(method_signature, response_type_annotation)
|
|
@@ -304,13 +314,14 @@ class _BuilderBaseSerializer(_BuilderSerializerProtocol): # pylint: disable=abs
|
|
|
304
314
|
description_list.append(
|
|
305
315
|
f":{param.docstring_type_keyword} { param.serialized_name }: { param.docstring_type }"
|
|
306
316
|
)
|
|
307
|
-
try:
|
|
308
|
-
request_builder: RequestBuilder = cast(Operation, builder).request_builder
|
|
309
|
-
except AttributeError:
|
|
310
|
-
request_builder = cast(RequestBuilder, builder)
|
|
311
317
|
|
|
312
|
-
if len(
|
|
313
|
-
description_list
|
|
318
|
+
if len(builder.parameters.content_types) > 1:
|
|
319
|
+
description_list = [
|
|
320
|
+
_content_type_docstring(builder) if l.startswith(":keyword content_type:") else l
|
|
321
|
+
for l in description_list
|
|
322
|
+
]
|
|
323
|
+
if not any(l for l in description_list if l.startswith(":keyword content_type:")):
|
|
324
|
+
description_list.append(_content_type_docstring(builder))
|
|
314
325
|
return description_list
|
|
315
326
|
|
|
316
327
|
def param_description_and_response_docstring(self, builder) -> List[str]:
|
|
@@ -402,7 +413,7 @@ class _BuilderBaseSerializer(_BuilderSerializerProtocol): # pylint: disable=abs
|
|
|
402
413
|
def _serialize_parameter(
|
|
403
414
|
self, param: Parameter, function_name: str
|
|
404
415
|
) -> List[str]:
|
|
405
|
-
set_parameter = "{}_parameters['{}'] = {}".format(
|
|
416
|
+
set_parameter = "_{}_parameters['{}'] = {}".format(
|
|
406
417
|
function_name,
|
|
407
418
|
param.rest_api_name,
|
|
408
419
|
utils.build_serialize_data_call(param, function_name, self.serializer_name)
|
|
@@ -499,11 +510,11 @@ class _RequestBuilderBaseSerializer(_BuilderBaseSerializer): # pylint: disable=
|
|
|
499
510
|
def create_http_request(self, builder) -> List[str]:
|
|
500
511
|
retval = ["return HttpRequest("]
|
|
501
512
|
retval.append(f' method="{builder.method}",')
|
|
502
|
-
retval.append(" url=
|
|
513
|
+
retval.append(" url=_url,")
|
|
503
514
|
if builder.parameters.query:
|
|
504
|
-
retval.append(" params=
|
|
515
|
+
retval.append(" params=_query_parameters,")
|
|
505
516
|
if builder.parameters.headers:
|
|
506
|
-
retval.append(" headers=
|
|
517
|
+
retval.append(" headers=_header_parameters,")
|
|
507
518
|
if builder.parameters.has_body:
|
|
508
519
|
retval.extend([
|
|
509
520
|
f" {body_kwarg}={body_kwarg},"
|
|
@@ -533,6 +544,13 @@ class _RequestBuilderBaseSerializer(_BuilderBaseSerializer): # pylint: disable=
|
|
|
533
544
|
))
|
|
534
545
|
return retval
|
|
535
546
|
|
|
547
|
+
def construct_url(self, builder) -> str:
|
|
548
|
+
if any(o for o in ["low_level_client", "version_tolerant"] if self.code_model.options.get(o)):
|
|
549
|
+
url_value = _escape_str(builder.url)
|
|
550
|
+
else:
|
|
551
|
+
url_value = f'kwargs.pop("template_url", {_escape_str(builder.url)})'
|
|
552
|
+
return f"_url = {url_value}{' # pylint: disable=line-too-long' if len(url_value) > 114 else ''}"
|
|
553
|
+
|
|
536
554
|
class RequestBuilderGenericSerializer(_RequestBuilderBaseSerializer):
|
|
537
555
|
@property
|
|
538
556
|
def _want_inline_type_hints(self) -> bool:
|
|
@@ -711,7 +729,7 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
|
|
|
711
729
|
)
|
|
712
730
|
ser_ctxt_name = "serialization_ctxt"
|
|
713
731
|
ser_ctxt = builder.parameters.body[0].xml_serialization_ctxt if send_xml else None
|
|
714
|
-
if ser_ctxt:
|
|
732
|
+
if ser_ctxt and self.code_model.options["models_mode"]:
|
|
715
733
|
retval.append(f'{ser_ctxt_name} = {{"xml": {{{ser_ctxt}}}}}')
|
|
716
734
|
serialize_body_call = self._serialize_body_call(
|
|
717
735
|
builder,
|
|
@@ -781,6 +799,7 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
|
|
|
781
799
|
builder,
|
|
782
800
|
request_builder: RequestBuilder,
|
|
783
801
|
template_url: Optional[str] = None,
|
|
802
|
+
is_next_request: bool = False,
|
|
784
803
|
) -> List[str]:
|
|
785
804
|
retval = []
|
|
786
805
|
if len(builder.body_kwargs_to_pass_to_request_builder) > 1:
|
|
@@ -820,6 +839,16 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
|
|
|
820
839
|
parameter.serialized_name not in builder.body_kwargs_to_pass_to_request_builder
|
|
821
840
|
):
|
|
822
841
|
continue
|
|
842
|
+
if (
|
|
843
|
+
is_next_request and
|
|
844
|
+
not bool(builder.next_request_builder) and
|
|
845
|
+
not self.code_model.options["reformat_next_link"] and
|
|
846
|
+
parameter.location == ParameterLocation.Query
|
|
847
|
+
):
|
|
848
|
+
# if we don't want to reformat query parameters for next link calls
|
|
849
|
+
# in paging operations with a single swagger operation defintion,
|
|
850
|
+
# we skip passing query params when building the next request
|
|
851
|
+
continue
|
|
823
852
|
high_level_name = cast(RequestBuilderParameter, parameter).name_in_high_level_operation
|
|
824
853
|
retval.append(f" {parameter.serialized_name}={high_level_name},")
|
|
825
854
|
if not self.code_model.options["version_tolerant"]:
|
|
@@ -986,7 +1015,8 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
|
|
|
986
1015
|
|
|
987
1016
|
@staticmethod
|
|
988
1017
|
def get_metadata_url(builder) -> str:
|
|
989
|
-
|
|
1018
|
+
url = _escape_str(builder.request_builder.url)
|
|
1019
|
+
return f"{builder.python_name}.metadata = {{'url': { url }}} # type: ignore"
|
|
990
1020
|
|
|
991
1021
|
class _SyncOperationBaseSerializer(_OperationBaseSerializer): # pylint: disable=abstract-method
|
|
992
1022
|
@property
|
|
@@ -1065,11 +1095,13 @@ class _PagingOperationBaseSerializer(_OperationBaseSerializer): # pylint: disab
|
|
|
1065
1095
|
else:
|
|
1066
1096
|
request_builder = builder.request_builder
|
|
1067
1097
|
template_url = "next_link"
|
|
1098
|
+
|
|
1068
1099
|
request_builder = builder.next_request_builder or builder.request_builder
|
|
1069
1100
|
return self._call_request_builder_helper(
|
|
1070
1101
|
builder,
|
|
1071
1102
|
request_builder,
|
|
1072
1103
|
template_url=template_url,
|
|
1104
|
+
is_next_request=True
|
|
1073
1105
|
)
|
|
1074
1106
|
|
|
1075
1107
|
def _prepare_request_callback(self, builder) -> List[str]:
|
|
@@ -1114,7 +1146,7 @@ class _PagingOperationBaseSerializer(_OperationBaseSerializer): # pylint: disab
|
|
|
1114
1146
|
deserialized = (
|
|
1115
1147
|
f'self._deserialize("{response.serialization_type}", pipeline_response)'
|
|
1116
1148
|
if self.code_model.options["models_mode"] else
|
|
1117
|
-
"
|
|
1149
|
+
"pipeline_response.http_response.json()"
|
|
1118
1150
|
)
|
|
1119
1151
|
retval.append(f" deserialized = {deserialized}")
|
|
1120
1152
|
item_name = builder.item_name(self.code_model)
|
|
@@ -1137,10 +1169,11 @@ class _PagingOperationBaseSerializer(_OperationBaseSerializer): # pylint: disab
|
|
|
1137
1169
|
retval = [f"{self._def} get_next(next_link=None):"]
|
|
1138
1170
|
retval.append(" request = prepare_request(next_link)")
|
|
1139
1171
|
retval.append("")
|
|
1140
|
-
retval.append(
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
)
|
|
1172
|
+
retval.append(f" pipeline_response = {self._call_method}self._client._pipeline.run( # pylint: disable=protected-access")
|
|
1173
|
+
retval.append(" request,")
|
|
1174
|
+
retval.append(f" stream={builder.is_stream_response},")
|
|
1175
|
+
retval.append(" **kwargs")
|
|
1176
|
+
retval.append(" )")
|
|
1144
1177
|
retval.append(" response = pipeline_response.http_response")
|
|
1145
1178
|
retval.append("")
|
|
1146
1179
|
retval.extend([
|
|
@@ -1234,7 +1267,7 @@ class _LROOperationBaseSerializer(_OperationBaseSerializer): # pylint: disable=
|
|
|
1234
1267
|
"Pass in False for this operation to not poll, or pass in your own initialized polling object for a"
|
|
1235
1268
|
" personal polling strategy."
|
|
1236
1269
|
)
|
|
1237
|
-
retval.append(f":paramtype polling: bool or ~{self._polling_method_type}")
|
|
1270
|
+
retval.append(f":paramtype polling: bool or ~azure.core.polling.{self._polling_method_type}")
|
|
1238
1271
|
retval.append(
|
|
1239
1272
|
":keyword int polling_interval: Default waiting time between two polls for LRO operations "
|
|
1240
1273
|
"if no Retry-After header is present."
|
|
@@ -1287,9 +1320,8 @@ class _LROOperationBaseSerializer(_OperationBaseSerializer): # pylint: disable=
|
|
|
1287
1320
|
retval.append(" client=self._client,")
|
|
1288
1321
|
retval.append(" deserialization_callback=get_long_running_output")
|
|
1289
1322
|
retval.append(" )")
|
|
1290
|
-
retval.append("else:")
|
|
1291
1323
|
retval.append(
|
|
1292
|
-
f"
|
|
1324
|
+
f"return {self._poller(builder)}"
|
|
1293
1325
|
"(self._client, raw_result, get_long_running_output, polling_method)"
|
|
1294
1326
|
)
|
|
1295
1327
|
return retval
|
|
@@ -1335,7 +1367,7 @@ class _SyncLROOperationBaseSerializer(_LROOperationBaseSerializer, _SyncOperatio
|
|
|
1335
1367
|
|
|
1336
1368
|
@property
|
|
1337
1369
|
def _polling_method_type(self):
|
|
1338
|
-
return "
|
|
1370
|
+
return "PollingMethod"
|
|
1339
1371
|
|
|
1340
1372
|
def _poller(self, builder) -> str:
|
|
1341
1373
|
return builder.get_poller(async_mode=False)
|
|
@@ -1368,7 +1400,7 @@ class AsyncLROOperationSerializer(_LROOperationBaseSerializer, AsyncOperationSer
|
|
|
1368
1400
|
|
|
1369
1401
|
@property
|
|
1370
1402
|
def _polling_method_type(self):
|
|
1371
|
-
return "
|
|
1403
|
+
return "AsyncPollingMethod"
|
|
1372
1404
|
|
|
1373
1405
|
def _poller(self, builder) -> str:
|
|
1374
1406
|
return builder.get_poller(async_mode=True)
|
|
@@ -1383,8 +1415,7 @@ class _LROPagingOperationBaseSerializer(_LROOperationBaseSerializer, _PagingOper
|
|
|
1383
1415
|
retval.append(f" {self._def} internal_get_next(next_link=None):")
|
|
1384
1416
|
retval.append(" if next_link is None:")
|
|
1385
1417
|
retval.append(" return pipeline_response")
|
|
1386
|
-
retval.append("
|
|
1387
|
-
retval.append(f" return {self._call_method}get_next(next_link)")
|
|
1418
|
+
retval.append(f" return {self._call_method}get_next(next_link)")
|
|
1388
1419
|
retval.append("")
|
|
1389
1420
|
retval.append(f" return {self._pager(builder)}(")
|
|
1390
1421
|
retval.append(" internal_get_next, extract_data")
|
|
@@ -44,9 +44,12 @@ class ClientSerializer:
|
|
|
44
44
|
base_class = f"{class_name}OperationsMixin"
|
|
45
45
|
elif not (async_mode or self.is_python3_file):
|
|
46
46
|
base_class = "object"
|
|
47
|
+
disable = ""
|
|
48
|
+
if len(self.code_model.operation_groups) > 6:
|
|
49
|
+
disable = " # pylint: disable=too-many-instance-attributes"
|
|
47
50
|
if base_class:
|
|
48
|
-
return f"class {class_name}({base_class}):"
|
|
49
|
-
return f"class {class_name}:"
|
|
51
|
+
return f"class {class_name}({base_class}):{disable}"
|
|
52
|
+
return f"class {class_name}:{disable}"
|
|
50
53
|
|
|
51
54
|
def property_descriptions(self, async_mode: bool) -> List[str]:
|
|
52
55
|
retval: List[str] = []
|
|
@@ -113,7 +116,7 @@ class ClientSerializer:
|
|
|
113
116
|
method_name=self.code_model.send_request_name,
|
|
114
117
|
is_in_class=True,
|
|
115
118
|
method_param_signatures=self.code_model.service_client.send_request_signature(
|
|
116
|
-
async_mode
|
|
119
|
+
async_mode or self.is_python3_file
|
|
117
120
|
),
|
|
118
121
|
)
|
|
119
122
|
|
|
@@ -227,3 +230,11 @@ class ConfigSerializer:
|
|
|
227
230
|
for p in self.code_model.global_parameters.config_method
|
|
228
231
|
if p.required and not p.constant
|
|
229
232
|
]
|
|
233
|
+
|
|
234
|
+
def property_descriptions(self) -> List[str]:
|
|
235
|
+
retval: List[str] = []
|
|
236
|
+
for p in self.code_model.global_parameters.config_method:
|
|
237
|
+
retval.append(f":{p.description_keyword} {p.serialized_name}: {p.description}")
|
|
238
|
+
retval.append(f":{p.docstring_type_keyword} {p.serialized_name}: {p.docstring_type}")
|
|
239
|
+
retval.append('"""')
|
|
240
|
+
return retval
|
|
@@ -10,17 +10,17 @@ from .client_serializer import ClientSerializer, ConfigSerializer
|
|
|
10
10
|
|
|
11
11
|
def config_imports(code_model, global_parameters: ParameterList, async_mode: bool) -> FileImport:
|
|
12
12
|
file_import = FileImport()
|
|
13
|
-
file_import.
|
|
14
|
-
file_import.
|
|
15
|
-
file_import.
|
|
13
|
+
file_import.add_submodule_import("azure.core.configuration", "Configuration", ImportType.AZURECORE)
|
|
14
|
+
file_import.add_submodule_import("azure.core.pipeline", "policies", ImportType.AZURECORE)
|
|
15
|
+
file_import.add_submodule_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
16
16
|
if code_model.options["package_version"]:
|
|
17
|
-
file_import.
|
|
17
|
+
file_import.add_submodule_import(".._version" if async_mode else "._version", "VERSION", ImportType.LOCAL)
|
|
18
18
|
for gp in global_parameters:
|
|
19
19
|
file_import.merge(gp.imports())
|
|
20
20
|
if code_model.options["azure_arm"]:
|
|
21
21
|
policy = "AsyncARMChallengeAuthenticationPolicy" if async_mode else "ARMChallengeAuthenticationPolicy"
|
|
22
|
-
file_import.
|
|
23
|
-
file_import.
|
|
22
|
+
file_import.add_submodule_import("azure.mgmt.core.policies", "ARMHttpLoggingPolicy", ImportType.AZURECORE)
|
|
23
|
+
file_import.add_submodule_import("azure.mgmt.core.policies", policy, ImportType.AZURECORE)
|
|
24
24
|
return file_import
|
|
25
25
|
|
|
26
26
|
|
|
@@ -71,7 +71,7 @@ class GeneralSerializer:
|
|
|
71
71
|
# configure imports
|
|
72
72
|
file_import = FileImport()
|
|
73
73
|
if self.code_model.need_request_converter:
|
|
74
|
-
file_import.
|
|
74
|
+
file_import.add_submodule_import(
|
|
75
75
|
"azure.core.pipeline.transport",
|
|
76
76
|
"HttpRequest",
|
|
77
77
|
ImportType.AZURECORE,
|
|
@@ -4,75 +4,73 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from copy import deepcopy
|
|
7
|
-
from typing import
|
|
8
|
-
from ..models.imports import ImportType, FileImport, TypingSection
|
|
7
|
+
from typing import List
|
|
8
|
+
from ..models.imports import ImportType, FileImport, ImportModel, TypingSection
|
|
9
9
|
|
|
10
10
|
def _serialize_package(
|
|
11
|
-
|
|
11
|
+
imports: List[ImportModel], delimiter: str
|
|
12
12
|
) -> str:
|
|
13
13
|
buffer = []
|
|
14
|
-
if
|
|
15
|
-
buffer.append(f"import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
]))
|
|
22
|
-
)
|
|
23
|
-
)
|
|
14
|
+
if any(i for i in imports if i.submodule_name is None):
|
|
15
|
+
buffer.append(f"import {imports[0].module_name}")
|
|
16
|
+
else:
|
|
17
|
+
import_str = ", ".join(sorted([
|
|
18
|
+
f"{i.submodule_name} as {i.alias}" if i.alias else i.submodule_name for i in imports # type: ignore
|
|
19
|
+
]))
|
|
20
|
+
buffer.append(f"from {imports[0].module_name} import {import_str}")
|
|
24
21
|
return delimiter.join(buffer)
|
|
25
22
|
|
|
26
|
-
def
|
|
23
|
+
def _serialize_import_type(imports: List[ImportModel], delimiter: str) -> str:
|
|
27
24
|
"""Serialize a given import type."""
|
|
28
25
|
import_list = []
|
|
29
|
-
for
|
|
30
|
-
|
|
31
|
-
import_list.append(_serialize_package(
|
|
26
|
+
for module_name in sorted(set(i.module_name for i in imports)):
|
|
27
|
+
|
|
28
|
+
import_list.append(_serialize_package([
|
|
29
|
+
i for i in imports if i.module_name == module_name
|
|
30
|
+
], delimiter))
|
|
32
31
|
return delimiter.join(import_list)
|
|
33
32
|
|
|
34
33
|
def _get_import_clauses(
|
|
35
|
-
imports:
|
|
34
|
+
imports: List[ImportModel], delimiter: str
|
|
36
35
|
) -> List[str]:
|
|
37
36
|
import_clause = []
|
|
38
37
|
for import_type in ImportType:
|
|
39
|
-
if import_type
|
|
40
|
-
|
|
38
|
+
imports_with_import_type = [i for i in imports if i.import_type == import_type]
|
|
39
|
+
if imports_with_import_type:
|
|
40
|
+
import_clause.append(_serialize_import_type(imports_with_import_type, delimiter))
|
|
41
41
|
return import_clause
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
class FileImportSerializer:
|
|
45
45
|
def __init__(self, file_import: FileImport, is_python3_file: bool, async_mode: bool = False) -> None:
|
|
46
|
-
self.
|
|
46
|
+
self.file_import = file_import
|
|
47
47
|
self.is_python3_file = is_python3_file
|
|
48
48
|
self.async_mode = async_mode
|
|
49
49
|
|
|
50
|
-
def
|
|
51
|
-
switched_dictionary = {}
|
|
52
|
-
switched_dictionary[new_key] = self._file_import.imports[TypingSection.CONDITIONAL]
|
|
53
|
-
return switched_dictionary
|
|
54
|
-
|
|
55
|
-
def _get_imports_dict(self, baseline_typing_section: TypingSection, add_conditional_typing: bool):
|
|
50
|
+
def _get_imports_list(self, baseline_typing_section: TypingSection, add_conditional_typing: bool):
|
|
56
51
|
# If this is a python 3 file, our regular imports include the CONDITIONAL category
|
|
57
52
|
# If this is not a python 3 file, our typing imports include the CONDITIONAL category
|
|
58
|
-
file_import_copy = deepcopy(self.
|
|
59
|
-
if add_conditional_typing and
|
|
53
|
+
file_import_copy = deepcopy(self.file_import)
|
|
54
|
+
if add_conditional_typing and any(
|
|
55
|
+
self.file_import.get_imports_from_section(TypingSection.CONDITIONAL)
|
|
56
|
+
):
|
|
60
57
|
# we switch the TypingSection key for the CONDITIONAL typing imports so we can merge
|
|
61
58
|
# the imports together
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return file_import_copy.
|
|
59
|
+
for i in file_import_copy.imports:
|
|
60
|
+
if i.typing_section == TypingSection.CONDITIONAL:
|
|
61
|
+
i.typing_section = baseline_typing_section
|
|
62
|
+
return file_import_copy.get_imports_from_section(baseline_typing_section)
|
|
66
63
|
|
|
67
64
|
def _add_type_checking_import(self):
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
)
|
|
72
|
-
|
|
65
|
+
any_typing = any(self.file_import.get_imports_from_section(TypingSection.TYPING))
|
|
66
|
+
conditional_and_not_py3 = not self.is_python3_file and any(
|
|
67
|
+
self.file_import.get_imports_from_section(TypingSection.CONDITIONAL)
|
|
68
|
+
)
|
|
69
|
+
if any_typing or conditional_and_not_py3:
|
|
70
|
+
self.file_import.add_submodule_import("typing", "TYPE_CHECKING", ImportType.STDLIB)
|
|
73
71
|
|
|
74
72
|
def _get_typing_definitions(self) -> str:
|
|
75
|
-
if not self.
|
|
73
|
+
if not self.file_import.type_definitions:
|
|
76
74
|
return ""
|
|
77
75
|
spacing = "" if self.is_python3_file else " "
|
|
78
76
|
declarations: List[str] = [f"\n{spacing}T = TypeVar('T')"]
|
|
@@ -82,27 +80,27 @@ class FileImportSerializer:
|
|
|
82
80
|
type_name,
|
|
83
81
|
values[1] if self.async_mode else values[0]
|
|
84
82
|
)
|
|
85
|
-
for type_name, values in self.
|
|
83
|
+
for type_name, values in self.file_import.type_definitions.items()
|
|
86
84
|
])
|
|
87
85
|
return "\n".join(declarations)
|
|
88
86
|
|
|
89
87
|
def __str__(self) -> str:
|
|
90
88
|
self._add_type_checking_import()
|
|
91
89
|
regular_imports = ""
|
|
92
|
-
|
|
90
|
+
regular_imports_list = self._get_imports_list(
|
|
93
91
|
baseline_typing_section=TypingSection.REGULAR, add_conditional_typing=self.is_python3_file
|
|
94
92
|
)
|
|
95
93
|
|
|
96
|
-
if
|
|
94
|
+
if regular_imports_list:
|
|
97
95
|
regular_imports = "\n\n".join(
|
|
98
|
-
_get_import_clauses(
|
|
96
|
+
_get_import_clauses(regular_imports_list, "\n")
|
|
99
97
|
)
|
|
100
98
|
|
|
101
99
|
typing_imports = ""
|
|
102
|
-
|
|
100
|
+
typing_imports_list = self._get_imports_list(
|
|
103
101
|
baseline_typing_section=TypingSection.TYPING, add_conditional_typing=not self.is_python3_file
|
|
104
102
|
)
|
|
105
|
-
if
|
|
103
|
+
if typing_imports_list:
|
|
106
104
|
typing_imports += "\n\nif TYPE_CHECKING:\n # pylint: disable=unused-import,ungrouped-imports\n "
|
|
107
|
-
typing_imports += "\n\n ".join(_get_import_clauses(
|
|
105
|
+
typing_imports += "\n\n ".join(_get_import_clauses(typing_imports_list, "\n "))
|
|
108
106
|
return regular_imports + typing_imports + self._get_typing_definitions()
|
|
@@ -62,7 +62,7 @@ def _mixin_imports(mixin_operation_group: Optional[OperationGroup]) -> Tuple[Opt
|
|
|
62
62
|
sync_mixin_imports = mixin_operation_group.imports_for_multiapi(async_mode=False)
|
|
63
63
|
async_mixin_imports = mixin_operation_group.imports_for_multiapi(async_mode=True)
|
|
64
64
|
|
|
65
|
-
return _json_serialize_imports(sync_mixin_imports.
|
|
65
|
+
return _json_serialize_imports(sync_mixin_imports.to_dict()), _json_serialize_imports(async_mixin_imports.to_dict())
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
class MetadataSerializer:
|
|
@@ -102,20 +102,22 @@ class MetadataSerializer:
|
|
|
102
102
|
file_import = FileImport()
|
|
103
103
|
for gp in global_parameters:
|
|
104
104
|
file_import.merge(gp.imports())
|
|
105
|
-
file_import.
|
|
106
|
-
file_import.
|
|
107
|
-
file_import.
|
|
105
|
+
file_import.add_submodule_import("azure.profiles", "KnownProfiles", import_type=ImportType.AZURECORE)
|
|
106
|
+
file_import.add_submodule_import("azure.profiles", "ProfileDefinition", import_type=ImportType.AZURECORE)
|
|
107
|
+
file_import.add_submodule_import(
|
|
108
108
|
"azure.profiles.multiapiclient", "MultiApiClientMixin", import_type=ImportType.AZURECORE
|
|
109
109
|
)
|
|
110
|
-
file_import.
|
|
110
|
+
file_import.add_submodule_import(
|
|
111
|
+
"._configuration", f"{self.code_model.class_name}Configuration", ImportType.LOCAL
|
|
112
|
+
)
|
|
111
113
|
# api_version and potentially endpoint require Optional typing
|
|
112
|
-
file_import.
|
|
114
|
+
file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
113
115
|
if mixin_operation_group:
|
|
114
|
-
file_import.
|
|
116
|
+
file_import.add_submodule_import(
|
|
115
117
|
"._operations_mixin", f"{self.code_model.class_name}OperationsMixin", ImportType.LOCAL
|
|
116
118
|
)
|
|
117
119
|
file_import.merge(self.code_model.service_client.imports_for_multiapi(async_mode=async_mode))
|
|
118
|
-
return _json_serialize_imports(file_import.
|
|
120
|
+
return _json_serialize_imports(file_import.to_dict())
|
|
119
121
|
|
|
120
122
|
def serialize(self) -> str:
|
|
121
123
|
def _is_lro(operation):
|
|
@@ -179,10 +181,10 @@ class MetadataSerializer:
|
|
|
179
181
|
sync_client_imports=sync_client_imports,
|
|
180
182
|
async_client_imports=async_client_imports,
|
|
181
183
|
sync_config_imports=_json_serialize_imports(
|
|
182
|
-
config_imports(self.code_model, self.code_model.global_parameters, async_mode=False).
|
|
184
|
+
config_imports(self.code_model, self.code_model.global_parameters, async_mode=False).to_dict()
|
|
183
185
|
),
|
|
184
186
|
async_config_imports=_json_serialize_imports(
|
|
185
|
-
config_imports(self.code_model, async_global_parameters, async_mode=True).
|
|
187
|
+
config_imports(self.code_model, async_global_parameters, async_mode=True).to_dict()
|
|
186
188
|
),
|
|
187
189
|
get_async_operation_serializer=functools.partial(
|
|
188
190
|
get_operation_serializer, code_model=self.code_model, async_mode=True, is_python3_file=True
|
|
@@ -13,9 +13,13 @@ def serialize_method(
|
|
|
13
13
|
method_name: str,
|
|
14
14
|
is_in_class: bool,
|
|
15
15
|
method_param_signatures: List[str],
|
|
16
|
+
ignore_inconsistent_return_statements: bool = False,
|
|
16
17
|
):
|
|
17
18
|
lines: List[str] = []
|
|
18
|
-
|
|
19
|
+
first_line = f"{function_def} {method_name}("
|
|
20
|
+
if ignore_inconsistent_return_statements:
|
|
21
|
+
first_line += " # pylint: disable=inconsistent-return-statements"
|
|
22
|
+
lines.append(first_line)
|
|
19
23
|
if is_in_class:
|
|
20
24
|
lines.append(" self,")
|
|
21
25
|
lines.extend([
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
VERSION = "unknown"
|
|
12
12
|
{% endif %}
|
|
13
13
|
|
|
14
|
-
class {{ code_model.class_name }}Configuration(Configuration):
|
|
14
|
+
class {{ code_model.class_name }}Configuration(Configuration): # pylint: disable=too-many-instance-attributes
|
|
15
15
|
"""Configuration for {{ code_model.class_name }}.
|
|
16
16
|
|
|
17
17
|
Note that all parameters used to create this instance are saved as instance
|
|
@@ -19,12 +19,7 @@ class {{ code_model.class_name }}Configuration(Configuration):
|
|
|
19
19
|
{% if code_model.global_parameters.config_method | first %}
|
|
20
20
|
|
|
21
21
|
{% endif %}
|
|
22
|
-
{
|
|
23
|
-
:{{ parameter.description_keyword }} {{ parameter.serialized_name }}: {{ parameter.description }}
|
|
24
|
-
:{{ parameter.docstring_type_keyword }} {{ parameter.serialized_name }}: {{ parameter.docstring_type }}
|
|
25
|
-
{% endfor %}
|
|
26
|
-
"""
|
|
27
|
-
|
|
22
|
+
{{ op_tools.serialize_with_wrap(serializer.property_descriptions(), "\n ") | indent }}
|
|
28
23
|
{{ serializer.init_signature_and_response_type_annotation(async_mode) | indent }}
|
|
29
24
|
super({{ code_model.class_name }}Configuration, self).__init__(**kwargs)
|
|
30
25
|
{% if code_model.service_client.parameters.config_kwargs_to_pop(async_mode) %}
|
|
@@ -13,4 +13,6 @@
|
|
|
13
13
|
{{ op_tools.serialize(operation_serializer.get_long_running_output(operation)) | indent }}
|
|
14
14
|
|
|
15
15
|
{{ op_tools.serialize(operation_serializer.return_lro_poller(operation)) | indent }}
|
|
16
|
-
{
|
|
16
|
+
{% if not code_model.options["version_tolerant"] %}
|
|
17
|
+
{{ operation_serializer.get_metadata_url(operation) -}}
|
|
18
|
+
{% endif %}
|
|
@@ -15,4 +15,6 @@
|
|
|
15
15
|
{{ op_tools.serialize(operation_serializer.initial_call(operation)) | indent }}
|
|
16
16
|
{{ op_tools.serialize(operation_serializer.get_long_running_output(operation)) | indent }}
|
|
17
17
|
{{ op_tools.serialize(operation_serializer.return_lro_poller(operation)) | indent }}
|
|
18
|
+
{% if not code_model.options["version_tolerant"] %}
|
|
18
19
|
{{ operation_serializer.get_metadata_url(operation) }}
|
|
20
|
+
{% endif %}
|
|
@@ -18,6 +18,12 @@
|
|
|
18
18
|
{{ op_tools.serialize(operation_serializer.pop_kwargs_from_signature(operation)) | indent }}
|
|
19
19
|
{% endif %}
|
|
20
20
|
{{ op_tools.serialize(operation_serializer.call_request_builder(operation)) | indent }}
|
|
21
|
-
pipeline_response = {{ keywords.await }}self._client._pipeline.run(
|
|
21
|
+
pipeline_response = {{ keywords.await }}self._client._pipeline.run( # pylint: disable=protected-access
|
|
22
|
+
request,
|
|
23
|
+
{{ stream_request_parameter }},
|
|
24
|
+
**kwargs
|
|
25
|
+
)
|
|
22
26
|
{{ op_tools.serialize(operation_serializer.handle_response(operation)) | indent }}
|
|
23
|
-
{
|
|
27
|
+
{% if not code_model.options["version_tolerant"] %}
|
|
28
|
+
{{ operation_serializer.get_metadata_url(operation) }}
|
|
29
|
+
{% endif %}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
{% set disable = " # pylint: disable=too-many-public-methods" if operation_group.operations | length > 20 else "" %}
|
|
2
|
+
class {{ operation_group.class_name }}{{ object_base_class }}:{{ disable }}
|
|
2
3
|
{% if not operation_group.is_empty_operation_group %}
|
|
3
4
|
"""{{ operation_group.class_name }} {{ operations_description }}.
|
|
4
5
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
{% set object_base_class = "" if async_mode else "(object)" %}
|
|
3
3
|
{% set operations_description = "async operations" if async_mode else "operations" %}
|
|
4
4
|
{% set return_none_type_annotation = " -> None" if async_mode else "" %}
|
|
5
|
+
# pylint: disable=too-many-lines
|
|
5
6
|
# coding=utf-8
|
|
6
7
|
{{ code_model.options['license_header'] }}
|
|
7
8
|
{{ imports }}
|