@autorest/python 6.15.0 → 6.16.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.
@@ -164,6 +164,10 @@ class OptionsRetriever:
164
164
  except AttributeError:
165
165
  return packaging_files_config
166
166
 
167
+ @property
168
+ def package_version(self) -> Optional[str]:
169
+ return str(self.options.get("package-version", ""))
170
+
167
171
 
168
172
  class CodeGenerator(Plugin):
169
173
  def __init__(self, *args, **kwargs: Any) -> None:
@@ -18,6 +18,7 @@ from .request_builder import (
18
18
  from .parameter import Parameter, ParameterMethodLocation
19
19
  from .lro_operation import LROOperation
20
20
  from .lro_paging_operation import LROPagingOperation
21
+ from ...utils import extract_original_name
21
22
 
22
23
  ParameterListType = TypeVar(
23
24
  "ParameterListType",
@@ -92,7 +93,7 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
92
93
  if operation_yaml.get("isLroInitialOperation"):
93
94
  # we want to change the name
94
95
  request_builder.name = request_builder.get_name(
95
- request_builder.yaml_data["name"][1 : -len("_initial")],
96
+ extract_original_name(request_builder.yaml_data["name"]),
96
97
  request_builder.yaml_data,
97
98
  request_builder.code_model,
98
99
  request_builder.client,
@@ -343,6 +343,8 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
343
343
  "ResourceExistsError",
344
344
  "ResourceNotModifiedError",
345
345
  ]
346
+ if self.stream_value:
347
+ errors.extend(["StreamConsumedError", "StreamClosedError"])
346
348
  for error in errors:
347
349
  file_import.add_submodule_import("exceptions", error, ImportType.SDKCORE)
348
350
  if self.code_model.options["azure_arm"]:
@@ -555,6 +555,10 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
555
555
 
556
556
  for client in self.code_model.clients:
557
557
  for og in client.operation_groups:
558
+ if self.code_model.options["multiapi"] and any(
559
+ o.api_versions[0] != self.code_model.options["default_api_version"] for o in og.operations
560
+ ):
561
+ continue
558
562
  test_serializer = TestSerializer(self.code_model, env, client=client, operation_group=og)
559
563
  for is_async in (True, False):
560
564
  try:
@@ -410,14 +410,19 @@ class RequestBuilderSerializer(_BuilderBaseSerializer[RequestBuilderType]): # p
410
410
  return "response.json()"
411
411
 
412
412
  @staticmethod
413
- def declare_non_inputtable_constants(builder: RequestBuilderType) -> List[str]:
413
+ def declare_non_inputtable_headers_queries(builder: RequestBuilderType) -> List[str]:
414
414
  def _get_value(param):
415
+ declaration = param.get_declaration() if param.constant else None
415
416
  if param.location in [ParameterLocation.HEADER, ParameterLocation.QUERY]:
416
417
  kwarg_dict = "headers" if param.location == ParameterLocation.HEADER else "params"
417
- return f"_{kwarg_dict}.pop('{param.wire_name}', {param.get_declaration()})"
418
- return f"{param.get_declaration()}"
418
+ return f"_{kwarg_dict}.pop('{param.wire_name}', {declaration})"
419
+ return declaration
419
420
 
420
- return [f"{p.client_name} = {_get_value(p)}" for p in builder.parameters.constant if not p.in_method_signature]
421
+ return [
422
+ f"{p.client_name} = {_get_value(p)}"
423
+ for p in (builder.parameters.headers + builder.parameters.query)
424
+ if not p.in_method_signature
425
+ ]
421
426
 
422
427
  @property
423
428
  def _function_def(self) -> str:
@@ -561,16 +566,22 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]): # pylint: di
561
566
  return retval
562
567
 
563
568
  def make_pipeline_call(self, builder: OperationType) -> List[str]:
569
+ retval = []
564
570
  type_ignore = self.async_mode and builder.group_name == "" # is in a mixin
