@autorest/python 5.12.5 → 5.14.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 +185 -118
- package/autorest/black/__init__.py +3 -0
- package/autorest/codegen/__init__.py +34 -2
- package/autorest/codegen/models/__init__.py +2 -1
- package/autorest/codegen/models/client.py +6 -5
- package/autorest/codegen/models/code_model.py +3 -0
- package/autorest/codegen/models/constant_schema.py +0 -4
- package/autorest/codegen/models/lro_operation.py +6 -2
- package/autorest/codegen/models/operation.py +20 -11
- package/autorest/codegen/models/operation_group.py +0 -9
- package/autorest/codegen/models/paging_operation.py +3 -3
- package/autorest/codegen/models/parameter.py +35 -9
- package/autorest/codegen/models/parameter_list.py +11 -4
- package/autorest/codegen/models/request_builder.py +3 -2
- package/autorest/codegen/models/request_builder_parameter.py +5 -0
- package/autorest/codegen/models/request_builder_parameter_list.py +1 -0
- package/autorest/codegen/serializers/__init__.py +147 -74
- 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 +4 -1
- package/autorest/codegen/serializers/utils.py +5 -1
- package/autorest/codegen/templates/CHANGELOG.md.jinja2 +6 -0
- package/autorest/codegen/templates/LICENSE.jinja2 +21 -0
- package/autorest/codegen/templates/MANIFEST.in.jinja2 +7 -0
- package/autorest/codegen/templates/README.md.jinja2 +105 -0
- package/autorest/codegen/templates/config.py.jinja2 +2 -7
- package/autorest/codegen/templates/dev_requirements.txt.jinja2 +10 -0
- 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 +6 -2
- package/autorest/codegen/templates/operation_group.py.jinja2 +15 -18
- 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 +2 -2
- package/autorest/codegen/templates/request_builder.py.jinja2 +2 -7
- package/autorest/codegen/templates/service_client.py.jinja2 +1 -1
- package/autorest/codegen/templates/setup.py.jinja2 +79 -20
- package/autorest/namer/name_converter.py +1 -1
- package/package.json +2 -2
- package/run-python3.js +1 -7
- package/venvtools.py +2 -2
|
@@ -159,7 +159,8 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
|
|
|
159
159
|
if response.has_body:
|
|
160
160
|
file_import.merge(cast(BaseSchema, response.schema).imports())
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
response_types = [r.operation_type_annotation for r in self.responses if r.has_body]
|
|
163
|
+
if len(set(response_types)) > 1:
|
|
163
164
|
file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
164
165
|
|
|
165
166
|
if self.is_stream_response:
|
|
@@ -179,13 +180,10 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
|
|
|
179
180
|
file_import.add_submodule_import("azure.mgmt.core.exceptions", "ARMErrorFormat", ImportType.AZURECORE)
|
|
180
181
|
file_import.add_submodule_import("azure.core.exceptions", "HttpResponseError", ImportType.AZURECORE)
|
|
181
182
|
|
|
182
|
-
|
|
183
|
-
file_import.add_import("functools", ImportType.STDLIB)
|
|
184
183
|
file_import.add_submodule_import("typing", "Callable", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
185
184
|
file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
186
185
|
file_import.add_submodule_import("typing", "Dict", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
187
186
|
file_import.add_submodule_import("typing", "TypeVar", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
188
|
-
file_import.add_submodule_import("typing", "Generic", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
189
187
|
file_import.add_submodule_import("azure.core.pipeline", "PipelineResponse", ImportType.AZURECORE)
|
|
190
188
|
file_import.add_submodule_import("azure.core.rest", "HttpRequest", ImportType.AZURECORE)
|
|
191
189
|
if async_mode:
|
|
@@ -193,9 +191,7 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
|
|
|
193
191
|
else:
|
|
194
192
|
file_import.add_submodule_import("azure.core.pipeline.transport", "HttpResponse", ImportType.AZURECORE)
|
|
195
193
|
|
|
196
|
-
|
|
197
|
-
# FIXME: Replace with "the YAML contains deprecated:true"
|
|
198
|
-
if True: # pylint: disable=using-constant-test
|
|
194
|
+
if self.deprecated:
|
|
199
195
|
file_import.add_import("warnings", ImportType.STDLIB)
|
|
200
196
|
|
|
201
197
|
if self.code_model.options["builders_visibility"] != "embedded":
|
|
@@ -227,6 +223,12 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
|
|
|
227
223
|
any(r for r in self.responses if r.has_body)
|
|
228
224
|
):
|
|
229
225
|
file_import.define_mypy_type("JSONType", "Any")
|
|
226
|
+
if self.code_model.options["tracing"] and self.want_tracing:
|
|
227
|
+
file_import.add_submodule_import(
|
|
228
|
+
f"azure.core.tracing.decorator{'_async' if async_mode else ''}",
|
|
229
|
+
f"distributed_trace{'_async' if async_mode else ''}",
|
|
230
|
+
ImportType.AZURECORE,
|
|
231
|
+
)
|
|
230
232
|
return file_import
|
|
231
233
|
|
|
232
234
|
def _get_body_param_from_body_kwarg(self, body_kwarg: Parameter) -> Parameter:
|
|
@@ -301,6 +303,15 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
|
|
|
301
303
|
parameters, multiple_content_type_parameters = create_parameters(
|
|
302
304
|
yaml_data, code_model, parameter_creator
|
|
303
305
|
)
|
|
306
|
+
parameter_list = parameter_list_creator(code_model, parameters, schema_requests)
|
|
307
|
+
multiple_content_type_parameter_list = parameter_list_creator(
|
|
308
|
+
code_model, multiple_content_type_parameters, schema_requests
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
if len(parameter_list.content_types) > 1:
|
|
312
|
+
for p in parameter_list.parameters:
|
|
313
|
+
if p.rest_api_name == "Content-Type":
|
|
314
|
+
p.is_keyword_only = True
|
|
304
315
|
|
|
305
316
|
return cls(
|
|
306
317
|
code_model=code_model,
|
|
@@ -308,10 +319,8 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
|
|
|
308
319
|
name=name,
|
|
309
320
|
description=yaml_data["language"]["python"]["description"],
|
|
310
321
|
api_versions=set(value_dict["version"] for value_dict in yaml_data["apiVersions"]),
|
|
311
|
-
parameters=
|
|
312
|
-
multiple_content_type_parameters=
|
|
313
|
-
code_model, multiple_content_type_parameters, schema_requests
|
|
314
|
-
),
|
|
322
|
+
parameters=parameter_list,
|
|
323
|
+
multiple_content_type_parameters=multiple_content_type_parameter_list,
|
|
315
324
|
schema_requests=schema_requests,
|
|
316
325
|
summary=yaml_data["language"]["python"].get("summary"),
|
|
317
326
|
responses=[SchemaResponse.from_yaml(yaml) for yaml in yaml_data.get("responses", [])],
|
|
@@ -63,15 +63,6 @@ class OperationGroup(BaseModel):
|
|
|
63
63
|
file_import.add_submodule_import("azure.core.exceptions", "ResourceExistsError", ImportType.AZURECORE)
|
|
64
64
|
for operation in self.operations:
|
|
65
65
|
file_import.merge(operation.imports(async_mode))
|
|
66
|
-
if self.code_model.options["tracing"]:
|
|
67
|
-
if async_mode:
|
|
68
|
-
file_import.add_submodule_import(
|
|
69
|
-
"azure.core.tracing.decorator_async", "distributed_trace_async", ImportType.AZURECORE,
|
|
70
|
-
)
|
|
71
|
-
else:
|
|
72
|
-
file_import.add_submodule_import(
|
|
73
|
-
"azure.core.tracing.decorator", "distributed_trace", ImportType.AZURECORE,
|
|
74
|
-
)
|
|
75
66
|
local_path = "..." if async_mode else ".."
|
|
76
67
|
if self.code_model.has_schemas and self.code_model.options["models_mode"]:
|
|
77
68
|
file_import.add_submodule_import(local_path, "models", ImportType.LOCAL, alias="_models")
|
|
@@ -147,6 +147,8 @@ class PagingOperation(Operation):
|
|
|
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)
|
|
@@ -156,11 +158,9 @@ class PagingOperation(Operation):
|
|
|
156
158
|
if async_mode:
|
|
157
159
|
file_import.add_submodule_import("azure.core.async_paging", "AsyncList", ImportType.AZURECORE)
|
|
158
160
|
|
|
159
|
-
if self.code_model.options["tracing"]:
|
|
161
|
+
if self.code_model.options["tracing"] and self.want_tracing:
|
|
160
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_submodule_import("json", "loads", ImportType.STDLIB, alias="_loads")
|
|
165
165
|
|
|
166
166
|
return file_import
|
|
@@ -68,7 +68,7 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
68
68
|
grouped_by: Optional["Parameter"] = None,
|
|
69
69
|
original_parameter: Optional["Parameter"] = None,
|
|
70
70
|
client_default_value: Optional[Any] = None,
|
|
71
|
-
keyword_only: bool =
|
|
71
|
+
keyword_only: Optional[bool] = None,
|
|
72
72
|
content_types: Optional[List[str]] = None,
|
|
73
73
|
) -> None:
|
|
74
74
|
super().__init__(yaml_data)
|
|
@@ -98,6 +98,8 @@ 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
|
|
102
|
+
self.is_kwarg = (self.rest_api_name == "Content-Type" or (self.constant and self.rest_api_name != "Accept"))
|
|
101
103
|
|
|
102
104
|
def __hash__(self) -> int:
|
|
103
105
|
return hash(self.serialized_name)
|
|
@@ -110,6 +112,14 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
110
112
|
if description:
|
|
111
113
|
description += " "
|
|
112
114
|
description += f"{self.schema.extra_description_information}"
|
|
115
|
+
if isinstance(self.schema, ConstantSchema) and not self.constant:
|
|
116
|
+
if description:
|
|
117
|
+
description += " "
|
|
118
|
+
description += f"Possible values are {self.schema.get_declaration(self.schema.value)} or {None}."
|
|
119
|
+
if self.has_default_value and not any(
|
|
120
|
+
l for l in ["default value is", "default is"] if l in description.lower()
|
|
121
|
+
):
|
|
122
|
+
description += f" Default value is {self.default_value_declaration}."
|
|
113
123
|
if self.constant:
|
|
114
124
|
description += " Note that overriding this default value may result in unsupported behavior."
|
|
115
125
|
return description
|
|
@@ -231,7 +241,12 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
231
241
|
default_value_declaration = "None"
|
|
232
242
|
else:
|
|
233
243
|
if isinstance(self.schema, ConstantSchema):
|
|
234
|
-
|
|
244
|
+
if (self.required or
|
|
245
|
+
self.is_content_type or
|
|
246
|
+
not self.code_model.options["default_optional_constants_to_none"]):
|
|
247
|
+
default_value = self.schema.get_declaration(self.schema.value)
|
|
248
|
+
else:
|
|
249
|
+
default_value = None
|
|
235
250
|
default_value_declaration = default_value
|
|
236
251
|
else:
|
|
237
252
|
default_value = self.schema.default_value
|
|
@@ -297,22 +312,26 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
297
312
|
origin_name = f"self._config.{self.serialized_name}"
|
|
298
313
|
return origin_name
|
|
299
314
|
|
|
300
|
-
@property
|
|
301
|
-
def is_kwarg(self) -> bool:
|
|
302
|
-
# this means "am I in **kwargs?"
|
|
303
|
-
return self.rest_api_name == "Content-Type" or (self.constant and self.rest_api_name != "Accept")
|
|
304
|
-
|
|
305
315
|
@property
|
|
306
316
|
def is_keyword_only(self) -> bool:
|
|
307
317
|
# this means in async mode, I am documented like def hello(positional_1, *, me!)
|
|
308
|
-
return self._keyword_only
|
|
318
|
+
return self._keyword_only or False
|
|
319
|
+
|
|
320
|
+
@is_keyword_only.setter
|
|
321
|
+
def is_keyword_only(self, val: bool) -> None:
|
|
322
|
+
self._keyword_only = val
|
|
323
|
+
self.is_kwarg = False
|
|
309
324
|
|
|
310
325
|
@property
|
|
311
326
|
def is_hidden(self) -> bool:
|
|
312
|
-
return self.serialized_name in _HIDDEN_KWARGS or (
|
|
327
|
+
return self.serialized_name in _HIDDEN_KWARGS and self.is_kwarg or (
|
|
313
328
|
self.yaml_data["implementation"] == "Client" and self.constant
|
|
314
329
|
)
|
|
315
330
|
|
|
331
|
+
@property
|
|
332
|
+
def is_content_type(self) -> bool:
|
|
333
|
+
return self.rest_api_name == "Content-Type" and self.location == ParameterLocation.Header
|
|
334
|
+
|
|
316
335
|
@property
|
|
317
336
|
def is_positional(self) -> bool:
|
|
318
337
|
return self.in_method_signature and not (self.is_keyword_only or self.is_kwarg)
|
|
@@ -364,6 +383,8 @@ class ParameterOnlyPathAndBodyPositional(Parameter):
|
|
|
364
383
|
|
|
365
384
|
@property
|
|
366
385
|
def is_keyword_only(self) -> bool:
|
|
386
|
+
if self._keyword_only is not None:
|
|
387
|
+
return self._keyword_only
|
|
367
388
|
return self.in_method_signature and not (
|
|
368
389
|
self.is_hidden or
|
|
369
390
|
self.location == ParameterLocation.Path or
|
|
@@ -372,6 +393,11 @@ class ParameterOnlyPathAndBodyPositional(Parameter):
|
|
|
372
393
|
self.is_kwarg
|
|
373
394
|
)
|
|
374
395
|
|
|
396
|
+
@is_keyword_only.setter
|
|
397
|
+
def is_keyword_only(self, val: bool) -> None:
|
|
398
|
+
self._keyword_only = val
|
|
399
|
+
self.is_kwarg = False
|
|
400
|
+
|
|
375
401
|
def get_parameter(code_model):
|
|
376
402
|
if code_model.options["only_path_and_body_params_positional"]:
|
|
377
403
|
return ParameterOnlyPathAndBodyPositional
|
|
@@ -207,7 +207,9 @@ class ParameterList(MutableSequence): # pylint: disable=too-many-public-methods
|
|
|
207
207
|
lambda parameter: parameter.implementation == self.implementation
|
|
208
208
|
)
|
|
209
209
|
positional = [p for p in parameters_of_this_implementation if p.is_positional]
|
|
210
|
-
keyword_only =
|
|
210
|
+
keyword_only = self._filter_out_multiple_content_type(
|
|
211
|
+
[p for p in parameters_of_this_implementation if p.is_keyword_only]
|
|
212
|
+
)
|
|
211
213
|
kwargs = self._filter_out_multiple_content_type(
|
|
212
214
|
[p for p in parameters_of_this_implementation if p.is_kwarg]
|
|
213
215
|
)
|
|
@@ -275,6 +277,7 @@ class ParameterList(MutableSequence): # pylint: disable=too-many-public-methods
|
|
|
275
277
|
def _create_files_or_data_param(
|
|
276
278
|
params: List[Parameter], serialized_name: str, description: str
|
|
277
279
|
) -> Parameter:
|
|
280
|
+
params[0].need_import = False
|
|
278
281
|
param = copy(params[0])
|
|
279
282
|
param.serialized_name = serialized_name
|
|
280
283
|
param.schema = DictionarySchema(
|
|
@@ -314,7 +317,9 @@ class ParameterOnlyPathAndBodyPositionalList(ParameterList):
|
|
|
314
317
|
file_and_data_params.append(data_param)
|
|
315
318
|
method_params = [p for p in method_params if not p.is_multipart and not p.is_data_input]
|
|
316
319
|
positional = [p for p in method_params if p.is_positional]
|
|
317
|
-
keyword_only =
|
|
320
|
+
keyword_only = self._filter_out_multiple_content_type(
|
|
321
|
+
[p for p in method_params if p.is_keyword_only]
|
|
322
|
+
)
|
|
318
323
|
kwargs = self._filter_out_multiple_content_type(
|
|
319
324
|
[p for p in method_params if p.is_kwarg]
|
|
320
325
|
)
|
|
@@ -337,7 +342,9 @@ class GlobalParameterList(ParameterList):
|
|
|
337
342
|
"""
|
|
338
343
|
# Client level should not be on Method, etc.
|
|
339
344
|
positional = [p for p in self.parameters if p.is_positional]
|
|
340
|
-
keyword_only =
|
|
345
|
+
keyword_only = self._filter_out_multiple_content_type(
|
|
346
|
+
[p for p in self.parameters if p.is_keyword_only]
|
|
347
|
+
)
|
|
341
348
|
kwargs = self._filter_out_multiple_content_type(
|
|
342
349
|
[p for p in self.parameters if p.is_kwarg]
|
|
343
350
|
)
|
|
@@ -383,7 +390,7 @@ class GlobalParameterList(ParameterList):
|
|
|
383
390
|
schema=StringSchema(namespace="", yaml_data={"type": "str"}),
|
|
384
391
|
rest_api_name=self.host_variable_name,
|
|
385
392
|
serialized_name=self.host_variable_name,
|
|
386
|
-
description=f"Service URL.
|
|
393
|
+
description=f"Service URL.",
|
|
387
394
|
implementation="Client",
|
|
388
395
|
required=True,
|
|
389
396
|
location=ParameterLocation.Other,
|
|
@@ -66,7 +66,8 @@ 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
72
|
file_import.add_submodule_import(
|
|
72
73
|
"azure.core.rest",
|
|
@@ -87,7 +88,7 @@ class RequestBuilder(BaseBuilder):
|
|
|
87
88
|
file_import.add_submodule_import(
|
|
88
89
|
"typing", "Any", ImportType.STDLIB, typing_section=TypingSection.CONDITIONAL
|
|
89
90
|
)
|
|
90
|
-
file_import.add_submodule_import("msrest", "Serializer", ImportType.
|
|
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"]
|
|
@@ -62,6 +62,11 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
|
|
|
62
62
|
def is_keyword_only(self) -> bool:
|
|
63
63
|
return not self.location == ParameterLocation.Path and not self.is_kwarg
|
|
64
64
|
|
|
65
|
+
@is_keyword_only.setter
|
|
66
|
+
def is_keyword_only(self, val: bool) -> None:
|
|
67
|
+
self._keyword_only = val
|
|
68
|
+
self.is_kwarg = False
|
|
69
|
+
|
|
65
70
|
@property
|
|
66
71
|
def full_serialized_name(self) -> str:
|
|
67
72
|
return self.serialized_name
|