@autorest/python 5.12.2 → 5.12.6
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 +60 -0
- package/autorest/black/__init__.py +4 -1
- package/autorest/codegen/models/client.py +22 -19
- 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 +28 -26
- package/autorest/codegen/models/operation_group.py +5 -14
- package/autorest/codegen/models/paging_operation.py +9 -9
- package/autorest/codegen/models/parameter.py +6 -7
- package/autorest/codegen/models/parameter_list.py +1 -0
- 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 +0 -2
- package/autorest/codegen/models/request_builder_parameter_list.py +1 -0
- package/autorest/codegen/models/schema_response.py +1 -1
- package/autorest/codegen/serializers/builder_serializer.py +33 -26
- 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/model_base_serializer.py +6 -6
- 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/metadata.json.jinja2 +3 -3
- 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/package.json +2 -2
|
@@ -125,9 +125,9 @@ class PagingOperation(Operation):
|
|
|
125
125
|
def _imports_shared(self, async_mode: bool) -> FileImport:
|
|
126
126
|
file_import = super()._imports_shared(async_mode)
|
|
127
127
|
if async_mode:
|
|
128
|
-
file_import.
|
|
128
|
+
file_import.add_submodule_import("typing", "AsyncIterable", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
129
129
|
else:
|
|
130
|
-
file_import.
|
|
130
|
+
file_import.add_submodule_import("typing", "Iterable", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
131
131
|
if (
|
|
132
132
|
self.next_request_builder and
|
|
133
133
|
self.code_model.options["builders_visibility"] == "embedded"
|
|
@@ -141,26 +141,26 @@ class PagingOperation(Operation):
|
|
|
141
141
|
pager_import_path = ".".join(self.get_pager_path(async_mode).split(".")[:-1])
|
|
142
142
|
pager = self.get_pager(async_mode)
|
|
143
143
|
|
|
144
|
-
file_import.
|
|
144
|
+
file_import.add_submodule_import(pager_import_path, pager, ImportType.AZURECORE, TypingSection.CONDITIONAL)
|
|
145
145
|
|
|
146
146
|
return file_import
|
|
147
147
|
|
|
148
148
|
def imports(self, async_mode: bool) -> FileImport:
|
|
149
149
|
file_import = super(PagingOperation, self).imports(async_mode)
|
|
150
|
+
# operation adds an import for distributed_trace_async, we don't want it
|
|
151
|
+
file_import.imports = [i for i in file_import.imports if not i.submodule_name == "distributed_trace_async"]
|
|
150
152
|
|
|
151
153
|
pager_import_path = ".".join(self.get_pager_path(async_mode).split(".")[:-1])
|
|
152
154
|
pager = self.get_pager(async_mode)
|
|
153
155
|
|
|
154
|
-
file_import.
|
|
156
|
+
file_import.add_submodule_import(pager_import_path, pager, ImportType.AZURECORE)
|
|
155
157
|
|
|
156
158
|
if async_mode:
|
|
157
|
-
file_import.
|
|
159
|
+
file_import.add_submodule_import("azure.core.async_paging", "AsyncList", ImportType.AZURECORE)
|
|
158
160
|
|
|
159
|
-
if self.code_model.options["tracing"]:
|
|
160
|
-
file_import.
|
|
161
|
+
if self.code_model.options["tracing"] and self.want_tracing:
|
|
162
|
+
file_import.add_submodule_import(
|
|
161
163
|
"azure.core.tracing.decorator", "distributed_trace", ImportType.AZURECORE,
|
|
162
164
|
)
|
|
163
|
-
if not self.code_model.options["models_mode"]:
|
|
164
|
-
file_import.add_from_import("json", "loads", ImportType.STDLIB, alias="_loads")
|
|
165
165
|
|
|
166
166
|
return file_import
|
|
@@ -98,6 +98,7 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
98
98
|
self.content_types = content_types or []
|
|
99
99
|
self.body_kwargs: List[Parameter] = []
|
|
100
100
|
self.is_body_kwarg = False
|
|
101
|
+
self.need_import = True
|
|
101
102
|
|
|
102
103
|
def __hash__(self) -> int:
|
|
103
104
|
return hash(self.serialized_name)
|
|
@@ -177,8 +178,6 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
177
178
|
return not(
|
|
178
179
|
# don't put accept in signature
|
|
179
180
|
self.rest_api_name == "Accept"
|
|
180
|
-
# if i'm multiapi, don't add constants
|
|
181
|
-
or (self.code_model.options["multiapi"] and self.constant)
|
|
182
181
|
# If i'm not in the method code, no point in being in signature
|
|
183
182
|
or not self.in_method_code
|
|
184
183
|
# If I'm grouped, my grouper will be on signature, not me
|
|
@@ -302,8 +301,6 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
302
301
|
@property
|
|
303
302
|
def is_kwarg(self) -> bool:
|
|
304
303
|
# this means "am I in **kwargs?"
|
|
305
|
-
if self.code_model.options["multiapi"]:
|
|
306
|
-
return self.rest_api_name == "Content-Type"
|
|
307
304
|
return self.rest_api_name == "Content-Type" or (self.constant and self.rest_api_name != "Accept")
|
|
308
305
|
|
|
309
306
|
@property
|
|
@@ -313,7 +310,9 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
313
310
|
|
|
314
311
|
@property
|
|
315
312
|
def is_hidden(self) -> bool:
|
|
316
|
-
return self.serialized_name in _HIDDEN_KWARGS
|
|
313
|
+
return self.serialized_name in _HIDDEN_KWARGS or (
|
|
314
|
+
self.yaml_data["implementation"] == "Client" and self.constant
|
|
315
|
+
)
|
|
317
316
|
|
|
318
317
|
@property
|
|
319
318
|
def is_positional(self) -> bool:
|
|
@@ -356,9 +355,9 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
356
355
|
def imports(self) -> FileImport:
|
|
357
356
|
file_import = self.schema.imports()
|
|
358
357
|
if not self.required:
|
|
359
|
-
file_import.
|
|
358
|
+
file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
360
359
|
if self.has_multiple_content_types or self._is_io_json:
|
|
361
|
-
file_import.
|
|
360
|
+
file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
362
361
|
|
|
363
362
|
return file_import
|
|
364
363
|
|
|
@@ -275,6 +275,7 @@ class ParameterList(MutableSequence): # pylint: disable=too-many-public-methods
|
|
|
275
275
|
def _create_files_or_data_param(
|
|
276
276
|
params: List[Parameter], serialized_name: str, description: str
|
|
277
277
|
) -> Parameter:
|
|
278
|
+
params[0].need_import = False
|
|
278
279
|
param = copy(params[0])
|
|
279
280
|
param.serialized_name = serialized_name
|
|
280
281
|
param.schema = DictionarySchema(
|
|
@@ -116,7 +116,7 @@ class IOSchema(PrimitiveSchema):
|
|
|
116
116
|
|
|
117
117
|
def imports(self) -> FileImport:
|
|
118
118
|
file_import = FileImport()
|
|
119
|
-
file_import.
|
|
119
|
+
file_import.add_submodule_import("typing", "IO", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
120
120
|
return file_import
|
|
121
121
|
|
|
122
122
|
class AnySchema(PrimitiveSchema):
|
|
@@ -138,7 +138,7 @@ class AnySchema(PrimitiveSchema):
|
|
|
138
138
|
|
|
139
139
|
def imports(self) -> FileImport:
|
|
140
140
|
file_import = FileImport()
|
|
141
|
-
file_import.
|
|
141
|
+
file_import.add_submodule_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
142
142
|
return file_import
|
|
143
143
|
|
|
144
144
|
class JSONSchema(AnySchema):
|
|
@@ -170,5 +170,5 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
|
|
|
170
170
|
def model_file_imports(self) -> FileImport:
|
|
171
171
|
file_import = self.schema.model_file_imports()
|
|
172
172
|
if not self.required:
|
|
173
|
-
file_import.
|
|
173
|
+
file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
174
174
|
return file_import
|
|
@@ -66,9 +66,10 @@ class RequestBuilder(BaseBuilder):
|
|
|
66
66
|
def imports(self) -> FileImport:
|
|
67
67
|
file_import = FileImport()
|
|
68
68
|
for parameter in self.parameters:
|
|
69
|
-
|
|
69
|
+
if parameter.need_import:
|
|
70
|
+
file_import.merge(parameter.imports())
|
|
70
71
|
|
|
71
|
-
file_import.
|
|
72
|
+
file_import.add_submodule_import(
|
|
72
73
|
"azure.core.rest",
|
|
73
74
|
"HttpRequest",
|
|
74
75
|
ImportType.AZURECORE,
|
|
@@ -77,17 +78,17 @@ class RequestBuilder(BaseBuilder):
|
|
|
77
78
|
relative_path = ".."
|
|
78
79
|
if not self.code_model.options["builders_visibility"] == "embedded" and self.operation_group_name:
|
|
79
80
|
relative_path = "..." if self.operation_group_name else ".."
|
|
80
|
-
file_import.
|
|
81
|
+
file_import.add_submodule_import(
|
|
81
82
|
f"{relative_path}_vendor", "_format_url_section", ImportType.LOCAL
|
|
82
83
|
)
|
|
83
84
|
if self.parameters.headers or self.parameters.query:
|
|
84
|
-
file_import.
|
|
85
|
+
file_import.add_submodule_import(
|
|
85
86
|
"typing", "Dict", ImportType.STDLIB, typing_section=TypingSection.CONDITIONAL
|
|
86
87
|
)
|
|
87
|
-
file_import.
|
|
88
|
+
file_import.add_submodule_import(
|
|
88
89
|
"typing", "Any", ImportType.STDLIB, typing_section=TypingSection.CONDITIONAL
|
|
89
90
|
)
|
|
90
|
-
file_import.
|
|
91
|
+
file_import.add_submodule_import("msrest", "Serializer", ImportType.THIRDPARTY)
|
|
91
92
|
if self.parameters.has_body and (
|
|
92
93
|
self.code_model.options["builders_visibility"] != "embedded" or
|
|
93
94
|
self.code_model.options["add_python3_operation_files"]
|
|
@@ -18,8 +18,6 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
|
|
|
18
18
|
return not(
|
|
19
19
|
# don't put accept in method signature
|
|
20
20
|
self.rest_api_name == "Accept"
|
|
21
|
-
# if i'm multiapi, don't add constants
|
|
22
|
-
or (self.code_model.options["multiapi"] and self.constant)
|
|
23
21
|
# If i'm not in the method code, no point in being in signature
|
|
24
22
|
or not self.in_method_code
|
|
25
23
|
# If I'm a flattened property of a body, don't want me, want the body param
|
|
@@ -99,7 +99,7 @@ class SchemaResponse(BaseModel):
|
|
|
99
99
|
def imports(self, code_model) -> FileImport:
|
|
100
100
|
file_import = FileImport()
|
|
101
101
|
if not code_model.options["models_mode"] and self.is_xml:
|
|
102
|
-
file_import.
|
|
102
|
+
file_import.add_submodule_import("xml.etree", "ElementTree", ImportType.STDLIB, alias="ET")
|
|
103
103
|
return file_import
|
|
104
104
|
|
|
105
105
|
@classmethod
|
|
@@ -33,6 +33,9 @@ from . import utils
|
|
|
33
33
|
T = TypeVar("T")
|
|
34
34
|
OrderedSet = Dict[T, None]
|
|
35
35
|
|
|
36
|
+
def _escape_str(input_str: str) -> str:
|
|
37
|
+
replace = input_str.replace("'", "\\'")
|
|
38
|
+
return f'"{replace}"'
|
|
36
39
|
|
|
37
40
|
def _improve_json_string(template_representation: str) -> Any:
|
|
38
41
|
origin = template_representation.split('\n')
|
|
@@ -110,7 +113,7 @@ def _pop_parameters_kwarg(
|
|
|
110
113
|
function_name: str,
|
|
111
114
|
kwarg_name: str,
|
|
112
115
|
) -> str:
|
|
113
|
-
return f'{function_name}_parameters = kwargs.pop("{kwarg_name}", {{}}) # type: Dict[str, Any]'
|
|
116
|
+
return f'_{function_name}_parameters = kwargs.pop("{kwarg_name}", {{}}) # type: Dict[str, Any]'
|
|
114
117
|
|
|
115
118
|
def _serialize_grouped_body(builder) -> List[str]:
|
|
116
119
|
retval: List[str] = []
|
|
@@ -180,11 +183,6 @@ class _BuilderSerializerProtocol(ABC):
|
|
|
180
183
|
"""Whether you want inline type hints. If false, your type hints will be commented'"""
|
|
181
184
|
...
|
|
182
185
|
|
|
183
|
-
@abstractmethod
|
|
184
|
-
def _method_signature(self, builder) -> str:
|
|
185
|
-
"""Signature of the builder. Does not include return type annotation"""
|
|
186
|
-
...
|
|
187
|
-
|
|
188
186
|
@abstractmethod
|
|
189
187
|
def _response_type_annotation(self, builder, modify_if_head_as_boolean: bool = True) -> str:
|
|
190
188
|
"""The mypy type annotation for the response"""
|
|
@@ -266,20 +264,22 @@ class _BuilderBaseSerializer(_BuilderSerializerProtocol): # pylint: disable=abs
|
|
|
266
264
|
def _cls_docstring_rtype(self) -> str:
|
|
267
265
|
return "" if self.code_model.options["version_tolerant"] else " or the result of cls(response)"
|
|
268
266
|
|
|
269
|
-
def _method_signature(self, builder) -> str:
|
|
267
|
+
def _method_signature(self, builder: Operation, response_type_annotation: str) -> str:
|
|
270
268
|
return utils.serialize_method(
|
|
271
269
|
function_def=self._function_definition,
|
|
272
270
|
method_name=builder.name,
|
|
273
271
|
is_in_class=self._is_in_class,
|
|
274
272
|
method_param_signatures=builder.parameters.method_signature(self._want_inline_type_hints),
|
|
273
|
+
ignore_inconsistent_return_statements=(response_type_annotation == "None")
|
|
275
274
|
)
|
|
276
275
|
|
|
277
276
|
def _response_type_annotation_wrapper(self, builder) -> List[str]:
|
|
278
277
|
return []
|
|
279
278
|
|
|
280
279
|
def method_signature_and_response_type_annotation(self, builder) -> str:
|
|
281
|
-
method_signature = self._method_signature(builder)
|
|
282
280
|
response_type_annotation = self._response_type_annotation(builder)
|
|
281
|
+
# want pre-wrapped response type. As long as it's None, pylint will get mad about inconsistent return types
|
|
282
|
+
method_signature = self._method_signature(builder, response_type_annotation)
|
|
283
283
|
for wrapper in self._response_type_annotation_wrapper(builder)[::-1]:
|
|
284
284
|
response_type_annotation = f"{wrapper}[{response_type_annotation}]"
|
|
285
285
|
return self._method_signature_and_response_type_annotation_template(method_signature, response_type_annotation)
|
|
@@ -402,7 +402,7 @@ class _BuilderBaseSerializer(_BuilderSerializerProtocol): # pylint: disable=abs
|
|
|
402
402
|
def _serialize_parameter(
|
|
403
403
|
self, param: Parameter, function_name: str
|
|
404
404
|
) -> List[str]:
|
|
405
|
-
set_parameter = "{}_parameters['{}'] = {}".format(
|
|
405
|
+
set_parameter = "_{}_parameters['{}'] = {}".format(
|
|
406
406
|
function_name,
|
|
407
407
|
param.rest_api_name,
|
|
408
408
|
utils.build_serialize_data_call(param, function_name, self.serializer_name)
|
|
@@ -499,11 +499,11 @@ class _RequestBuilderBaseSerializer(_BuilderBaseSerializer): # pylint: disable=
|
|
|
499
499
|
def create_http_request(self, builder) -> List[str]:
|
|
500
500
|
retval = ["return HttpRequest("]
|
|
501
501
|
retval.append(f' method="{builder.method}",')
|
|
502
|
-
retval.append(" url=
|
|
502
|
+
retval.append(" url=_url,")
|
|
503
503
|
if builder.parameters.query:
|
|
504
|
-
retval.append(" params=
|
|
504
|
+
retval.append(" params=_query_parameters,")
|
|
505
505
|
if builder.parameters.headers:
|
|
506
|
-
retval.append(" headers=
|
|
506
|
+
retval.append(" headers=_header_parameters,")
|
|
507
507
|
if builder.parameters.has_body:
|
|
508
508
|
retval.extend([
|
|
509
509
|
f" {body_kwarg}={body_kwarg},"
|
|
@@ -533,6 +533,13 @@ class _RequestBuilderBaseSerializer(_BuilderBaseSerializer): # pylint: disable=
|
|
|
533
533
|
))
|
|
534
534
|
return retval
|
|
535
535
|
|
|
536
|
+
def construct_url(self, builder) -> str:
|
|
537
|
+
if any(o for o in ["low_level_client", "version_tolerant"] if self.code_model.options.get(o)):
|
|
538
|
+
url_value = _escape_str(builder.url)
|
|
539
|
+
else:
|
|
540
|
+
url_value = f'kwargs.pop("template_url", {_escape_str(builder.url)})'
|
|
541
|
+
return f"_url = {url_value}{' # pylint: disable=line-too-long' if len(url_value) > 114 else ''}"
|
|
542
|
+
|
|
536
543
|
class RequestBuilderGenericSerializer(_RequestBuilderBaseSerializer):
|
|
537
544
|
@property
|
|
538
545
|
def _want_inline_type_hints(self) -> bool:
|
|
@@ -711,7 +718,7 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
|
|
|
711
718
|
)
|
|
712
719
|
ser_ctxt_name = "serialization_ctxt"
|
|
713
720
|
ser_ctxt = builder.parameters.body[0].xml_serialization_ctxt if send_xml else None
|
|
714
|
-
if ser_ctxt:
|
|
721
|
+
if ser_ctxt and self.code_model.options["models_mode"]:
|
|
715
722
|
retval.append(f'{ser_ctxt_name} = {{"xml": {{{ser_ctxt}}}}}')
|
|
716
723
|
serialize_body_call = self._serialize_body_call(
|
|
717
724
|
builder,
|
|
@@ -986,7 +993,8 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
|
|
|
986
993
|
|
|
987
994
|
@staticmethod
|
|
988
995
|
def get_metadata_url(builder) -> str:
|
|
989
|
-
|
|
996
|
+
url = _escape_str(builder.request_builder.url)
|
|
997
|
+
return f"{builder.python_name}.metadata = {{'url': { url }}} # type: ignore"
|
|
990
998
|
|
|
991
999
|
class _SyncOperationBaseSerializer(_OperationBaseSerializer): # pylint: disable=abstract-method
|
|
992
1000
|
@property
|
|
@@ -1114,7 +1122,7 @@ class _PagingOperationBaseSerializer(_OperationBaseSerializer): # pylint: disab
|
|
|
1114
1122
|
deserialized = (
|
|
1115
1123
|
f'self._deserialize("{response.serialization_type}", pipeline_response)'
|
|
1116
1124
|
if self.code_model.options["models_mode"] else
|
|
1117
|
-
"
|
|
1125
|
+
"pipeline_response.http_response.json()"
|
|
1118
1126
|
)
|
|
1119
1127
|
retval.append(f" deserialized = {deserialized}")
|
|
1120
1128
|
item_name = builder.item_name(self.code_model)
|
|
@@ -1137,10 +1145,11 @@ class _PagingOperationBaseSerializer(_OperationBaseSerializer): # pylint: disab
|
|
|
1137
1145
|
retval = [f"{self._def} get_next(next_link=None):"]
|
|
1138
1146
|
retval.append(" request = prepare_request(next_link)")
|
|
1139
1147
|
retval.append("")
|
|
1140
|
-
retval.append(
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
)
|
|
1148
|
+
retval.append(f" pipeline_response = {self._call_method}self._client._pipeline.run( # pylint: disable=protected-access")
|
|
1149
|
+
retval.append(" request,")
|
|
1150
|
+
retval.append(f" stream={builder.is_stream_response},")
|
|
1151
|
+
retval.append(" **kwargs")
|
|
1152
|
+
retval.append(" )")
|
|
1144
1153
|
retval.append(" response = pipeline_response.http_response")
|
|
1145
1154
|
retval.append("")
|
|
1146
1155
|
retval.extend([
|
|
@@ -1234,7 +1243,7 @@ class _LROOperationBaseSerializer(_OperationBaseSerializer): # pylint: disable=
|
|
|
1234
1243
|
"Pass in False for this operation to not poll, or pass in your own initialized polling object for a"
|
|
1235
1244
|
" personal polling strategy."
|
|
1236
1245
|
)
|
|
1237
|
-
retval.append(f":paramtype polling: bool or ~{self._polling_method_type}")
|
|
1246
|
+
retval.append(f":paramtype polling: bool or ~azure.core.polling.{self._polling_method_type}")
|
|
1238
1247
|
retval.append(
|
|
1239
1248
|
":keyword int polling_interval: Default waiting time between two polls for LRO operations "
|
|
1240
1249
|
"if no Retry-After header is present."
|
|
@@ -1287,9 +1296,8 @@ class _LROOperationBaseSerializer(_OperationBaseSerializer): # pylint: disable=
|
|
|
1287
1296
|
retval.append(" client=self._client,")
|
|
1288
1297
|
retval.append(" deserialization_callback=get_long_running_output")
|
|
1289
1298
|
retval.append(" )")
|
|
1290
|
-
retval.append("else:")
|
|
1291
1299
|
retval.append(
|
|
1292
|
-
f"
|
|
1300
|
+
f"return {self._poller(builder)}"
|
|
1293
1301
|
"(self._client, raw_result, get_long_running_output, polling_method)"
|
|
1294
1302
|
)
|
|
1295
1303
|
return retval
|
|
@@ -1335,7 +1343,7 @@ class _SyncLROOperationBaseSerializer(_LROOperationBaseSerializer, _SyncOperatio
|
|
|
1335
1343
|
|
|
1336
1344
|
@property
|
|
1337
1345
|
def _polling_method_type(self):
|
|
1338
|
-
return "
|
|
1346
|
+
return "PollingMethod"
|
|
1339
1347
|
|
|
1340
1348
|
def _poller(self, builder) -> str:
|
|
1341
1349
|
return builder.get_poller(async_mode=False)
|
|
@@ -1368,7 +1376,7 @@ class AsyncLROOperationSerializer(_LROOperationBaseSerializer, AsyncOperationSer
|
|
|
1368
1376
|
|
|
1369
1377
|
@property
|
|
1370
1378
|
def _polling_method_type(self):
|
|
1371
|
-
return "
|
|
1379
|
+
return "AsyncPollingMethod"
|
|
1372
1380
|
|
|
1373
1381
|
def _poller(self, builder) -> str:
|
|
1374
1382
|
return builder.get_poller(async_mode=True)
|
|
@@ -1383,8 +1391,7 @@ class _LROPagingOperationBaseSerializer(_LROOperationBaseSerializer, _PagingOper
|
|
|
1383
1391
|
retval.append(f" {self._def} internal_get_next(next_link=None):")
|
|
1384
1392
|
retval.append(" if next_link is None:")
|
|
1385
1393
|
retval.append(" return pipeline_response")
|
|
1386
|
-
retval.append("
|
|
1387
|
-
retval.append(f" return {self._call_method}get_next(next_link)")
|
|
1394
|
+
retval.append(f" return {self._call_method}get_next(next_link)")
|
|
1388
1395
|
retval.append("")
|
|
1389
1396
|
retval.append(f" return {self._pager(builder)}(")
|
|
1390
1397
|
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()
|