565
- return [
566
- f"_stream = {builder.stream_value}",
567
- f"pipeline_response: PipelineResponse = {self._call_method}self._client.{self.pipeline_name}.run( "
568
- + f"{'# type: ignore' if type_ignore else ''} # pylint: disable=protected-access",
569
- " _request,",
570
- " stream=_stream,",
571
- " **kwargs",
572
- ")",
573
- ]
571
+ if builder.stream_value is True and not self.code_model.options["version_tolerant"]:
572
+ retval.append("_decompress = kwargs.pop('decompress', True)")
573
+ retval.extend(
574
+ [
575
+ f"_stream = {builder.stream_value}",
576
+ f"pipeline_response: PipelineResponse = {self._call_method}self._client.{self.pipeline_name}.run( "
577
+ + f"{'# type: ignore' if type_ignore else ''} # pylint: disable=protected-access",
578
+ " _request,",
579
+ " stream=_stream,",
580
+ " **kwargs",
581
+ ")",
582
+ ]
583
+ )
584
+ return retval
574
585
 
575
586
  @property
576
587
  def _function_def(self) -> str:
@@ -913,7 +924,9 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]): # pylint: di
913
924
  if self.code_model.options["version_tolerant"]:
914
925
  deserialized = "response.iter_bytes()"
915
926
  else:
916
- deserialized = f"response.stream_download(self._client.{self.pipeline_name})"
927
+ deserialized = (
928
+ f"response.stream_download(self._client.{self.pipeline_name}, decompress=_decompress)"
929
+ )
917
930
  deserialize_code.append(f"deserialized = {deserialized}")
918
931
  elif response.type:
919
932
  pylint_disable = ""
@@ -961,11 +974,17 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]): # pylint: di
961
974
  def handle_error_response(self, builder: OperationType) -> List[str]:
962
975
  async_await = "await " if self.async_mode else ""
963
976
  retval = [f"if response.status_code not in {str(builder.success_status_codes)}:"]
964
- response_read = f" {async_await}response.read() # Load the body in memory and close the socket"
977
+ response_read = [
978
+ " try:",
979
+ f" {async_await}response.read() # Load the body in memory and close the socket",
980
+ " except (StreamConsumedError, StreamClosedError):",
981
+ " pass",
982
+ ]
965
983
  if builder.stream_value is True: # _stream is True so no need to judge it
966
- retval.append(response_read)
984
+ retval.extend(response_read)
967
985
  elif isinstance(builder.stream_value, str): # _stream is not sure, so we need to judge it
968
- retval.extend([" if _stream:", f" {response_read}"])
986
+ retval.append(" if _stream:")
987
+ retval.extend([f" {l}" for l in response_read])
969
988
  type_ignore = " # type: ignore" if _need_type_ignore(builder) else ""
970
989
  retval.append(
971
990
  f" map_error(status_code=response.status_code, response=response, error_map=error_map){type_ignore}"
@@ -148,7 +148,7 @@ class ParameterSerializer:
148
148
  param.wire_name,
149
149
  ParameterSerializer.serialize_parameter(param, serializer_name),
150
150
  )
151
- if not param.optional:
151
+ if not param.optional and (param.in_method_signature or param.constant):
152
152
  retval = [set_parameter]
153
153
  else:
154
154
  retval = [
@@ -8,8 +8,8 @@
8
8
  {% if request_builder_serializer.pop_kwargs_from_signature(request_builder) %}
9
9
  {{ op_tools.serialize(request_builder_serializer.pop_kwargs_from_signature(request_builder)) | indent }}
10
10
  {%- endif -%}
11
- {% if request_builder_serializer.declare_non_inputtable_constants(request_builder) %}
12
- {{ op_tools.serialize(request_builder_serializer.declare_non_inputtable_constants(request_builder)) | indent }}
11
+ {% if request_builder_serializer.declare_non_inputtable_headers_queries(request_builder) %}
12
+ {{ op_tools.serialize(request_builder_serializer.declare_non_inputtable_headers_queries(request_builder)) | indent }}
13
13
  {% endif %}
14
14
  # Construct URL
15
15
  {{ request_builder_serializer.construct_url(request_builder) }}
@@ -8,7 +8,7 @@
8
8
  import copy
9
9
  from typing import Callable, Dict, Any, List, Optional
10
10
 
11
- from ..utils import to_snake_case
11
+ from ..utils import to_snake_case, extract_original_name
12
12
  from .helpers import (
13
13
  add_redefined_builtin_info,
14
14
  pad_builtin_namespaces,
@@ -235,7 +235,8 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
235
235
  property["clientName"] = self.pad_reserved_words(property["clientName"].lower(), PadType.PROPERTY)
236
236
  add_redefined_builtin_info(property["clientName"], property)
237
237
  if type.get("name"):
238
- name = self.pad_reserved_words(type["name"], PadType.MODEL)
238
+ pad_type = PadType.MODEL if type["type"] == "model" else PadType.ENUM_CLASS
239
+ name = self.pad_reserved_words(type["name"], pad_type)
239
240
  type["name"] = name[0].upper() + name[1:]
240
241
  type["description"] = update_description(type.get("description", ""), type["name"])
241
242
  type["snakeCaseName"] = to_snake_case(type["name"])
@@ -243,7 +244,7 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
243
244
  # we're enums
244
245
  values_to_add = []
245
246
  for value in type["values"]:
246
- padded_name = self.pad_reserved_words(value["name"].lower(), PadType.ENUM).upper()
247
+ padded_name = self.pad_reserved_words(value["name"].lower(), PadType.ENUM_VALUE).upper()
247
248
  if self.version_tolerant:
248
249
  if padded_name[0] in "0123456789":
249
250
  padded_name = "ENUM_" + padded_name
@@ -362,7 +363,12 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
362
363
  yaml_data["groupName"] = self.pad_reserved_words(yaml_data["groupName"], PadType.OPERATION_GROUP)
363
364
  yaml_data["groupName"] = to_snake_case(yaml_data["groupName"])
364
365
  yaml_data["name"] = yaml_data["name"].lower()
365
- yaml_data["name"] = self.pad_reserved_words(yaml_data["name"], PadType.METHOD)
366
+ if yaml_data.get("isLroInitialOperation") is True:
367
+ yaml_data["name"] = (
368
+ "_" + self.pad_reserved_words(extract_original_name(yaml_data["name"]), PadType.METHOD) + "_initial"
369
+ )
370
+ else:
371
+ yaml_data["name"] = self.pad_reserved_words(yaml_data["name"], PadType.METHOD)
366
372
  yaml_data["description"] = update_description(yaml_data["description"], yaml_data["name"])
367
373
  yaml_data["summary"] = update_description(yaml_data.get("summary", ""))
368
374
  body_parameter = yaml_data.get("bodyParameter")
@@ -53,9 +53,10 @@ basic_latin_chars = {
53
53
 
54
54
  class PadType(str, Enum):
55
55
  MODEL = "Model"
56
+ ENUM_CLASS = "Enum"
56
57
  METHOD = "_method"
57
58
  PARAMETER = "_parameter"
58
- ENUM = "_enum"
59
+ ENUM_VALUE = "_enum"
59
60
  PROPERTY = "_property"
60
61
  OPERATION_GROUP = "Operations"
61
62
 
@@ -175,9 +176,10 @@ RESERVED_WORDS = {
175
176
  "retry_on_status_codes",
176
177
  *_always_reserved,
177
178
  ],
178
- PadType.MODEL: [*_always_reserved],
179
+ PadType.MODEL: ["enum", *_always_reserved],
179
180
  PadType.PROPERTY: ["self", *_always_reserved],
180
- PadType.ENUM: ["mro", *_always_reserved],
181
+ PadType.ENUM_CLASS: ["enum", *_always_reserved],
182
+ PadType.ENUM_VALUE: ["mro", *_always_reserved],
181
183
  PadType.OPERATION_GROUP: [*_always_reserved],
182
184
  }
183
185
 
@@ -147,3 +147,7 @@ def build_policies(
147
147
  "self._config.logging_policy",
148
148
  ]
149
149
  return [p for p in policies if p]
150
+
151
+
152
+ def extract_original_name(name: str) -> str:
153
+ return name[1 : -len("_initial")]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autorest/python",
3
- "version": "6.15.0",
3
+ "version": "6.16.0",
4
4
  "description": "The Python extension for generators in AutoRest.",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -25,7 +25,7 @@
25
25
  "devDependencies": {
26
26
  "@microsoft.azure/autorest.testserver": "^3.3.46",
27
27
  "typescript": "~5.1.3",
28
- "@azure-tools/typespec-python": "^0.25.0"
28
+ "@azure-tools/typespec-python": "^0.26.0"
29
29
  },
30
30
  "files": [
31
31
  "autorest/**/*.py",