@autorest/python 5.16.0 → 5.19.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.
Files changed (96) hide show
  1. package/ChangeLog.md +79 -4
  2. package/README.md +30 -4
  3. package/autorest/__init__.py +1 -1
  4. package/autorest/codegen/__init__.py +55 -211
  5. package/autorest/codegen/models/__init__.py +116 -83
  6. package/autorest/codegen/models/base_builder.py +49 -88
  7. package/autorest/codegen/models/base_model.py +1 -1
  8. package/autorest/codegen/models/{base_schema.py → base_type.py} +61 -39
  9. package/autorest/codegen/models/client.py +165 -53
  10. package/autorest/codegen/models/code_model.py +122 -257
  11. package/autorest/codegen/models/combined_type.py +107 -0
  12. package/autorest/codegen/models/{constant_schema.py → constant_type.py} +49 -40
  13. package/autorest/codegen/models/credential_types.py +224 -0
  14. package/autorest/codegen/models/dictionary_type.py +131 -0
  15. package/autorest/codegen/models/enum_type.py +195 -0
  16. package/autorest/codegen/models/imports.py +80 -2
  17. package/autorest/codegen/models/list_type.py +149 -0
  18. package/autorest/codegen/models/lro_operation.py +79 -156
  19. package/autorest/codegen/models/lro_paging_operation.py +28 -11
  20. package/autorest/codegen/models/model_type.py +262 -0
  21. package/autorest/codegen/models/operation.py +331 -298
  22. package/autorest/codegen/models/operation_group.py +54 -91
  23. package/autorest/codegen/models/paging_operation.py +82 -123
  24. package/autorest/codegen/models/parameter.py +289 -396
  25. package/autorest/codegen/models/parameter_list.py +355 -360
  26. package/autorest/codegen/models/primitive_types.py +544 -0
  27. package/autorest/codegen/models/property.py +123 -139
  28. package/autorest/codegen/models/request_builder.py +130 -102
  29. package/autorest/codegen/models/request_builder_parameter.py +112 -100
  30. package/autorest/codegen/models/response.py +325 -0
  31. package/autorest/codegen/models/utils.py +12 -19
  32. package/autorest/codegen/serializers/__init__.py +55 -37
  33. package/autorest/codegen/serializers/builder_serializer.py +695 -1144
  34. package/autorest/codegen/serializers/client_serializer.py +92 -89
  35. package/autorest/codegen/serializers/general_serializer.py +15 -69
  36. package/autorest/codegen/serializers/import_serializer.py +7 -4
  37. package/autorest/codegen/serializers/metadata_serializer.py +15 -104
  38. package/autorest/codegen/serializers/model_base_serializer.py +49 -36
  39. package/autorest/codegen/serializers/model_generic_serializer.py +8 -6
  40. package/autorest/codegen/serializers/model_init_serializer.py +2 -4
  41. package/autorest/codegen/serializers/model_python3_serializer.py +22 -16
  42. package/autorest/codegen/serializers/operation_groups_serializer.py +7 -13
  43. package/autorest/codegen/serializers/parameter_serializer.py +174 -0
  44. package/autorest/codegen/serializers/request_builders_serializer.py +13 -30
  45. package/autorest/codegen/serializers/utils.py +0 -140
  46. package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
  47. package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +10 -7
  48. package/autorest/codegen/templates/config.py.jinja2 +13 -13
  49. package/autorest/codegen/templates/enum.py.jinja2 +4 -4
  50. package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
  51. package/autorest/codegen/templates/init.py.jinja2 +2 -2
  52. package/autorest/codegen/templates/lro_operation.py.jinja2 +4 -1
  53. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +4 -1
  54. package/autorest/codegen/templates/metadata.json.jinja2 +33 -33
  55. package/autorest/codegen/templates/model.py.jinja2 +23 -24
  56. package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
  57. package/autorest/codegen/templates/model_init.py.jinja2 +3 -5
  58. package/autorest/codegen/templates/operation.py.jinja2 +6 -8
  59. package/autorest/codegen/templates/operation_group.py.jinja2 +21 -8
  60. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +2 -2
  61. package/autorest/codegen/templates/operation_tools.jinja2 +11 -3
  62. package/autorest/codegen/templates/paging_operation.py.jinja2 +2 -2
  63. package/autorest/codegen/templates/request_builder.py.jinja2 +10 -15
  64. package/autorest/codegen/templates/request_builders.py.jinja2 +1 -1
  65. package/autorest/codegen/templates/serialization.py.jinja2 +2006 -0
  66. package/autorest/codegen/templates/setup.py.jinja2 +13 -3
  67. package/autorest/codegen/templates/vendor.py.jinja2 +11 -1
  68. package/autorest/jsonrpc/server.py +15 -3
  69. package/autorest/m4reformatter/__init__.py +1126 -0
  70. package/autorest/multiapi/models/client.py +12 -2
  71. package/autorest/multiapi/models/code_model.py +1 -1
  72. package/autorest/multiapi/serializers/__init__.py +18 -4
  73. package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
  74. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
  75. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +4 -4
  76. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
  77. package/autorest/postprocess/__init__.py +202 -0
  78. package/autorest/postprocess/get_all.py +19 -0
  79. package/autorest/postprocess/venvtools.py +73 -0
  80. package/autorest/preprocess/__init__.py +210 -0
  81. package/autorest/preprocess/helpers.py +54 -0
  82. package/autorest/{namer → preprocess}/python_mappings.py +21 -16
  83. package/package.json +2 -2
  84. package/autorest/codegen/models/credential_model.py +0 -55
  85. package/autorest/codegen/models/credential_schema.py +0 -95
  86. package/autorest/codegen/models/credential_schema_policy.py +0 -73
  87. package/autorest/codegen/models/dictionary_schema.py +0 -106
  88. package/autorest/codegen/models/enum_schema.py +0 -225
  89. package/autorest/codegen/models/list_schema.py +0 -135
  90. package/autorest/codegen/models/object_schema.py +0 -303
  91. package/autorest/codegen/models/primitive_schemas.py +0 -495
  92. package/autorest/codegen/models/request_builder_parameter_list.py +0 -249
  93. package/autorest/codegen/models/schema_request.py +0 -55
  94. package/autorest/codegen/models/schema_response.py +0 -141
  95. package/autorest/namer/__init__.py +0 -23
  96. package/autorest/namer/name_converter.py +0 -509
@@ -4,11 +4,10 @@
4
4
  # Licensed under the MIT License. See License.txt in the project root for
5
5
  # license information.
6
6
  # --------------------------------------------------------------------------
7
- from itertools import groupby
8
7
  import json
8
+ from abc import abstractmethod
9
9
  from collections import defaultdict
10
- from abc import abstractmethod, ABC
11
- from typing import Any, List, TypeVar, Dict, Union, Optional, cast
10
+ from typing import Any, Generic, List, Type, TypeVar, Dict, Union, Optional, cast
12
11
 
13
12
 
14
13
  from ..models import (
@@ -17,25 +16,45 @@ from ..models import (
17
16
  PagingOperation,
18
17
  LROOperation,
19
18
  LROPagingOperation,
20
- ObjectSchema,
21
- DictionarySchema,
22
- ListSchema,
23
- BaseSchema,
19
+ ModelType,
20
+ DictionaryType,
21
+ ListType,
24
22
  Parameter,
25
23
  RequestBuilder,
26
- RequestBuilderParameter,
27
- EnumSchema,
28
- SchemaResponse,
29
- IOSchema,
30
- ParameterStyle,
31
24
  ParameterLocation,
25
+ Response,
26
+ BinaryType,
27
+ BodyParameter,
32
28
  ParameterMethodLocation,
29
+ RequestBuilderBodyParameter,
30
+ OverloadedRequestBuilder,
31
+ ConstantType,
32
+ MultipartBodyParameter,
33
+ Property,
34
+ RequestBuilderType,
33
35
  )
36
+ from .parameter_serializer import ParameterSerializer, PopKwargType
34
37
  from . import utils
35
38
 
36
39
  T = TypeVar("T")
37
40
  OrderedSet = Dict[T, None]
38
41
 
42
+ BuilderType = TypeVar(
43
+ "BuilderType",
44
+ bound=Union[
45
+ RequestBuilder,
46
+ Operation,
47
+ PagingOperation,
48
+ LROOperation,
49
+ LROPagingOperation,
50
+ OverloadedRequestBuilder,
51
+ ],
52
+ )
53
+ OperationType = TypeVar(
54
+ "OperationType",
55
+ bound=Union[Operation, PagingOperation, LROOperation, LROPagingOperation],
56
+ )
57
+
39
58
 
40
59
  def _escape_str(input_str: str) -> str:
41
60
  replace = input_str.replace("'", "\\'")
@@ -65,247 +84,176 @@ def _json_dumps_template(template_representation: Any) -> Any:
65
84
  )
66
85
 
67
86
 
68
- def _content_type_error_check(builder) -> List[str]:
69
- retval = ["else:"]
70
- retval.append(" raise ValueError(")
87
+ def _get_polymorphic_subtype_template(polymorphic_subtype: ModelType) -> List[str]:
88
+ retval: List[str] = []
89
+ retval.append("")
71
90
  retval.append(
72
- " \"The content_type '{}' is not one of the allowed values: \""
91
+ f'# JSON input template for discriminator value "{polymorphic_subtype.discriminator_value}":'
92
+ )
93
+ subtype_template = _json_dumps_template(
94
+ polymorphic_subtype.get_json_template_representation(),
73
95
  )
74
- retval.append(f' "{builder.parameters.content_types}".format(content_type)')
75
- retval.append(" )")
76
- return retval
77
-
78
96
 
79
- def _serialize_files_and_data_body(builder, param_name: str) -> List[str]:
80
- retval: List[str] = []
81
- # we have to construct our form data before passing to the request as well
82
- retval.append("# Construct form data")
83
- retval.append(f"{param_name} = {{")
84
- for param in builder.parameters.body:
85
- retval.append(f' "{param.rest_api_name}": {param.serialized_name},')
86
- retval.append("}")
97
+ def _get_polymorphic_parent(
98
+ polymorphic_subtype: Optional[ModelType],
99
+ ) -> Optional[ModelType]:
100
+ if not polymorphic_subtype:
101
+ return None
102
+ try:
103
+ return next(
104
+ p for p in polymorphic_subtype.parents if p.discriminated_subtypes
105
+ )
106
+ except StopIteration:
107
+ return None
108
+
109
+ polymorphic_parent = _get_polymorphic_parent(polymorphic_subtype)
110
+ while _get_polymorphic_parent(polymorphic_parent):
111
+ polymorphic_parent = _get_polymorphic_parent(polymorphic_parent)
112
+ retval.extend(
113
+ f"{cast(ModelType, polymorphic_parent).snake_case_name} = {subtype_template}".splitlines()
114
+ )
87
115
  return retval
88
116
 
89
117
 
90
- def _serialize_grouped_body(builder) -> List[str]:
118
+ def _serialize_grouped_body(builder: BuilderType) -> List[str]:
91
119
  retval: List[str] = []
92
120
  for grouped_parameter in builder.parameters.grouped:
93
- retval.append(f"{grouped_parameter.serialized_name} = None")
94
- for grouper_name, grouped_parameters in groupby(
95
- builder.parameters.grouped,
96
- key=lambda a: cast(Parameter, a.grouped_by).serialized_name,
97
- ):
98
- retval.append(f"if {grouper_name} is not None:")
99
- for grouped_parameter in grouped_parameters:
100
- retval.append(
101
- f" {grouped_parameter.serialized_name} = "
102
- f"{ grouper_name }.{ grouped_parameter.corresponding_grouped_property.name }"
103
- )
121
+ retval.append(f"{grouped_parameter.client_name} = None")
122
+ groupers = [p for p in builder.parameters if p.grouper]
123
+ for grouper in groupers:
124
+ retval.append(f"if {grouper.client_name} is not None:")
125
+ retval.extend(
126
+ [
127
+ f" {parameter} = {grouper.client_name}.{property}"
128
+ for property, parameter in grouper.property_to_parameter_name.items()
129
+ ]
130
+ )
104
131
  return retval
105
132
 
106
133
 
107
- def _serialize_flattened_body(builder) -> List[str]:
134
+ def _serialize_flattened_body(body_parameter: BodyParameter) -> List[str]:
108
135
  retval: List[str] = []
109
- if not builder.parameters.is_flattened:
136
+ if not body_parameter.property_to_parameter_name:
110
137
  raise ValueError(
111
138
  "This method can't be called if the operation doesn't need parameter flattening"
112
139
  )
113
140
 
114
- parameters = builder.parameters.get_from_predicate(
115
- lambda parameter: parameter.in_method_code
116
- )
117
141
  parameter_string = ", ".join(
118
- [
119
- f"{param.target_property_name}={param.serialized_name}"
120
- for param in parameters
121
- if param.target_property_name
122
- ]
142
+ f"{property_name}={parameter_name}"
143
+ for property_name, parameter_name in body_parameter.property_to_parameter_name.items()
123
144
  )
124
- object_schema = cast(ObjectSchema, builder.parameters.body[0].schema)
145
+ model_type = cast(ModelType, body_parameter.type)
125
146
  retval.append(
126
- f"{builder.parameters.body[0].serialized_name} = _models.{object_schema.name}({parameter_string})"
147
+ f"{body_parameter.client_name} = _models.{model_type.name}({parameter_string})"
127
148
  )
128
149
  return retval
129
150
 
130
151
 
131
- def _content_type_docstring(builder) -> str:
132
- content_types = [f'"{c}"' for c in builder.parameters.content_types]
133
- if len(content_types) == 2:
134
- possible_values_str = " or ".join(content_types)
135
- else:
136
- possible_values_str = (
137
- ", ".join(content_types[: len(content_types) - 1])
138
- + f", and {content_types[-1]}"
139
- )
140
- default_value = next(
141
- p for p in builder.parameters.method if p.rest_api_name == "Content-Type"
142
- ).default_value_declaration
143
- return (
144
- ":keyword content_type: Media type of the body sent to the API. "
145
- + f"Known values are: {possible_values_str}. "
146
- + f"Default value is {default_value}."
147
- )
152
+ def _serialize_multipart_body(builder: BuilderType) -> List[str]:
153
+ retval: List[str] = []
154
+ body_param = cast(MultipartBodyParameter, builder.parameters.body_parameter)
155
+ # we have to construct our form data before passing to the request as well
156
+ retval.append("# Construct form data")
157
+ retval.append(f"_{body_param.client_name} = {{")
158
+ for param in body_param.entries:
159
+ retval.append(f' "{param.rest_api_name}": {param.client_name},')
160
+ retval.append("}")
161
+ return retval
162
+
163
+
164
+ def _get_json_response_template_to_status_codes(
165
+ builder: OperationType,
166
+ ) -> Dict[str, List[str]]:
167
+ retval = defaultdict(list)
168
+ for response in builder.responses:
169
+ json_template = response.get_json_template_representation()
170
+ if not json_template:
171
+ continue
172
+ status_codes = [str(status_code) for status_code in response.status_codes]
173
+ response_json = _json_dumps_template(json_template)
174
+ retval[response_json].extend(status_codes)
175
+ return retval
148
176
 
149
177
 
150
- class _BuilderSerializerProtocol(ABC):
178
+ class _BuilderBaseSerializer(Generic[BuilderType]): # pylint: disable=abstract-method
179
+ def __init__(
180
+ self, code_model: CodeModel, async_mode: bool, is_python3_file: bool
181
+ ) -> None:
182
+ self.code_model = code_model
183
+ self.async_mode = async_mode
184
+ self.is_python3_file = is_python3_file
185
+ self.parameter_serializer = ParameterSerializer()
186
+
151
187
  @property
152
188
  @abstractmethod
153
- def _is_in_class(self) -> bool:
189
+ def _need_self_param(self) -> bool:
154
190
  ...
155
191
 
156
192
  @property
157
193
  @abstractmethod
158
- def _function_definition(self) -> str:
194
+ def _function_def(self) -> str:
159
195
  """The def keyword for the builder we're serializing, i.e. 'def' or 'async def'"""
160
196
  ...
161
197
 
162
198
  @property
163
199
  @abstractmethod
164
- def _def(self) -> str:
165
- """The general definition of a function, i.e. def or async def"""
200
+ def _call_method(self) -> str:
201
+ """How to call network calls. Await if we have to await network calls"""
166
202
  ...
167
203
 
168
204
  @property
169
205
  @abstractmethod
170
- def _want_inline_type_hints(self) -> bool:
171
- """Whether you want inline type hints. If false, your type hints will be commented'"""
172
- ...
173
-
174
- @abstractmethod
175
- def _response_type_annotation(
176
- self, builder, modify_if_head_as_boolean: bool = True
177
- ) -> str:
178
- """The mypy type annotation for the response"""
179
- ...
180
-
181
- @abstractmethod
182
- def _response_type_annotation_wrapper(self, builder) -> List[str]:
183
- """Any wrappers that you want to go around the response type annotation"""
184
- ...
185
-
186
- @staticmethod
187
- @abstractmethod
188
- def _method_signature_and_response_type_annotation_template(
189
- method_signature: str, response_type_annotation: str
190
- ) -> str:
191
- """Template for how to combine the method signature + the response type annotation together. Called by
192
- method_signature_and_response_type_annotation"""
193
- ...
194
-
195
- @abstractmethod
196
- def decorators(self, builder, async_mode: bool) -> List[str]:
197
- """Decorators for the method"""
198
- ...
199
-
200
- @abstractmethod
201
- def method_signature_and_response_type_annotation(
202
- self, builder, async_mode: bool, *, want_decorators: Optional[bool] = True
203
- ) -> str:
204
- """Combines the method signature + the response type annotation together"""
205
- ...
206
-
207
- @abstractmethod
208
- def description_and_summary(self, builder) -> List[str]:
209
- """Description + summary from the swagger. Will be formatted into the overall operation description"""
206
+ def serializer_name(self) -> str:
210
207
  ...
211
208
 
212
209
  @abstractmethod
213
- def response_docstring(self, builder) -> List[str]:
210
+ def response_docstring(self, builder: BuilderType) -> List[str]:
214
211
  """Response portion of the docstring"""
215
212
  ...
216
213
 
217
- @abstractmethod
218
- def want_example_template(self, builder) -> bool:
219
- ...
220
-
221
- @abstractmethod
222
- def get_example_template(self, builder) -> List[str]:
223
- ...
224
-
225
- @abstractmethod
226
- def _get_json_example_template(self, builder) -> List[str]:
227
- ...
228
-
229
- @abstractmethod
230
- def _has_json_example_template(self, builder) -> bool:
231
- ...
232
-
233
- @abstractmethod
234
- def _json_example_param_name(self, builder) -> str:
235
- ...
236
-
237
- @abstractmethod
238
- def _get_json_response_template(self, builder) -> List[str]:
239
- ...
240
-
241
- @abstractmethod
242
- def _get_json_response_template_to_status_codes(
243
- self, builder
244
- ) -> Dict[str, List[str]]:
245
- ...
246
-
247
- @abstractmethod
248
- def _get_kwargs_to_pop(self, builder) -> List[Parameter]:
249
- ...
250
-
251
-
252
- class _BuilderBaseSerializer(
253
- _BuilderSerializerProtocol
254
- ): # pylint: disable=abstract-method
255
- def __init__(self, code_model: CodeModel) -> None:
256
- self.code_model = code_model
257
-
258
- @property
259
- def _cls_docstring_rtype(self) -> str:
260
- return (
261
- ""
262
- if self.code_model.options["version_tolerant"]
263
- else " or the result of cls(response)"
264
- )
265
-
266
- def decorators(self, builder, async_mode: bool) -> List[str]:
214
+ def decorators(self, builder: BuilderType) -> List[str]:
267
215
  """Decorators for the method"""
268
216
  retval: List[str] = []
217
+ if builder.is_overload:
218
+ return ["@overload"]
269
219
  if self.code_model.options["tracing"] and builder.want_tracing:
270
- retval.append(f"@distributed_trace{'_async' if async_mode else ''}")
220
+ retval.append(f"@distributed_trace{'_async' if self.async_mode else ''}")
271
221
  return retval
272
222
 
273
- def _method_signature(
274
- self, builder: Operation, response_type_annotation: str
275
- ) -> str:
276
- return utils.serialize_method(
277
- function_def=self._function_definition,
223
+ def _method_signature(self, builder: BuilderType) -> str:
224
+ return self.parameter_serializer.serialize_method(
225
+ function_def=self._function_def,
278
226
  method_name=builder.name,
279
- is_in_class=self._is_in_class,
227
+ need_self_param=self._need_self_param,
280
228
  method_param_signatures=builder.method_signature(
281
- self._want_inline_type_hints
229
+ self.async_mode or self.is_python3_file, self.async_mode
282
230
  ),
283
- ignore_inconsistent_return_statements=(response_type_annotation == "None"),
231
+ pylint_disable=builder.pylint_disable,
284
232
  )
285
233
 
286
- def _response_type_annotation_wrapper(self, builder) -> List[str]:
287
- return []
288
-
289
234
  def method_signature_and_response_type_annotation(
290
- self, builder, async_mode: bool, *, want_decorators: Optional[bool] = True
235
+ self, builder: BuilderType, *, want_decorators: Optional[bool] = True
291
236
  ) -> str:
292
- response_type_annotation = self._response_type_annotation(builder)
293
- # want pre-wrapped response type. As long as it's None, pylint will get mad about inconsistent return types
294
- method_signature = self._method_signature(builder, response_type_annotation)
295
- for wrapper in self._response_type_annotation_wrapper(builder)[::-1]:
296
- response_type_annotation = f"{wrapper}[{response_type_annotation}]"
297
- decorators = self.decorators(builder, async_mode)
237
+ response_type_annotation = builder.response_type_annotation(
238
+ async_mode=self.async_mode
239
+ )
240
+ method_signature = self._method_signature(builder)
241
+ decorators = self.decorators(builder)
298
242
  decorators_str = ""
299
243
  if decorators and want_decorators:
300
244
  decorators_str = "\n".join(decorators) + "\n"
301
245
  return (
302
246
  decorators_str
303
- + self._method_signature_and_response_type_annotation_template(
304
- method_signature, response_type_annotation
247
+ + utils.method_signature_and_response_type_annotation_template(
248
+ is_python3_file=self.is_python3_file,
249
+ method_signature=method_signature,
250
+ response_type_annotation=response_type_annotation,
305
251
  )
306
252
  )
307
253
 
308
- def description_and_summary(self, builder) -> List[str]:
254
+ def description_and_summary( # pylint: disable=no-self-use
255
+ self, builder: BuilderType
256
+ ) -> List[str]:
309
257
  description_list: List[str] = []
310
258
  description_list.append(
311
259
  f"{ builder.summary.strip() if builder.summary else builder.description.strip() }"
@@ -316,267 +264,195 @@ class _BuilderBaseSerializer(
316
264
  description_list.append("")
317
265
  return description_list
318
266
 
267
+ def example_template(self, builder: BuilderType) -> List[str]:
268
+ template = []
269
+ if builder.abstract:
270
+ return []
271
+ if self._json_input_example_template(builder):
272
+ template.append("")
273
+ template += self._json_input_example_template(builder)
274
+ return template
275
+
319
276
  def param_description( # pylint: disable=no-self-use
320
- self, builder: Union[RequestBuilder, Operation]
277
+ self, builder: BuilderType
321
278
  ) -> List[str]:
322
279
  description_list: List[str] = []
323
- for param in [
324
- m
325
- for m in builder.parameters.method
326
- if m.method_location != ParameterMethodLocation.HIDDEN_KWARG
327
- ]:
280
+ for param in builder.parameters.method:
281
+ if not param.in_docstring:
282
+ continue
328
283
  description_list.extend(
329
- f":{param.description_keyword} { param.serialized_name }: { param.description }".replace(
284
+ f":{param.description_keyword} { param.client_name }: { param.description }".replace(
330
285
  "\n", "\n "
331
286
  ).split(
332
287
  "\n"
333
288
  )
334
289
  )
290
+ docstring_type = param.docstring_type(async_mode=self.async_mode)
335
291
  description_list.append(
336
- f":{param.docstring_type_keyword} { param.serialized_name }: { param.docstring_type }"
292
+ f":{param.docstring_type_keyword} {param.client_name}: {docstring_type}"
337
293
  )
338
-
339
- if len(builder.parameters.content_types) > 1:
340
- description_list = [
341
- _content_type_docstring(builder)
342
- if l.startswith(":keyword content_type:")
343
- else l
344
- for l in description_list
345
- ]
346
- if not any(
347
- l for l in description_list if l.startswith(":keyword content_type:")
348
- ):
349
- description_list.append(_content_type_docstring(builder))
350
294
  return description_list
351
295
 
352
- def param_description_and_response_docstring(self, builder) -> List[str]:
296
+ def param_description_and_response_docstring(
297
+ self, builder: BuilderType
298
+ ) -> List[str]:
353
299
  if builder.abstract:
354
300
  return []
355
301
  return self.param_description(builder) + self.response_docstring(builder)
356
302
 
357
- def _get_json_response_template_to_status_codes(
358
- self, builder
359
- ) -> Dict[str, List[str]]:
360
- # successful status codes of responses that have bodies
361
- responses = [
362
- response
363
- for response in builder.responses
364
- if any(
365
- code in builder.success_status_code for code in response.status_codes
366
- )
367
- and isinstance(
368
- response.schema,
369
- (DictionarySchema, ListSchema, ObjectSchema, EnumSchema),
370
- )
371
- ]
372
- retval = defaultdict(list)
373
- for response in responses:
374
- status_codes = [str(status_code) for status_code in response.status_codes]
375
- response_json = _json_dumps_template(
376
- cast(BaseSchema, response.schema).get_json_template_representation()
377
- )
378
- retval[response_json].extend(status_codes)
379
- return retval
380
-
381
- def get_example_template(self, builder) -> List[str]:
382
- template = []
383
- if self._has_json_example_template(builder):
384
- template.append("")
385
- template += self._get_json_example_template(builder)
386
- if self._get_json_response_template_to_status_codes(builder):
387
- template.append("")
388
- template += self._get_json_response_template(builder)
389
- return template
303
+ @property
304
+ @abstractmethod
305
+ def _json_response_template_name(self) -> str:
306
+ ...
390
307
 
391
- def _get_json_example_template(self, builder) -> List[str]:
392
- template = []
393
- json_body = builder.parameters.json_body
394
- object_schema = cast(ObjectSchema, json_body)
395
- try:
396
- discriminator_name = object_schema.discriminator_name
397
- subtype_map = object_schema.subtype_map
398
- except AttributeError:
399
- discriminator_name = None
400
- subtype_map = None
401
- if subtype_map:
308
+ def _json_input_example_template(self, builder: BuilderType) -> List[str]:
309
+ template: List[str] = []
310
+ if self.code_model.options["models_mode"]:
311
+ # No input template if we have models
312
+ return template
313
+ if (
314
+ not builder.parameters.has_body
315
+ or builder.parameters.body_parameter.flattened
316
+ ):
317
+ # No input template if now body parameter
318
+ return template
319
+ if builder.overloads:
320
+ # if there's overloads, we do the json input example template on the overload
321
+ return template
322
+
323
+ body_param = builder.parameters.body_parameter
324
+ if not isinstance(body_param.type, (ListType, DictionaryType, ModelType)):
325
+ return template
326
+
327
+ polymorphic_subtypes: List[ModelType] = []
328
+ body_param.type.get_polymorphic_subtypes(polymorphic_subtypes)
329
+ if polymorphic_subtypes:
330
+ # we just assume one kind of polymorphic body for input
331
+ discriminator_name = cast(
332
+ Property, polymorphic_subtypes[0].discriminator
333
+ ).rest_api_name
402
334
  template.append(
403
- "{} = '{}'".format(
404
- discriminator_name, "' or '".join(subtype_map.values())
405
- )
335
+ "# The input is polymorphic. The following are possible polymorphic "
336
+ f'inputs based off discriminator "{discriminator_name}":'
406
337
  )
407
- template.append("")
408
-
409
- try:
410
- property_with_discriminator = object_schema.property_with_discriminator
411
- except AttributeError:
412
- property_with_discriminator = None
413
- if property_with_discriminator:
414
- polymorphic_schemas = [
415
- s
416
- for s in self.code_model.sorted_schemas
417
- if s.name in property_with_discriminator.schema.subtype_map.values()
418
- ]
419
- num_schemas = min(
420
- self.code_model.options["polymorphic_examples"],
421
- len(polymorphic_schemas),
422
- )
423
- for i in range(num_schemas):
424
- schema = polymorphic_schemas[i]
425
- polymorphic_property = _json_dumps_template(
426
- schema.get_json_template_representation(),
338
+ for idx in range(
339
+ min(
340
+ self.code_model.options["polymorphic_examples"],
341
+ len(polymorphic_subtypes),
427
342
  )
343
+ ):
428
344
  template.extend(
429
- f"{property_with_discriminator.name} = {polymorphic_property}".splitlines()
345
+ _get_polymorphic_subtype_template(polymorphic_subtypes[idx])
430
346
  )
431
- if i != num_schemas - 1:
432
- template.append("# OR")
433
347
  template.append("")
434
348
  template.append(
435
349
  "# JSON input template you can fill out and use as your body input."
436
350
  )
437
351
  json_template = _json_dumps_template(
438
- builder.parameters.json_body.get_json_template_representation(),
352
+ body_param.type.get_json_template_representation(),
439
353
  )
440
354
  template.extend(
441
- f"{self._json_example_param_name(builder)} = {json_template}".splitlines()
355
+ f"{builder.parameters.body_parameter.client_name} = {json_template}".splitlines()
442
356
  )
443
357
  return template
444
358
 
445
- @property
446
- @abstractmethod
447
- def serializer_name(self) -> str:
448
- ...
449
-
450
359
  def _serialize_parameter(self, param: Parameter, kwarg_name: str) -> List[str]:
451
- function_name = "header" if kwarg_name == "headers" else "query"
452
360
  set_parameter = "_{}['{}'] = {}".format(
453
361
  kwarg_name,
454
362
  param.rest_api_name,
455
- utils.build_serialize_data_call(param, function_name, self.serializer_name),
363
+ self.parameter_serializer.serialize_parameter(param, self.serializer_name),
456
364
  )
457
- if param.required:
365
+ if not param.optional:
458
366
  retval = [set_parameter]
459
367
  else:
460
368
  retval = [
461
- f"if {param.full_serialized_name} is not None:",
369
+ f"if {param.full_client_name} is not None:",
462
370
  f" {set_parameter}",
463
371
  ]
464
372
  return retval
465
373
 
466
- def _get_json_response_template(self, builder) -> List[str]:
467
- template = []
468
- for (
469
- response_body,
470
- status_codes,
471
- ) in self._get_json_response_template_to_status_codes(builder).items():
472
- template.append(
473
- "# response body for status code(s): {}".format(", ".join(status_codes))
474
- )
475
- template.extend(f"response.json() == {response_body}".splitlines())
476
- return template
477
-
478
- def serialize_path(self, builder) -> List[str]:
479
- return utils.serialize_path(builder.parameters.path, self.serializer_name)
480
-
481
- @property
482
- def _function_definition(self) -> str:
483
- return self._def
374
+ def serialize_path(self, builder: BuilderType) -> List[str]:
375
+ return self.parameter_serializer.serialize_path(
376
+ builder.parameters.path, self.serializer_name
377
+ )
484
378
 
485
379
 
486
380
  ############################## REQUEST BUILDERS ##############################
487
381
 
488
382
 
489
- class _RequestBuilderBaseSerializer(
490
- _BuilderBaseSerializer
383
+ class RequestBuilderSerializer(
384
+ _BuilderBaseSerializer[RequestBuilderType]
491
385
  ): # pylint: disable=abstract-method
492
- def description_and_summary(self, builder) -> List[str]:
386
+ def description_and_summary(self, builder: RequestBuilderType) -> List[str]:
493
387
  retval = super().description_and_summary(builder)
494
388
  retval += [
495
- "See https://aka.ms/azsdk/python/protocol/quickstart for how to incorporate this "
389
+ "See https://aka.ms/azsdk/dpcodegen/python/send_request for how to incorporate this "
496
390
  "request builder into your code flow.",
497
391
  "",
498
392
  ]
499
393
  return retval
500
394
 
395
+ @property
396
+ def _call_method(self) -> str:
397
+ return ""
398
+
501
399
  @property
502
400
  def serializer_name(self) -> str:
503
401
  return "_SERIALIZER"
504
402
 
403
+ @property
404
+ def _json_response_template_name(self) -> str:
405
+ return "response.json()"
406
+
505
407
  @staticmethod
506
- def declare_non_inputtable_constants(builder) -> List[str]:
507
- def _get_value(param: Parameter):
508
- if param.location in [ParameterLocation.Header, ParameterLocation.Query]:
408
+ def declare_non_inputtable_constants(builder: RequestBuilderType) -> List[str]:
409
+ def _get_value(param):
410
+ param_type = cast(ConstantType, param.type)
411
+ if param.location in [ParameterLocation.HEADER, ParameterLocation.QUERY]:
509
412
  kwarg_dict = (
510
413
  "headers"
511
- if param.location == ParameterLocation.Header
414
+ if param.location == ParameterLocation.HEADER
512
415
  else "params"
513
416
  )
514
- return f"_{kwarg_dict}.pop('{param.rest_api_name}', {param.constant_declaration})"
515
- return f"{param.constant_declaration}"
417
+ return f"_{kwarg_dict}.pop('{param.rest_api_name}', {param_type.get_declaration()})"
418
+ return f"{param_type.get_declaration()}"
516
419
 
517
420
  return [
518
- f"{p.serialized_name} = {_get_value(p)}"
421
+ f"{p.client_name} = {_get_value(p)}"
519
422
  for p in builder.parameters.constant
520
- if p.original_parameter is None
521
- and p.in_method_code
522
- and not p.in_method_signature
423
+ if not p.in_method_signature
523
424
  ]
524
425
 
525
- def want_example_template(self, builder) -> bool:
526
- if builder.abstract:
527
- return False
528
- if self.code_model.options["builders_visibility"] != "public":
529
- return False # if we're not exposing rest layer, don't need to generate
530
- if builder.parameters.has_body:
531
- body_kwargs = set(builder.parameters.body_kwarg_names.keys())
532
- return bool(body_kwargs.intersection({"json", "files", "data"}))
533
- return bool(self._get_json_response_template_to_status_codes(builder))
534
-
535
426
  @property
536
- def _def(self) -> str:
427
+ def _function_def(self) -> str:
537
428
  return "def"
538
429
 
539
430
  @property
540
- def _is_in_class(self) -> bool:
431
+ def _need_self_param(self) -> bool:
541
432
  return False
542
433
 
543
- def _response_type_annotation(
544
- self, builder, modify_if_head_as_boolean: bool = True
545
- ) -> str:
546
- return "HttpRequest"
547
-
548
- def response_docstring(self, builder) -> List[str]:
434
+ def response_docstring(self, builder: RequestBuilderType) -> List[str]:
549
435
  response_str = (
550
436
  f":return: Returns an :class:`~azure.core.rest.HttpRequest` that you will pass to the client's "
551
- + "`send_request` method. See https://aka.ms/azsdk/python/protocol/quickstart for how to "
437
+ + "`send_request` method. See https://aka.ms/azsdk/dpcodegen/python/send_request for how to "
552
438
  + "incorporate this response into your code flow."
553
439
  )
554
440
  rtype_str = f":rtype: ~azure.core.rest.HttpRequest"
555
441
  return [response_str, rtype_str]
556
442
 
557
- def _json_example_param_name(self, builder) -> str:
558
- return "json"
559
-
560
- def _has_json_example_template(self, builder) -> bool:
561
- return "json" in builder.parameters.body_kwarg_names
562
-
563
- @abstractmethod
564
- def _body_params_to_pass_to_request_creation(self, builder) -> List[str]:
565
- ...
566
-
567
- def pop_kwargs_from_signature(self, builder) -> List[str]:
568
- return utils.pop_kwargs_from_signature(
569
- self._get_kwargs_to_pop(builder),
443
+ def pop_kwargs_from_signature(self, builder: RequestBuilderType) -> List[str]:
444
+ return self.parameter_serializer.pop_kwargs_from_signature(
445
+ builder.parameters.kwargs_to_pop(is_python3_file=self.is_python3_file),
570
446
  check_kwarg_dict=True,
571
- pop_headers_kwarg=utils.PopKwargType.CASE_INSENSITIVE
447
+ pop_headers_kwarg=PopKwargType.CASE_INSENSITIVE
572
448
  if bool(builder.parameters.headers)
573
- else utils.PopKwargType.NO,
574
- pop_params_kwarg=utils.PopKwargType.CASE_INSENSITIVE
449
+ else PopKwargType.NO,
450
+ pop_params_kwarg=PopKwargType.CASE_INSENSITIVE
575
451
  if bool(builder.parameters.query)
576
- else utils.PopKwargType.NO,
452
+ else PopKwargType.NO,
577
453
  )
578
454
 
579
- def create_http_request(self, builder) -> List[str]:
455
+ def create_http_request(self, builder: RequestBuilderType) -> List[str]:
580
456
  retval = ["return HttpRequest("]
581
457
  retval.append(f' method="{builder.method}",')
582
458
  retval.append(" url=_url,")
@@ -584,20 +460,25 @@ class _RequestBuilderBaseSerializer(
584
460
  retval.append(" params=_params,")
585
461
  if builder.parameters.headers:
586
462
  retval.append(" headers=_headers,")
587
- if builder.parameters.has_body:
588
- retval.extend(
589
- [
590
- f" {body_kwarg}={body_kwarg},"
591
- for body_kwarg in self._body_params_to_pass_to_request_creation(
592
- builder
593
- )
594
- ]
595
- )
463
+ if (
464
+ builder.parameters.has_body
465
+ and builder.parameters.body_parameter.in_method_signature
466
+ ):
467
+ body_param = builder.parameters.body_parameter
468
+ if body_param.constant or (
469
+ self.is_python3_file
470
+ and body_param.method_location != ParameterMethodLocation.KWARG
471
+ ):
472
+ # we only need to pass it through if it's not a kwarg or it's a popped kwarg
473
+ retval.append(
474
+ f" {builder.parameters.body_parameter.client_name}="
475
+ f"{builder.parameters.body_parameter.client_name},"
476
+ )
596
477
  retval.append(" **kwargs")
597
478
  retval.append(")")
598
479
  return retval
599
480
 
600
- def serialize_headers(self, builder) -> List[str]:
481
+ def serialize_headers(self, builder: RequestBuilderType) -> List[str]:
601
482
  retval = ["# Construct headers"]
602
483
  for parameter in builder.parameters.headers:
603
484
  retval.extend(
@@ -608,7 +489,7 @@ class _RequestBuilderBaseSerializer(
608
489
  )
609
490
  return retval
610
491
 
611
- def serialize_query(self, builder) -> List[str]:
492
+ def serialize_query(self, builder: RequestBuilderType) -> List[str]:
612
493
  retval = ["# Construct parameters"]
613
494
  for parameter in builder.parameters.query:
614
495
  retval.extend(
@@ -619,7 +500,7 @@ class _RequestBuilderBaseSerializer(
619
500
  )
620
501
  return retval
621
502
 
622
- def construct_url(self, builder) -> str:
503
+ def construct_url(self, builder: RequestBuilderType) -> str:
623
504
  if any(
624
505
  o
625
506
  for o in ["low_level_client", "version_tolerant"]
@@ -631,74 +512,13 @@ class _RequestBuilderBaseSerializer(
631
512
  return f"_url = {url_value}{' # pylint: disable=line-too-long' if len(url_value) > 114 else ''}"
632
513
 
633
514
 
634
- class RequestBuilderGenericSerializer(_RequestBuilderBaseSerializer):
635
- @property
636
- def _want_inline_type_hints(self) -> bool:
637
- return False
638
-
639
- @staticmethod
640
- def _method_signature_and_response_type_annotation_template(
641
- method_signature: str, response_type_annotation: str
642
- ):
643
- return utils.method_signature_and_response_type_annotation_template(
644
- is_python3_file=False,
645
- method_signature=method_signature,
646
- response_type_annotation=response_type_annotation,
647
- )
648
-
649
- def _get_kwargs_to_pop(self, builder):
650
- return builder.parameters.kwargs_to_pop(is_python3_file=False)
651
-
652
- def _body_params_to_pass_to_request_creation(self, builder) -> List[str]:
653
- if any(
654
- b
655
- for b in builder.parameters.body
656
- if b.constant and not (b.is_data_input or b.is_multipart)
657
- ):
658
- # this means we have a constant body
659
- # only doing json body in this case
660
- return ["json"]
661
- return []
662
-
663
-
664
- class RequestBuilderPython3Serializer(_RequestBuilderBaseSerializer):
665
- @property
666
- def _want_inline_type_hints(self) -> bool:
667
- return True
668
-
669
- @staticmethod
670
- def _method_signature_and_response_type_annotation_template(
671
- method_signature: str, response_type_annotation: str
672
- ):
673
- return utils.method_signature_and_response_type_annotation_template(
674
- is_python3_file=True,
675
- method_signature=method_signature,
676
- response_type_annotation=response_type_annotation,
677
- )
678
-
679
- def _get_kwargs_to_pop(self, builder):
680
- return builder.parameters.kwargs_to_pop(is_python3_file=True)
681
-
682
- def _body_params_to_pass_to_request_creation(self, builder) -> List[str]:
683
- body_kwargs = list(builder.parameters.body_kwarg_names.keys())
684
- if body_kwargs:
685
- return body_kwargs
686
- if any(
687
- b
688
- for b in builder.parameters.body
689
- if b.constant and not (b.is_data_input or b.is_multipart)
690
- ):
691
- return ["json"]
692
- return body_kwargs
693
-
694
-
695
515
  ############################## NORMAL OPERATIONS ##############################
696
516
 
697
517
 
698
- class _OperationBaseSerializer(
699
- _BuilderBaseSerializer
518
+ class _OperationSerializer(
519
+ _BuilderBaseSerializer[OperationType]
700
520
  ): # pylint: disable=abstract-method
701
- def description_and_summary(self, builder) -> List[str]:
521
+ def description_and_summary(self, builder: OperationType) -> List[str]:
702
522
  retval = super().description_and_summary(builder)
703
523
  if builder.deprecated:
704
524
  retval.append(".. warning::")
@@ -707,26 +527,82 @@ class _OperationBaseSerializer(
707
527
  return retval
708
528
 
709
529
  @property
710
- def _is_in_class(self) -> bool:
530
+ def _json_response_template_name(self) -> str:
531
+ return "response"
532
+
533
+ def example_template(self, builder: OperationType) -> List[str]:
534
+ retval = super().example_template(builder)
535
+ if self.code_model.options["models_mode"]:
536
+ return retval
537
+ for response in builder.responses:
538
+ polymorphic_subtypes: List[ModelType] = []
539
+ if not response.type:
540
+ continue
541
+ response.type.get_polymorphic_subtypes(polymorphic_subtypes)
542
+ if polymorphic_subtypes:
543
+ # we just assume one kind of polymorphic body for input
544
+ discriminator_name = cast(
545
+ Property, polymorphic_subtypes[0].discriminator
546
+ ).rest_api_name
547
+ retval.append(
548
+ "# The response is polymorphic. The following are possible polymorphic "
549
+ f'responses based off discriminator "{discriminator_name}":'
550
+ )
551
+ for idx in range(
552
+ min(
553
+ self.code_model.options["polymorphic_examples"],
554
+ len(polymorphic_subtypes),
555
+ )
556
+ ):
557
+ retval.extend(
558
+ _get_polymorphic_subtype_template(polymorphic_subtypes[idx])
559
+ )
560
+
561
+ if _get_json_response_template_to_status_codes(builder):
562
+ retval.append("")
563
+ for (
564
+ response_body,
565
+ status_codes,
566
+ ) in _get_json_response_template_to_status_codes(builder).items():
567
+ retval.append(
568
+ "# response body for status code(s): {}".format(
569
+ ", ".join(status_codes)
570
+ )
571
+ )
572
+ retval.extend(
573
+ f"{self._json_response_template_name} == {response_body}".splitlines()
574
+ )
575
+ return retval
576
+
577
+ def make_pipeline_call(self, builder: OperationType) -> List[str]:
578
+ return [
579
+ f"pipeline_response = {self._call_method}self._client._pipeline.run( # type: ignore # pylint: disable=protected-access",
580
+ " request,",
581
+ f" stream={builder.has_stream_response},",
582
+ " **kwargs",
583
+ ")",
584
+ ]
585
+
586
+ @property
587
+ def _function_def(self) -> str:
588
+ return "async def" if self.async_mode else "def"
589
+
590
+ @property
591
+ def _need_self_param(self) -> bool:
711
592
  return True
712
593
 
713
594
  @property
714
595
  def serializer_name(self) -> str:
715
596
  return "self._serialize"
716
597
 
717
- def decorators(self, builder, async_mode: bool) -> List[str]:
598
+ def decorators(self, builder: OperationType) -> List[str]:
718
599
  """Decorators for the method"""
719
- super_decorators = super().decorators(builder, async_mode)
720
- if builder.abstract:
721
- super_decorators.append("@abc.abstractmethod")
600
+ super_decorators = super().decorators(builder)
722
601
  return super_decorators
723
602
 
724
- def _response_docstring_type_wrapper( # pylint: disable=unused-argument, no-self-use
725
- self, builder
726
- ) -> List[str]:
727
- return []
728
-
729
- def param_description(self, builder) -> List[str]: # pylint: disable=no-self-use
603
+ def param_description(
604
+ self, builder: OperationType
605
+ ) -> List[str]: # pylint: disable=no-self-use
730
606
  description_list = super().param_description(builder)
731
607
  if not self.code_model.options["version_tolerant"]:
732
608
  description_list.append(
@@ -734,308 +610,261 @@ class _OperationBaseSerializer(
734
610
  )
735
611
  return description_list
736
612
 
737
- def _response_docstring_type_template(self, builder) -> str:
738
- retval = "{}"
739
- for wrapper in self._response_docstring_type_wrapper(builder)[::-1]:
740
- retval = f"{wrapper}[{retval}]"
741
- return retval
742
-
743
- def _response_type_annotation(
744
- self, builder, modify_if_head_as_boolean: bool = True
745
- ) -> str:
746
- if (
747
- modify_if_head_as_boolean
748
- and builder.request_builder.method.lower() == "head"
749
- and self.code_model.options["head_as_boolean"]
750
- ):
751
- return "bool"
752
- response_body_annotations: OrderedSet[str] = {}
753
- for response in [r for r in builder.responses if r.has_body]:
754
- response_body_annotations[
755
- response.type_annotation(is_operation_file=True)
756
- ] = None
757
- response_str = ", ".join(response_body_annotations.keys()) or "None"
758
- if len(response_body_annotations) > 1:
759
- response_str = f"Union[{response_str}]"
760
- if builder.has_optional_return_type:
761
- response_str = f"Optional[{response_str}]"
762
- return response_str
763
-
764
- def pop_kwargs_from_signature(self, builder) -> List[str]:
765
- kwargs_to_pop = self._get_kwargs_to_pop(builder)
766
- kwargs = utils.pop_kwargs_from_signature(
613
+ def pop_kwargs_from_signature(self, builder: OperationType) -> List[str]:
614
+ kwargs_to_pop = builder.parameters.kwargs_to_pop(
615
+ is_python3_file=self.is_python3_file
616
+ )
617
+ kwargs = self.parameter_serializer.pop_kwargs_from_signature(
767
618
  kwargs_to_pop,
768
619
  check_kwarg_dict=True,
769
- pop_headers_kwarg=utils.PopKwargType.CASE_INSENSITIVE
620
+ pop_headers_kwarg=PopKwargType.CASE_INSENSITIVE
770
621
  if builder.has_kwargs_to_pop_with_default(
771
- kwargs_to_pop, ParameterLocation.Header
622
+ kwargs_to_pop, ParameterLocation.HEADER
772
623
  )
773
- else utils.PopKwargType.SIMPLE,
774
- pop_params_kwarg=utils.PopKwargType.CASE_INSENSITIVE
624
+ else PopKwargType.SIMPLE,
625
+ pop_params_kwarg=PopKwargType.CASE_INSENSITIVE
775
626
  if builder.has_kwargs_to_pop_with_default(
776
- kwargs_to_pop, ParameterLocation.Query
627
+ kwargs_to_pop, ParameterLocation.QUERY
777
628
  )
778
- else utils.PopKwargType.SIMPLE,
629
+ else PopKwargType.SIMPLE,
630
+ check_client_input=not self.code_model.options["multiapi"],
779
631
  )
780
632
  kwargs.append(
781
633
  f"cls = kwargs.pop('cls', None) {self.cls_type_annotation(builder)}"
782
634
  )
783
635
  return kwargs
784
636
 
785
- def cls_type_annotation(self, builder) -> str:
786
- return f"# type: ClsType[{self._response_type_annotation(builder, modify_if_head_as_boolean=False)}]"
637
+ def cls_type_annotation(self, builder: OperationType) -> str:
638
+ return f"# type: {builder.cls_type_annotation(async_mode=self.async_mode)}"
787
639
 
788
- def _response_docstring_text_template( # pylint: disable=no-self-use, unused-argument
789
- self, builder
790
- ) -> str:
791
- cls_str = f",{self._cls_docstring_rtype}" if self._cls_docstring_rtype else ""
792
- return "{}" + cls_str
793
-
794
- def response_docstring(self, builder) -> List[str]:
795
- responses_with_body = [r for r in builder.responses if r.has_body]
796
- if (
797
- builder.request_builder.method.lower() == "head"
798
- and self.code_model.options["head_as_boolean"]
799
- ):
800
- response_docstring_text = "bool"
801
- rtype = "bool"
802
- elif responses_with_body:
803
- response_body_docstring_text: OrderedSet[str] = {
804
- response.docstring_text: None for response in responses_with_body
805
- }
806
- response_docstring_text = " or ".join(response_body_docstring_text.keys())
807
- response_body_docstring_type: OrderedSet[str] = {
808
- response.docstring_type: None for response in responses_with_body
809
- }
810
- rtype = " or ".join(response_body_docstring_type.keys())
811
- if builder.has_optional_return_type:
812
- rtype += " or None"
813
- else:
814
- response_docstring_text = "None"
815
- rtype = "None"
816
- response_str = f":return: {self._response_docstring_text_template(builder).format(response_docstring_text)}"
640
+ def response_docstring(self, builder: OperationType) -> List[str]:
641
+ response_str = (
642
+ f":return: {builder.response_docstring_text(async_mode=self.async_mode)}"
643
+ )
817
644
  rtype_str = (
818
- f":rtype: {self._response_docstring_type_template(builder).format(rtype)}"
645
+ f":rtype: {builder.response_docstring_type(async_mode=self.async_mode)}"
819
646
  )
820
647
  return [
821
648
  response_str,
822
649
  rtype_str,
823
- ":raises: ~azure.core.exceptions.HttpResponseError",
650
+ ":raises ~azure.core.exceptions.HttpResponseError:",
824
651
  ]
825
652
 
826
- def want_example_template(self, builder) -> bool:
827
- if builder.abstract:
828
- return False
829
- if self.code_model.options["models_mode"]:
830
- return False
831
- if builder.parameters.has_body:
832
- body_params = builder.parameters.body
833
- return any(
834
- [
835
- b
836
- for b in body_params
837
- if isinstance(
838
- b.schema, (DictionarySchema, ListSchema, ObjectSchema)
839
- )
840
- ]
841
- )
842
- return bool(self._get_json_response_template_to_status_codes(builder))
843
-
844
- def _json_example_param_name(self, builder) -> str:
845
- return builder.parameters.body[0].serialized_name
846
-
847
- def _has_json_example_template(self, builder) -> bool:
848
- return builder.parameters.has_body
653
+ def _serialize_body_parameter(self, builder: OperationType) -> List[str]:
654
+ """We need to serialize params if they're not meant to be streamed in.
849
655
 
850
- def _serialize_body_call(
851
- self,
852
- builder,
853
- body_param: Parameter,
854
- send_xml: bool,
855
- ser_ctxt: Optional[str],
856
- ser_ctxt_name: str,
857
- ) -> str:
858
- body_is_xml = ", is_xml=True" if send_xml else ""
859
- pass_ser_ctxt = f", {ser_ctxt_name}={ser_ctxt_name}" if ser_ctxt else ""
860
- body_kwarg_to_pass = builder.body_kwargs_to_pass_to_request_builder[0]
656
+ This function serializes the body params that need to be serialized.
657
+ """
658
+ retval: List[str] = []
659
+ body_param = cast(BodyParameter, builder.parameters.body_parameter)
660
+ body_kwarg_name = builder.request_builder.parameters.body_parameter.client_name
661
+ send_xml = builder.parameters.body_parameter.type.is_xml
662
+ xml_serialization_ctxt = (
663
+ body_param.type.xml_serialization_ctxt if send_xml else None
664
+ )
665
+ ser_ctxt_name = "serialization_ctxt"
666
+ if xml_serialization_ctxt and self.code_model.options["models_mode"]:
667
+ retval.append(f'{ser_ctxt_name} = {{"xml": {{{xml_serialization_ctxt}}}}}')
861
668
  if self.code_model.options["models_mode"]:
862
- return (
863
- f"_{body_kwarg_to_pass} = self._serialize.body({body_param.serialized_name}, "
864
- f"'{ body_param.serialization_type }'{body_is_xml}{ pass_ser_ctxt })"
669
+ is_xml_cmd = ", is_xml=True" if send_xml else ""
670
+ serialization_ctxt_cmd = (
671
+ f", {ser_ctxt_name}={ser_ctxt_name}" if xml_serialization_ctxt else ""
672
+ )
673
+ create_body_call = (
674
+ f"_{body_kwarg_name} = self._serialize.body({body_param.client_name}, "
675
+ f"'{body_param.type.serialization_type}'{is_xml_cmd}{serialization_ctxt_cmd})"
865
676
  )
866
- return f"_{body_kwarg_to_pass} = {body_param.serialized_name}"
677
+ else:
678
+ create_body_call = f"_{body_kwarg_name} = {body_param.client_name}"
679
+ if body_param.optional:
680
+ retval.append(f"if {body_param.client_name} is not None:")
681
+ retval.append(" " + create_body_call)
682
+ retval.append("else:")
683
+ retval.append(f" _{body_kwarg_name} = None")
684
+ else:
685
+ retval.append(create_body_call)
686
+ return retval
867
687
 
868
- def _serialize_body(
869
- self, builder, body_param: Parameter, body_kwarg: str
688
+ def _create_body_parameter(
689
+ self,
690
+ builder: OperationType,
870
691
  ) -> List[str]:
692
+ """Create the body parameter before we pass it as either json or content to the request builder"""
871
693
  retval = []
872
- send_xml = bool(
873
- builder.parameters.has_body
874
- and any(["xml" in ct for ct in builder.parameters.content_types])
875
- and not isinstance(body_param.schema, IOSchema)
876
- )
877
- ser_ctxt_name = "serialization_ctxt"
878
- ser_ctxt = (
879
- builder.parameters.body[0].xml_serialization_ctxt if send_xml else None
880
- )
881
- if ser_ctxt and self.code_model.options["models_mode"]:
882
- retval.append(f'{ser_ctxt_name} = {{"xml": {{{ser_ctxt}}}}}')
883
- serialize_body_call = self._serialize_body_call(
884
- builder,
885
- body_param,
886
- send_xml,
887
- ser_ctxt,
888
- ser_ctxt_name,
889
- )
890
- if body_param.required:
891
- retval.append(serialize_body_call)
694
+ body_param = cast(BodyParameter, builder.parameters.body_parameter)
695
+ if hasattr(body_param, "entries"):
696
+ return _serialize_multipart_body(builder)
697
+ body_kwarg_name = builder.request_builder.parameters.body_parameter.client_name
698
+ if isinstance(body_param.type, BinaryType):
699
+ retval.append(f"_{body_kwarg_name} = {body_param.client_name}")
700
+ if (
701
+ not body_param.default_content_type
702
+ and not next(
703
+ p for p in builder.parameters if p.rest_api_name == "Content-Type"
704
+ ).optional
705
+ ):
706
+ content_types = "'" + "', '".join(body_param.content_types) + "'"
707
+ retval.extend(
708
+ [
709
+ "if not content_type:",
710
+ f' raise TypeError("Missing required keyword-only argument: content_type. '
711
+ f'Known values are:" + "{content_types}")',
712
+ ]
713
+ )
892
714
  else:
893
- retval.append(f"if {body_param.serialized_name} is not None:")
894
- retval.append(" " + serialize_body_call)
895
- if len(builder.body_kwargs_to_pass_to_request_builder) == 1:
896
- retval.append("else:")
897
- retval.append(f" _{body_kwarg} = None")
715
+ retval.extend(self._serialize_body_parameter(builder))
898
716
  return retval
899
717
 
900
- def _set_body_content_kwarg(
901
- self, builder, body_param: Parameter, body_kwarg: Parameter
902
- ) -> List[str]:
718
+ def _initialize_overloads(self, builder: OperationType) -> List[str]:
903
719
  retval: List[str] = []
904
- if (
905
- body_kwarg.serialized_name == "data"
906
- or body_kwarg.serialized_name == "files"
907
- ):
908
- return retval
720
+ same_content_type = (
721
+ len(
722
+ set(
723
+ o.parameters.body_parameter.default_content_type
724
+ for o in builder.overloads
725
+ )
726
+ )
727
+ == 1
728
+ )
729
+ if same_content_type:
730
+ default_content_type = builder.overloads[
731
+ 0
732
+ ].parameters.body_parameter.default_content_type
733
+ retval.append(f'content_type = content_type or "{default_content_type}"')
734
+ for overload in builder.overloads:
735
+ retval.append(
736
+ f"_{overload.request_builder.parameters.body_parameter.client_name} = None"
737
+ )
909
738
  try:
910
- if not body_param.style == ParameterStyle.binary:
911
- retval.extend(
912
- self._serialize_body(
913
- builder, body_param, body_kwarg.serialized_name
739
+ # if there is a binary overload, we do a binary check first.
740
+ binary_overload = cast(
741
+ OperationType,
742
+ next(
743
+ (
744
+ o
745
+ for o in builder.overloads
746
+ if isinstance(o.parameters.body_parameter.type, BinaryType)
914
747
  )
748
+ ),
749
+ )
750
+ binary_body_param = binary_overload.parameters.body_parameter
751
+ retval.append(
752
+ f"if {binary_body_param.type.instance_check_template.format(binary_body_param.client_name)}:"
753
+ )
754
+ if binary_body_param.default_content_type and not same_content_type:
755
+ retval.append(
756
+ f' content_type = content_type or "{binary_body_param.default_content_type}"'
915
757
  )
916
- return retval
917
- except AttributeError:
918
- pass
919
- retval.append(f"_{body_kwarg.serialized_name} = {body_param.serialized_name}")
920
- return retval
921
-
922
- def _serialize_body_parameters(
923
- self,
924
- builder,
925
- ) -> List[str]:
926
- retval = []
927
- body_kwargs = [
928
- p for p in builder.request_builder.parameters.body if p.content_types
929
- ]
930
- builder_params = []
931
- if builder.parameters.has_body:
932
- builder_params += builder.parameters.body
933
- if builder.multiple_content_type_parameters.has_body:
934
- builder_params += builder.multiple_content_type_parameters.body
935
- if len(body_kwargs) == 1:
936
758
  retval.extend(
937
- self._set_body_content_kwarg(
938
- builder, builder.parameters.body[0], body_kwargs[0]
939
- )
759
+ f" {l}" for l in self._create_body_parameter(binary_overload)
940
760
  )
941
- else:
942
- retval.append('content_type = content_type or ""')
943
- for idx, body_kwarg in enumerate(body_kwargs):
944
- body_param = next(
945
- b for b in builder_params if body_kwarg in b.body_kwargs
761
+ retval.append("else:")
762
+ other_overload = cast(
763
+ OperationType,
764
+ next(
765
+ (
766
+ o
767
+ for o in builder.overloads
768
+ if not isinstance(o.parameters.body_parameter.type, BinaryType)
769
+ )
770
+ ),
771
+ )
772
+ retval.extend(
773
+ f" {l}" for l in self._create_body_parameter(other_overload)
774
+ )
775
+ if (
776
+ other_overload.parameters.body_parameter.default_content_type
777
+ and not same_content_type
778
+ ):
779
+ retval.append(
780
+ " content_type = content_type or "
781
+ f'"{other_overload.parameters.body_parameter.default_content_type}"'
946
782
  )
783
+ except StopIteration:
784
+ for idx, overload in enumerate(builder.overloads):
947
785
  if_statement = "if" if idx == 0 else "elif"
786
+ body_param = overload.parameters.body_parameter
948
787
  retval.append(
949
- f'{if_statement} content_type.split(";")[0] in {body_kwarg.pre_semicolon_content_types}:'
788
+ f"{if_statement} {body_param.type.instance_check_template.format(body_param.client_name)}:"
950
789
  )
790
+ if body_param.default_content_type and not same_content_type:
791
+ retval.append(
792
+ f' content_type = content_type or "{body_param.default_content_type}"'
793
+ )
951
794
  retval.extend(
952
- [
953
- " " + line
954
- for line in self._set_body_content_kwarg(
955
- builder, body_param, body_kwarg
956
- )
957
- ]
795
+ f" {l}"
796
+ for l in self._create_body_parameter(cast(OperationType, overload))
958
797
  )
959
- retval.extend(_content_type_error_check(builder))
960
-
961
798
  return retval
962
799
 
963
- def _call_request_builder_helper( # pylint: disable=too-many-statements
800
+ def _create_request_builder_call(
964
801
  self,
965
- builder,
966
- request_builder: RequestBuilder,
802
+ builder: OperationType,
803
+ request_builder: RequestBuilderType,
967
804
  template_url: Optional[str] = None,
968
805
  is_next_request: bool = False,
969
806
  ) -> List[str]:
970
- retval = []
971
- if len(builder.body_kwargs_to_pass_to_request_builder) > 1:
972
- # special case for files, bc we hardcode body param to be called 'files' for multipart
973
- body_params_to_initialize = builder.body_kwargs_to_pass_to_request_builder
974
- if self.code_model.options["version_tolerant"]:
975
- body_params_to_initialize = [
976
- p for p in body_params_to_initialize if p != "files"
977
- ]
978
- for k in body_params_to_initialize:
979
- retval.append(f"_{k} = None")
980
- if builder.parameters.grouped:
981
- # request builders don't allow grouped parameters, so we group them before making the call
982
- retval.extend(_serialize_grouped_body(builder))
983
-
984
- if builder.parameters.is_flattened:
985
- # unflatten before passing to request builder as well
986
- retval.extend(_serialize_flattened_body(builder))
987
- if request_builder.multipart or request_builder.parameters.data_inputs:
988
- if not self.code_model.options["version_tolerant"]:
989
- param_name = "_files" if request_builder.multipart else "_data"
990
- retval.extend(_serialize_files_and_data_body(builder, param_name))
991
- elif builder.parameters.has_body and not builder.parameters.body[0].constant:
992
- retval.extend(self._serialize_body_parameters(builder))
993
-
807
+ retval: List[str] = []
994
808
  if self.code_model.options["builders_visibility"] == "embedded":
995
809
  request_path_name = request_builder.name
996
810
  else:
997
- builder_group_name = request_builder.builder_group_name
811
+ group_name = request_builder.group_name
998
812
  request_path_name = "rest{}.{}".format(
999
- ("_" + builder_group_name) if builder_group_name else "",
813
+ ("_" + group_name) if group_name else "",
1000
814
  request_builder.name,
1001
815
  )
1002
- retval.append("")
1003
816
  retval.append(f"request = {request_path_name}(")
1004
817
  for parameter in request_builder.parameters.method:
1005
- if (
1006
- parameter.is_body
1007
- and not parameter.constant
1008
- and parameter.serialized_name
1009
- not in builder.body_kwargs_to_pass_to_request_builder
1010
- ):
818
+ if parameter.location == ParameterLocation.BODY:
819
+ # going to pass in body later based off of overloads
1011
820
  continue
1012
821
  if (
1013
822
  is_next_request
1014
- and not bool(builder.next_request_builder)
823
+ and builder.operation_type == "paging"
824
+ and not bool(builder.next_request_builder) # type: ignore
1015
825
  and not self.code_model.options["reformat_next_link"]
1016
- and parameter.location == ParameterLocation.Query
826
+ and parameter.location == ParameterLocation.QUERY
1017
827
  ):
1018
828
  # if we don't want to reformat query parameters for next link calls
1019
829
  # in paging operations with a single swagger operation defintion,
1020
830
  # we skip passing query params when building the next request
1021
831
  continue
1022
- high_level_name = cast(
1023
- RequestBuilderParameter, parameter
1024
- ).name_in_high_level_operation
1025
- retval.append(f" {parameter.serialized_name}={high_level_name},")
832
+ retval.append(
833
+ f" {parameter.client_name}={parameter.name_in_high_level_operation},"
834
+ )
835
+ if request_builder.overloads:
836
+ for overload in request_builder.overloads:
837
+ body_param = cast(
838
+ RequestBuilderBodyParameter, overload.parameters.body_parameter
839
+ )
840
+ retval.append(
841
+ f" {body_param.client_name}={body_param.name_in_high_level_operation},"
842
+ )
843
+ elif request_builder.parameters.has_body:
844
+ body_param = cast(
845
+ RequestBuilderBodyParameter, request_builder.parameters.body_parameter
846
+ )
847
+ retval.append(
848
+ f" {body_param.client_name}={body_param.name_in_high_level_operation},"
849
+ )
1026
850
  if not self.code_model.options["version_tolerant"]:
1027
- if builder.parameters.multipart:
1028
- retval.append(f" files=_files,")
1029
- if builder.parameters.data_inputs:
1030
- retval.append(f" data=_data,")
1031
851
  template_url = template_url or f"self.{builder.name}.metadata['url']"
1032
852
  retval.append(f" template_url={template_url},")
1033
853
  retval.append(" headers=_headers,")
1034
854
  retval.append(" params=_params,")
1035
855
  retval.append(f")")
856
+ return retval
857
+
858
+ def _postprocess_http_request(
859
+ self, builder: OperationType, template_url: Optional[str] = None
860
+ ) -> List[str]:
861
+ retval: List[str] = []
1036
862
  if not self.code_model.options["version_tolerant"]:
1037
863
  pass_files = ""
1038
- if builder.parameters.multipart:
864
+ if (
865
+ builder.parameters.has_body
866
+ and builder.parameters.body_parameter.client_name == "files"
867
+ ):
1039
868
  pass_files = ", _files"
1040
869
  retval.append(f"request = _convert_request(request{pass_files})")
1041
870
  if builder.parameters.path:
@@ -1051,17 +880,46 @@ class _OperationBaseSerializer(
1051
880
  )
1052
881
  return retval
1053
882
 
1054
- def call_request_builder(self, builder) -> List[str]:
883
+ def _call_request_builder_helper( # pylint: disable=too-many-statements
884
+ self,
885
+ builder: OperationType,
886
+ request_builder: RequestBuilderType,
887
+ template_url: Optional[str] = None,
888
+ is_next_request: bool = False,
889
+ ) -> List[str]:
890
+ retval = []
891
+ if builder.parameters.grouped:
892
+ # request builders don't allow grouped parameters, so we group them before making the call
893
+ retval.extend(_serialize_grouped_body(builder))
894
+ if builder.parameters.has_body and builder.parameters.body_parameter.flattened:
895
+ # unflatten before passing to request builder as well
896
+ retval.extend(_serialize_flattened_body(builder.parameters.body_parameter))
897
+ if builder.overloads:
898
+ # we are only dealing with two overloads. If there are three, we generate an abstract operation
899
+ retval.extend(self._initialize_overloads(builder))
900
+ elif builder.parameters.has_body:
901
+ # non-overloaded body
902
+ retval.extend(self._create_body_parameter(builder))
903
+ retval.append("")
904
+ retval.extend(
905
+ self._create_request_builder_call(
906
+ builder, request_builder, template_url, is_next_request
907
+ )
908
+ )
909
+ retval.extend(self._postprocess_http_request(builder, template_url))
910
+ return retval
911
+
912
+ def call_request_builder(self, builder: OperationType) -> List[str]:
1055
913
  return self._call_request_builder_helper(builder, builder.request_builder)
1056
914
 
1057
915
  def response_headers_and_deserialization(
1058
916
  self,
1059
- response: SchemaResponse,
917
+ response: Response,
1060
918
  ) -> List[str]:
1061
919
  retval: List[str] = [
1062
920
  (
1063
- f"response_headers['{response_header.name}']=self._deserialize('{response_header.serialization_type}', "
1064
- f"response.headers.get('{response_header.name}'))"
921
+ f"response_headers['{response_header.rest_api_name}']=self._deserialize("
922
+ f"'{response_header.serialization_type}', response.headers.get('{response_header.rest_api_name}'))"
1065
923
  )
1066
924
  for response_header in response.headers
1067
925
  ]
@@ -1070,20 +928,21 @@ class _OperationBaseSerializer(
1070
928
  if response.is_stream_response:
1071
929
  retval.append(
1072
930
  "deserialized = {}".format(
1073
- "response"
931
+ "response.iter_bytes()"
1074
932
  if self.code_model.options["version_tolerant"]
1075
933
  else "response.stream_download(self._client._pipeline)"
1076
934
  )
1077
935
  )
1078
- elif response.has_body:
936
+ elif response.type:
1079
937
  if self.code_model.options["models_mode"]:
1080
938
  retval.append(
1081
939
  f"deserialized = self._deserialize('{response.serialization_type}', pipeline_response)"
1082
940
  )
1083
941
  else:
1084
- is_xml = any(["xml" in ct for ct in response.content_types])
1085
942
  deserialized_value = (
1086
- "ET.fromstring(response.text())" if is_xml else "response.json()"
943
+ "ET.fromstring(response.text())"
944
+ if response.type.is_xml
945
+ else "response.json()"
1087
946
  )
1088
947
  retval.append(f"if response.content:")
1089
948
  retval.append(f" deserialized = {deserialized_value}")
@@ -1091,20 +950,21 @@ class _OperationBaseSerializer(
1091
950
  retval.append(f" deserialized = None")
1092
951
  return retval
1093
952
 
1094
- @property
1095
- @abstractmethod
1096
- def _call_method(self) -> str:
1097
- ...
1098
-
1099
- def handle_error_response(self, builder) -> List[str]:
1100
- retval = [f"if response.status_code not in {str(builder.success_status_code)}:"]
953
+ def handle_error_response(self, builder: OperationType) -> List[str]:
954
+ retval = [
955
+ f"if response.status_code not in {str(builder.success_status_codes)}:"
956
+ ]
1101
957
  retval.append(
1102
958
  " map_error(status_code=response.status_code, response=response, error_map=error_map)"
1103
959
  )
1104
960
  error_model = ""
1105
- if builder.default_exception and self.code_model.options["models_mode"]:
961
+ if (
962
+ builder.default_error_deserialization
963
+ and self.code_model.options["models_mode"]
964
+ ):
1106
965
  retval.append(
1107
- f" error = self._deserialize.failsafe_deserialize({builder.default_exception}, pipeline_response)"
966
+ f" error = self._deserialize.failsafe_deserialize({builder.default_error_deserialization}, "
967
+ "pipeline_response)"
1108
968
  )
1109
969
  error_model = ", model=error"
1110
970
  retval.append(
@@ -1117,7 +977,7 @@ class _OperationBaseSerializer(
1117
977
  )
1118
978
  return retval
1119
979
 
1120
- def handle_response(self, builder) -> List[str]:
980
+ def handle_response(self, builder: OperationType) -> List[str]:
1121
981
  retval: List[str] = ["response = pipeline_response.http_response"]
1122
982
  retval.append("")
1123
983
  retval.extend(self.handle_error_response(builder))
@@ -1128,9 +988,9 @@ class _OperationBaseSerializer(
1128
988
  retval.append("response_headers = {}")
1129
989
  if builder.has_response_body or builder.any_response_has_headers:
1130
990
  if len(builder.responses) > 1:
1131
- for status_code in builder.success_status_code:
991
+ for status_code in builder.success_status_codes:
1132
992
  response = builder.get_response_from_status(status_code)
1133
- if response.headers or response.has_body:
993
+ if response.headers or response.type:
1134
994
  retval.append(f"if response.status_code == {status_code}:")
1135
995
  retval.extend(
1136
996
  [
@@ -1149,9 +1009,7 @@ class _OperationBaseSerializer(
1149
1009
  if builder.has_optional_return_type or self.code_model.options["models_mode"]:
1150
1010
  deserialized = "deserialized"
1151
1011
  else:
1152
- deserialized = (
1153
- f"cast({self._response_type_annotation(builder)}, deserialized)"
1154
- )
1012
+ deserialized = f"cast({builder.response_type_annotation(async_mode=self.async_mode)}, deserialized)"
1155
1013
  retval.append("if cls:")
1156
1014
  retval.append(
1157
1015
  " return cls(pipeline_response, {}, {})".format(
@@ -1169,23 +1027,22 @@ class _OperationBaseSerializer(
1169
1027
  retval.append("return 200 <= response.status_code <= 299")
1170
1028
  return retval
1171
1029
 
1172
- def error_map(self, builder) -> List[str]:
1030
+ def error_map(self, builder: OperationType) -> List[str]:
1173
1031
  retval = ["error_map = {"]
1174
- if builder.status_code_exceptions:
1175
- if not 401 in builder.status_code_exceptions_status_codes:
1032
+ if builder.non_default_errors:
1033
+ if not 401 in builder.non_default_error_status_codes:
1176
1034
  retval.append(" 401: ClientAuthenticationError,")
1177
- if not 404 in builder.status_code_exceptions_status_codes:
1035
+ if not 404 in builder.non_default_error_status_codes:
1178
1036
  retval.append(" 404: ResourceNotFoundError,")
1179
- if not 409 in builder.status_code_exceptions_status_codes:
1037
+ if not 409 in builder.non_default_error_status_codes:
1180
1038
  retval.append(" 409: ResourceExistsError,")
1181
- for excep in builder.status_code_exceptions:
1039
+ for excep in builder.non_default_errors:
1182
1040
  error_model_str = ""
1183
1041
  if (
1184
- isinstance(excep.schema, ObjectSchema)
1185
- and excep.is_exception
1042
+ isinstance(excep.type, ModelType)
1186
1043
  and self.code_model.options["models_mode"]
1187
1044
  ):
1188
- error_model_str = f", model=self._deserialize(_models.{excep.serialization_type}, response)"
1045
+ error_model_str = f", model=self._deserialize(_models.{excep.type.serialization_type}, response)"
1189
1046
  error_format_str = (
1190
1047
  ", error_format=ARMErrorFormat"
1191
1048
  if self.code_model.options["azure_arm"]
@@ -1223,108 +1080,53 @@ class _OperationBaseSerializer(
1223
1080
  return retval
1224
1081
 
1225
1082
  @staticmethod
1226
- def get_metadata_url(builder) -> str:
1083
+ def get_metadata_url(builder: OperationType) -> str:
1227
1084
  url = _escape_str(builder.request_builder.url)
1228
- return f"{builder.python_name}.metadata = {{'url': { url }}} # type: ignore"
1229
-
1230
-
1231
- class _SyncOperationBaseSerializer(
1232
- _OperationBaseSerializer
1233
- ): # pylint: disable=abstract-method
1234
- @property
1235
- def _want_inline_type_hints(self) -> bool:
1236
- return False
1237
-
1238
- @property
1239
- def _def(self) -> str:
1240
- return "def"
1085
+ return f"{builder.name}.metadata = {{'url': { url }}} # type: ignore"
1241
1086
 
1242
1087
  @property
1243
1088
  def _call_method(self) -> str:
1244
- return ""
1089
+ return "await " if self.async_mode else ""
1245
1090
 
1246
1091
 
1247
- class SyncOperationGenericSerializer(_SyncOperationBaseSerializer):
1248
- @property
1249
- def _want_inline_type_hints(self) -> bool:
1250
- return False
1251
-
1252
- @staticmethod
1253
- def _method_signature_and_response_type_annotation_template(
1254
- method_signature: str, response_type_annotation: str
1255
- ):
1256
- return utils.method_signature_and_response_type_annotation_template(
1257
- is_python3_file=False,
1258
- method_signature=method_signature,
1259
- response_type_annotation=response_type_annotation,
1260
- )
1261
-
1262
- def _get_kwargs_to_pop(self, builder):
1263
- return builder.parameters.kwargs_to_pop(is_python3_file=False)
1264
-
1265
-
1266
- class SyncOperationPython3Serializer(_SyncOperationBaseSerializer):
1267
- @property
1268
- def _want_inline_type_hints(self) -> bool:
1269
- return True
1270
-
1271
- @staticmethod
1272
- def _method_signature_and_response_type_annotation_template(
1273
- method_signature: str, response_type_annotation: str
1274
- ):
1275
- return utils.method_signature_and_response_type_annotation_template(
1276
- is_python3_file=True,
1277
- method_signature=method_signature,
1278
- response_type_annotation=response_type_annotation,
1279
- )
1280
-
1281
- def _get_kwargs_to_pop(self, builder):
1282
- return builder.parameters.kwargs_to_pop(is_python3_file=True)
1283
-
1284
-
1285
- class AsyncOperationSerializer(SyncOperationPython3Serializer):
1286
- @property
1287
- def _def(self) -> str:
1288
- return "async def"
1289
-
1290
- @property
1291
- def _function_definition(self) -> str:
1292
- return "async def"
1293
-
1294
- @property
1295
- def _call_method(self) -> str:
1296
- return "await "
1092
+ class OperationSerializer(_OperationSerializer[Operation]):
1093
+ ...
1297
1094
 
1298
1095
 
1299
1096
  ############################## PAGING OPERATIONS ##############################
1300
1097
 
1098
+ PagingOperationType = TypeVar(
1099
+ "PagingOperationType", bound=Union[PagingOperation, LROPagingOperation]
1100
+ )
1101
+
1301
1102
 
1302
- class _PagingOperationBaseSerializer(
1303
- _OperationBaseSerializer
1103
+ class _PagingOperationSerializer(
1104
+ _OperationSerializer[PagingOperationType]
1304
1105
  ): # pylint: disable=abstract-method
1305
- def _response_docstring_text_template(
1306
- self, builder
1307
- ) -> str: # pylint: disable=no-self-use, unused-argument
1308
- if self._cls_docstring_rtype:
1309
- return "An iterator like instance of either {}" + self._cls_docstring_rtype
1310
- return "An iterator like instance of {}"
1311
-
1312
- def cls_type_annotation(self, builder) -> str:
1313
- interior = super()._response_type_annotation(
1314
- builder, modify_if_head_as_boolean=False
1106
+ def __init__(
1107
+ self, code_model: CodeModel, async_mode: bool, is_python3_file: bool
1108
+ ) -> None:
1109
+ # for pylint reasons need to redefine init
1110
+ # probably because inheritance is going too deep
1111
+ super().__init__(code_model, async_mode, is_python3_file)
1112
+ self.code_model = code_model
1113
+ self.async_mode = async_mode
1114
+ self.is_python3_file = is_python3_file
1115
+ self.parameter_serializer = ParameterSerializer()
1116
+
1117
+ def serialize_path(self, builder: PagingOperationType) -> List[str]:
1118
+ return self.parameter_serializer.serialize_path(
1119
+ builder.parameters.path, self.serializer_name
1315
1120
  )
1316
- return f"# type: ClsType[{interior}]"
1317
1121
 
1318
- def decorators(self, builder, async_mode: bool) -> List[str]:
1122
+ def decorators(self, builder: PagingOperationType) -> List[str]:
1319
1123
  """Decorators for the method"""
1320
1124
  retval: List[str] = []
1321
1125
  if self.code_model.options["tracing"] and builder.want_tracing:
1322
1126
  retval.append("@distributed_trace")
1323
- if builder.abstract:
1324
- retval.append("@abc.abstractmethod")
1325
1127
  return retval
1326
1128
 
1327
- def call_next_link_request_builder(self, builder) -> List[str]:
1129
+ def call_next_link_request_builder(self, builder: PagingOperationType) -> List[str]:
1328
1130
  if builder.next_request_builder:
1329
1131
  request_builder = builder.next_request_builder
1330
1132
  template_url = (
@@ -1341,7 +1143,7 @@ class _PagingOperationBaseSerializer(
1341
1143
  builder, request_builder, template_url=template_url, is_next_request=True
1342
1144
  )
1343
1145
 
1344
- def _prepare_request_callback(self, builder) -> List[str]:
1146
+ def _prepare_request_callback(self, builder: PagingOperationType) -> List[str]:
1345
1147
  retval = ["def prepare_request(next_link=None):"]
1346
1148
  retval.append(" if not next_link:")
1347
1149
  retval.extend(
@@ -1363,17 +1165,13 @@ class _PagingOperationBaseSerializer(
1363
1165
  return retval
1364
1166
 
1365
1167
  @property
1366
- @abstractmethod
1367
- def _list_type_returned_to_users(self) -> str:
1368
- ...
1369
-
1370
- @staticmethod
1371
- @abstractmethod
1372
- def _pager(builder) -> str:
1373
- ...
1168
+ def _function_def(self) -> str:
1169
+ return "def"
1374
1170
 
1375
- def _extract_data_callback(self, builder) -> List[str]:
1376
- retval = [f"{self._def} extract_data(pipeline_response):"]
1171
+ def _extract_data_callback(self, builder: PagingOperationType) -> List[str]:
1172
+ retval = [
1173
+ f"{'async ' if self.async_mode else ''}def extract_data(pipeline_response):"
1174
+ ]
1377
1175
  response = builder.responses[0]
1378
1176
  deserialized = (
1379
1177
  f'self._deserialize("{response.serialization_type}", pipeline_response)'
@@ -1381,7 +1179,7 @@ class _PagingOperationBaseSerializer(
1381
1179
  else "pipeline_response.http_response.json()"
1382
1180
  )
1383
1181
  retval.append(f" deserialized = {deserialized}")
1384
- item_name = builder.item_name(self.code_model)
1182
+ item_name = builder.item_name
1385
1183
  list_of_elem = (
1386
1184
  f".{item_name}"
1387
1185
  if self.code_model.options["models_mode"]
@@ -1391,29 +1189,22 @@ class _PagingOperationBaseSerializer(
1391
1189
  retval.append(" if cls:")
1392
1190
  retval.append(" list_of_elem = cls(list_of_elem)")
1393
1191
 
1394
- next_link_name = builder.next_link_name
1395
- if not next_link_name:
1396
- next_link_property = "None"
1192
+ continuation_token_name = builder.continuation_token_name
1193
+ if not continuation_token_name:
1194
+ cont_token_property = "None"
1397
1195
  elif self.code_model.options["models_mode"]:
1398
- next_link_property = f"deserialized.{next_link_name} or None"
1196
+ cont_token_property = f"deserialized.{continuation_token_name} or None"
1399
1197
  else:
1400
- next_link_property = f'deserialized.get("{next_link_name}", None)'
1401
- retval.append(
1402
- f" return {next_link_property}, {self._list_type_returned_to_users}(list_of_elem)"
1403
- )
1198
+ cont_token_property = f'deserialized.get("{continuation_token_name}", None)'
1199
+ list_type = "AsyncList" if self.async_mode else "iter"
1200
+ retval.append(f" return {cont_token_property}, {list_type}(list_of_elem)")
1404
1201
  return retval
1405
1202
 
1406
- def _get_next_callback(self, builder) -> List[str]:
1407
- retval = [f"{self._def} get_next(next_link=None):"]
1203
+ def _get_next_callback(self, builder: PagingOperationType) -> List[str]:
1204
+ retval = [f"{'async ' if self.async_mode else ''}def get_next(next_link=None):"]
1408
1205
  retval.append(" request = prepare_request(next_link)")
1409
1206
  retval.append("")
1410
- retval.append(
1411
- f" pipeline_response = {self._call_method}self._client._pipeline.run( # pylint: disable=protected-access"
1412
- )
1413
- retval.append(" request,")
1414
- retval.append(f" stream={builder.is_stream_response},")
1415
- retval.append(" **kwargs")
1416
- retval.append(" )")
1207
+ retval.extend([f" {l}" for l in self.make_pipeline_call(builder)])
1417
1208
  retval.append(" response = pipeline_response.http_response")
1418
1209
  retval.append("")
1419
1210
  retval.extend([f" {line}" for line in self.handle_error_response(builder)])
@@ -1421,7 +1212,7 @@ class _PagingOperationBaseSerializer(
1421
1212
  retval.append(" return pipeline_response")
1422
1213
  return retval
1423
1214
 
1424
- def set_up_params_for_pager(self, builder) -> List[str]:
1215
+ def set_up_params_for_pager(self, builder: PagingOperationType) -> List[str]:
1425
1216
  retval = []
1426
1217
  retval.extend(self.error_map(builder))
1427
1218
  retval.extend(self._prepare_request_callback(builder))
@@ -1432,100 +1223,41 @@ class _PagingOperationBaseSerializer(
1432
1223
  return retval
1433
1224
 
1434
1225
 
1435
- class _SyncPagingOperationBaseSerializer(
1436
- _PagingOperationBaseSerializer, _SyncOperationBaseSerializer
1437
- ): # pylint: disable=abstract-method
1438
- def _response_docstring_type_wrapper(
1439
- self, builder
1440
- ) -> List[str]: # pylint: no-self-use
1441
- return [f"~{builder.get_pager_path(async_mode=False)}"]
1442
-
1443
- def _response_type_annotation_wrapper(self, builder) -> List[str]:
1444
- return ["Iterable"]
1445
-
1446
- @property
1447
- def _list_type_returned_to_users(self) -> str: # pylint: disable=no-self-use
1448
- return "iter"
1449
-
1450
- @staticmethod
1451
- def _pager(builder) -> str:
1452
- return builder.get_pager(async_mode=False)
1453
-
1454
-
1455
- class SyncPagingOperationGenericSerializer(
1456
- _SyncPagingOperationBaseSerializer, SyncOperationGenericSerializer
1457
- ):
1458
- pass
1459
-
1460
-
1461
- class SyncPagingOperationPython3Serializer(
1462
- _SyncPagingOperationBaseSerializer, SyncOperationPython3Serializer
1463
- ):
1464
- pass
1465
-
1466
-
1467
- class AsyncPagingOperationSerializer(
1468
- _PagingOperationBaseSerializer, AsyncOperationSerializer
1469
- ):
1470
- def _response_docstring_type_wrapper(
1471
- self, builder
1472
- ) -> List[str]: # pylint: no-self-use
1473
- return [f"~{builder.get_pager_path(async_mode=True)}"]
1474
-
1475
- @property
1476
- def _function_definition(self) -> str:
1477
- return "def"
1478
-
1479
- def _response_type_annotation_wrapper(self, builder) -> List[str]:
1480
- return ["AsyncIterable"]
1481
-
1482
- @property
1483
- def _list_type_returned_to_users(self) -> str: # pylint: disable=no-self-use
1484
- return "AsyncList"
1485
-
1486
- @staticmethod
1487
- def _pager(builder) -> str:
1488
- return builder.get_pager(async_mode=True)
1226
+ class PagingOperationSerializer(_PagingOperationSerializer[PagingOperation]):
1227
+ ...
1489
1228
 
1490
1229
 
1491
1230
  ############################## LRO OPERATIONS ##############################
1492
1231
 
1232
+ LROOperationType = TypeVar(
1233
+ "LROOperationType", bound=Union[LROOperation, LROPagingOperation]
1234
+ )
1493
1235
 
1494
- class _LROOperationBaseSerializer(
1495
- _OperationBaseSerializer
1496
- ): # pylint: disable=abstract-method
1497
- def cls_type_annotation(self, builder) -> str:
1498
- return f"# type: ClsType[{super()._response_type_annotation(builder, modify_if_head_as_boolean=False)}]"
1499
-
1500
- @abstractmethod
1501
- def _default_polling_method(self, builder) -> str:
1502
- ...
1503
-
1504
- @abstractmethod
1505
- def _default_no_polling_method(self, builder) -> str:
1506
- ...
1507
1236
 
1508
- @abstractmethod
1509
- def _poller(self, builder) -> str:
1510
- ...
1511
-
1512
- @property
1513
- @abstractmethod
1514
- def _polling_method_type(self):
1515
- ...
1237
+ class _LROOperationSerializer(_OperationSerializer[LROOperationType]):
1238
+ def __init__(
1239
+ self, code_model: CodeModel, async_mode: bool, is_python3_file: bool
1240
+ ) -> None:
1241
+ # for pylint reasons need to redefine init
1242
+ # probably because inheritance is going too deep
1243
+ super().__init__(code_model, async_mode, is_python3_file)
1244
+ self.code_model = code_model
1245
+ self.async_mode = async_mode
1246
+ self.is_python3_file = is_python3_file
1247
+ self.parameter_serializer = ParameterSerializer()
1516
1248
 
1517
- def param_description(self, builder) -> List[str]:
1249
+ def param_description(self, builder: LROOperationType) -> List[str]:
1518
1250
  retval = super().param_description(builder)
1519
1251
  retval.append(
1520
1252
  ":keyword str continuation_token: A continuation token to restart a poller from a saved state."
1521
1253
  )
1522
1254
  retval.append(
1523
- f":keyword polling: By default, your polling method will be {self._default_polling_method(builder)}. "
1255
+ f":keyword polling: By default, your polling method will be {builder.get_polling_method(self.async_mode)}. "
1524
1256
  "Pass in False for this operation to not poll, or pass in your own initialized polling object for a"
1525
1257
  " personal polling strategy."
1526
1258
  )
1527
1259
  retval.append(
1528
- f":paramtype polling: bool or ~azure.core.polling.{self._polling_method_type}"
1260
+ f":paramtype polling: bool or ~{builder.get_base_polling_method_path(self.async_mode)}"
1529
1261
  )
1530
1262
  retval.append(
1531
1263
  ":keyword int polling_interval: Default waiting time between two polls for LRO operations "
@@ -1533,9 +1265,15 @@ class _LROOperationBaseSerializer(
1533
1265
  )
1534
1266
  return retval
1535
1267
 
1536
- def initial_call(self, builder) -> List[str]:
1268
+ def serialize_path(self, builder: LROOperationType) -> List[str]:
1269
+ return self.parameter_serializer.serialize_path(
1270
+ builder.parameters.path, self.serializer_name
1271
+ )
1272
+
1273
+ def initial_call(self, builder: LROOperationType) -> List[str]:
1537
1274
  retval = [
1538
- f"polling = kwargs.pop('polling', True) # type: Union[bool, {self._polling_method_type}]"
1275
+ "polling = kwargs.pop('polling', True) # type: Union[bool, "
1276
+ f"{builder.get_base_polling_method(self.async_mode)}]"
1539
1277
  ]
1540
1278
  retval.append("lro_delay = kwargs.pop(")
1541
1279
  retval.append(" 'polling_interval',")
@@ -1550,7 +1288,7 @@ class _LROOperationBaseSerializer(
1550
1288
  )
1551
1289
  retval.extend(
1552
1290
  [
1553
- f" {parameter.serialized_name}={parameter.serialized_name},"
1291
+ f" {parameter.client_name}={parameter.client_name},"
1554
1292
  for parameter in builder.parameters.method
1555
1293
  ]
1556
1294
  )
@@ -1562,7 +1300,7 @@ class _LROOperationBaseSerializer(
1562
1300
  retval.append("kwargs.pop('error_map', None)")
1563
1301
  return retval
1564
1302
 
1565
- def return_lro_poller(self, builder) -> List[str]:
1303
+ def return_lro_poller(self, builder: LROOperationType) -> List[str]:
1566
1304
  retval = []
1567
1305
  lro_options_str = (
1568
1306
  "lro_options={'final-state-via': '"
@@ -1579,40 +1317,46 @@ class _LROOperationBaseSerializer(
1579
1317
  retval.extend(
1580
1318
  [
1581
1319
  "if polling is True:",
1582
- f" polling_method = cast({self._polling_method_type}, {self._default_polling_method(builder)}(",
1320
+ f" polling_method = cast({builder.get_base_polling_method(self.async_mode)}, "
1321
+ f"{builder.get_polling_method(self.async_mode)}(",
1583
1322
  " lro_delay,",
1584
1323
  f" {lro_options_str}",
1585
1324
  f" {path_format_arguments_str}",
1586
1325
  " **kwargs",
1587
- f")) # type: {self._polling_method_type}",
1326
+ f")) # type: {builder.get_base_polling_method(self.async_mode)}",
1588
1327
  ]
1589
1328
  )
1590
1329
  retval.append(
1591
- f"elif polling is False: polling_method = cast({self._polling_method_type}, "
1592
- f"{self._default_no_polling_method(builder)}())"
1330
+ f"elif polling is False: polling_method = cast({builder.get_base_polling_method(self.async_mode)}, "
1331
+ f"{builder.get_no_polling_method(self.async_mode)}())"
1593
1332
  )
1594
1333
  retval.append("else: polling_method = polling")
1595
1334
  retval.append("if cont_token:")
1596
- retval.append(f" return {self._poller(builder)}.from_continuation_token(")
1335
+ retval.append(
1336
+ f" return {builder.get_poller(self.async_mode)}.from_continuation_token("
1337
+ )
1597
1338
  retval.append(" polling_method=polling_method,")
1598
1339
  retval.append(" continuation_token=cont_token,")
1599
1340
  retval.append(" client=self._client,")
1600
1341
  retval.append(" deserialization_callback=get_long_running_output")
1601
1342
  retval.append(" )")
1602
1343
  retval.append(
1603
- f"return {self._poller(builder)}"
1344
+ f"return {builder.get_poller(self.async_mode)}"
1604
1345
  "(self._client, raw_result, get_long_running_output, polling_method)"
1605
1346
  )
1606
1347
  return retval
1607
1348
 
1608
- def get_long_running_output(self, builder) -> List[str]:
1609
- retval = ["def get_long_running_output(pipeline_response):"]
1349
+ def get_long_running_output(self, builder: LROOperationType) -> List[str]:
1350
+ pylint_disable = ""
1351
+ if not builder.lro_response:
1352
+ pylint_disable = " # pylint: disable=inconsistent-return-statements"
1353
+ retval = [f"def get_long_running_output(pipeline_response):{pylint_disable}"]
1610
1354
  if builder.lro_response:
1611
- if builder.lro_response.has_headers:
1355
+ if builder.lro_response.headers:
1612
1356
  retval.append(" response_headers = {}")
1613
1357
  if (
1614
1358
  not self.code_model.options["models_mode"]
1615
- or builder.lro_response.has_headers
1359
+ or builder.lro_response.headers
1616
1360
  ):
1617
1361
  retval.append(" response = pipeline_response.http_response")
1618
1362
  retval.extend(
@@ -1627,268 +1371,75 @@ class _LROOperationBaseSerializer(
1627
1371
  retval.append(
1628
1372
  " return cls(pipeline_response, {}, {})".format(
1629
1373
  "deserialized"
1630
- if builder.lro_response and builder.lro_response.has_body
1374
+ if builder.lro_response and builder.lro_response.type
1631
1375
  else "None",
1632
1376
  "response_headers"
1633
- if builder.lro_response and builder.lro_response.has_headers
1377
+ if builder.lro_response and builder.lro_response.headers
1634
1378
  else "{}",
1635
1379
  )
1636
1380
  )
1637
- if builder.lro_response and builder.lro_response.has_body:
1381
+ if builder.lro_response and builder.lro_response.type:
1638
1382
  retval.append(" return deserialized")
1639
1383
  return retval
1640
1384
 
1641
1385
 
1642
- class _SyncLROOperationBaseSerializer(
1643
- _LROOperationBaseSerializer, _SyncOperationBaseSerializer
1644
- ): # pylint: disable=abstract-method
1645
- def _response_docstring_text_template(
1646
- self, builder
1647
- ) -> str: # pylint: disable=no-self-use
1648
- lro_section = f"An instance of {builder.get_poller(async_mode=False)} "
1649
- if self._cls_docstring_rtype:
1650
- return lro_section + "that returns either {}" + self._cls_docstring_rtype
1651
- return lro_section + "that returns {}"
1652
-
1653
- def _response_docstring_type_wrapper(
1654
- self, builder
1655
- ) -> List[str]: # pylint: no-self-use
1656
- return [f"~{builder.get_poller_path(async_mode=False)}"]
1657
-
1658
- def _response_type_annotation_wrapper(self, builder) -> List[str]:
1659
- return [builder.get_poller(async_mode=False)]
1660
-
1661
- def _default_polling_method(self, builder) -> str:
1662
- return builder.get_default_polling_method(
1663
- async_mode=False, azure_arm=self.code_model.options["azure_arm"]
1664
- )
1665
-
1666
- def _default_no_polling_method(self, builder) -> str:
1667
- return builder.get_default_no_polling_method(async_mode=False)
1668
-
1669
- @property
1670
- def _polling_method_type(self):
1671
- return "PollingMethod"
1672
-
1673
- def _poller(self, builder) -> str:
1674
- return builder.get_poller(async_mode=False)
1675
-
1676
-
1677
- class SyncLROOperationGenericSerializer(
1678
- _SyncLROOperationBaseSerializer, SyncOperationGenericSerializer
1679
- ):
1680
- pass
1681
-
1682
-
1683
- class SyncLROOperationPython3Serializer(
1684
- _SyncLROOperationBaseSerializer, SyncOperationPython3Serializer
1685
- ):
1686
- pass
1687
-
1688
-
1689
- class AsyncLROOperationSerializer(
1690
- _LROOperationBaseSerializer, AsyncOperationSerializer
1691
- ):
1692
- def _response_docstring_text_template(
1693
- self, builder
1694
- ) -> str: # pylint: disable=no-self-use
1695
- lro_section = f"An instance of {builder.get_poller(async_mode=True)} "
1696
- if self._cls_docstring_rtype:
1697
- return lro_section + "that returns either {}" + self._cls_docstring_rtype
1698
- return lro_section + "that returns {}"
1386
+ class LROOperationSerializer(_LROOperationSerializer[LROOperation]):
1387
+ ...
1699
1388
 
1700
- def _response_docstring_type_wrapper(
1701
- self, builder
1702
- ) -> List[str]: # pylint: no-self-use
1703
- return [f"~{builder.get_poller_path(async_mode=True)}"]
1704
1389
 
1705
- def _response_type_annotation_wrapper(self, builder) -> List[str]:
1706
- return [builder.get_poller(async_mode=True)]
1707
-
1708
- def _default_polling_method(self, builder) -> str:
1709
- return builder.get_default_polling_method(
1710
- async_mode=True, azure_arm=self.code_model.options["azure_arm"]
1711
- )
1390
+ ############################## LRO PAGING OPERATIONS ##############################
1712
1391
 
1713
- def _default_no_polling_method(self, builder) -> str:
1714
- return builder.get_default_no_polling_method(async_mode=True)
1715
1392
 
1393
+ class LROPagingOperationSerializer(
1394
+ _LROOperationSerializer[LROPagingOperation],
1395
+ _PagingOperationSerializer[LROPagingOperation],
1396
+ ): # pylint: disable=abstract-method
1716
1397
  @property
1717
- def _polling_method_type(self):
1718
- return "AsyncPollingMethod"
1719
-
1720
- def _poller(self, builder) -> str:
1721
- return builder.get_poller(async_mode=True)
1722
-
1723
-
1724
- ############################## LRO PAGING OPERATIONS ##############################
1398
+ def _call_method(self) -> str:
1399
+ return "await " if self.async_mode else ""
1725
1400
 
1401
+ @property
1402
+ def _function_def(self) -> str:
1403
+ return "async def" if self.async_mode else "def"
1726
1404
 
1727
- class _LROPagingOperationBaseSerializer(
1728
- _LROOperationBaseSerializer, _PagingOperationBaseSerializer
1729
- ): # pylint: disable=abstract-method
1730
- def get_long_running_output(self, builder) -> List[str]:
1405
+ def get_long_running_output(self, builder: LROPagingOperation) -> List[str]:
1731
1406
  retval = ["def get_long_running_output(pipeline_response):"]
1732
- retval.append(f" {self._def} internal_get_next(next_link=None):")
1407
+ retval.append(f" {self._function_def} internal_get_next(next_link=None):")
1733
1408
  retval.append(" if next_link is None:")
1734
1409
  retval.append(" return pipeline_response")
1735
1410
  retval.append(f" return {self._call_method}get_next(next_link)")
1736
1411
  retval.append("")
1737
- retval.append(f" return {self._pager(builder)}(")
1412
+ retval.append(f" return {builder.get_pager(self.async_mode)}(")
1738
1413
  retval.append(" internal_get_next, extract_data")
1739
1414
  retval.append(" )")
1740
1415
  return retval
1741
1416
 
1742
- def decorators(self, builder, async_mode: bool) -> List[str]:
1417
+ def decorators(self, builder: LROPagingOperation) -> List[str]: # type: ignore
1743
1418
  """Decorators for the method"""
1744
- return _LROOperationBaseSerializer.decorators(self, builder, async_mode)
1745
-
1746
-
1747
- class _SyncLROPagingOperationBaseSerializer( # pylint: disable=abstract-method
1748
- _SyncLROOperationBaseSerializer,
1749
- _SyncPagingOperationBaseSerializer,
1750
- _LROPagingOperationBaseSerializer,
1751
- ):
1752
- def _response_docstring_type_wrapper(self, builder) -> List[str]:
1753
- return _SyncLROOperationBaseSerializer._response_docstring_type_wrapper(
1754
- self, builder
1755
- ) + _SyncPagingOperationBaseSerializer._response_docstring_type_wrapper(
1756
- self, builder
1757
- )
1758
-
1759
- def _response_type_annotation_wrapper(self, builder) -> List[str]:
1760
- return _SyncLROOperationBaseSerializer._response_type_annotation_wrapper(
1761
- self, builder
1762
- ) + [builder.get_pager(async_mode=False)]
1763
-
1764
- def _response_docstring_text_template(self, builder) -> str:
1765
- lro_doc = _SyncLROOperationBaseSerializer._response_docstring_text_template(
1766
- self, builder
1767
- )
1768
- paging_doc = (
1769
- _SyncPagingOperationBaseSerializer._response_docstring_text_template(
1770
- self, builder
1771
- )
1772
- )
1773
- paging_doc = paging_doc.replace(paging_doc[0], paging_doc[0].lower(), 1)
1774
- return (
1775
- lro_doc.format(paging_doc)
1776
- .replace(self._cls_docstring_rtype, "", 1)
1777
- .replace("either ", "", 1)
1778
- )
1779
-
1780
- def cls_type_annotation(self, builder) -> str:
1781
- return f"# type: ClsType[{self._response_type_annotation(builder, modify_if_head_as_boolean=False)}]"
1782
-
1783
-
1784
- class SyncLROPagingOperationGenericSerializer(
1785
- _SyncLROPagingOperationBaseSerializer, SyncOperationGenericSerializer
1786
- ):
1787
- pass
1788
-
1789
-
1790
- class SyncLROPagingOperationPython3Serializer(
1791
- _SyncLROPagingOperationBaseSerializer, SyncOperationPython3Serializer
1792
- ):
1793
- pass
1794
-
1795
-
1796
- class AsyncLROPagingOperationSerializer(
1797
- _LROPagingOperationBaseSerializer,
1798
- AsyncLROOperationSerializer,
1799
- AsyncPagingOperationSerializer,
1800
- ):
1801
- @property
1802
- def _function_definition(self) -> str:
1803
- return "async def"
1804
-
1805
- def _response_docstring_type_wrapper(self, builder) -> List[str]:
1806
- return AsyncLROOperationSerializer._response_docstring_type_wrapper(
1807
- self, builder
1808
- ) + AsyncPagingOperationSerializer._response_docstring_type_wrapper(
1809
- self, builder
1810
- )
1811
-
1812
- def _response_type_annotation_wrapper(
1813
- self, builder: LROPagingOperation
1814
- ) -> List[str]:
1815
- return AsyncLROOperationSerializer._response_type_annotation_wrapper(
1816
- self, builder
1817
- ) + [builder.get_pager(async_mode=True)]
1818
-
1819
- def _response_docstring_text_template(self, builder) -> str:
1820
- lro_doc = AsyncLROOperationSerializer._response_docstring_text_template(
1821
- self, builder
1822
- )
1823
- paging_doc = AsyncPagingOperationSerializer._response_docstring_text_template(
1824
- self, builder
1825
- )
1826
- paging_doc = paging_doc.replace(paging_doc[0], paging_doc[0].lower(), 1)
1827
- return (
1828
- lro_doc.format(paging_doc)
1829
- .replace(self._cls_docstring_rtype, "", 1)
1830
- .replace("either ", "", 1)
1831
- )
1419
+ return _LROOperationSerializer.decorators(self, builder) # type: ignore
1832
1420
 
1833
1421
 
1834
1422
  def get_operation_serializer(
1835
- builder,
1423
+ builder: Operation,
1836
1424
  code_model,
1837
1425
  async_mode: bool,
1838
1426
  is_python3_file: bool,
1839
- ) -> _OperationBaseSerializer:
1840
- retcls = _OperationBaseSerializer
1841
- if isinstance(builder, LROPagingOperation):
1842
- retcls = (
1843
- AsyncLROPagingOperationSerializer
1844
- if async_mode
1845
- else (
1846
- SyncLROPagingOperationPython3Serializer
1847
- if is_python3_file
1848
- else SyncLROPagingOperationGenericSerializer
1849
- )
1850
- )
1851
- return retcls(code_model)
1852
- if isinstance(builder, LROOperation):
1853
- retcls = (
1854
- AsyncLROOperationSerializer
1855
- if async_mode
1856
- else (
1857
- SyncLROOperationPython3Serializer
1858
- if is_python3_file
1859
- else SyncLROOperationGenericSerializer
1860
- )
1861
- )
1862
- return retcls(code_model)
1863
- if isinstance(builder, PagingOperation):
1864
- retcls = (
1865
- AsyncPagingOperationSerializer
1866
- if async_mode
1867
- else (
1868
- SyncPagingOperationPython3Serializer
1869
- if is_python3_file
1870
- else SyncPagingOperationGenericSerializer
1871
- )
1872
- )
1873
- return retcls(code_model)
1874
- retcls = (
1875
- AsyncOperationSerializer
1876
- if async_mode
1877
- else (
1878
- SyncOperationPython3Serializer
1879
- if is_python3_file
1880
- else SyncOperationGenericSerializer
1881
- )
1882
- )
1883
- return retcls(code_model)
1884
-
1885
-
1886
- def get_request_builder_serializer(
1887
- code_model, is_python3_file: bool
1888
- ) -> _RequestBuilderBaseSerializer:
1889
- retcls = (
1890
- RequestBuilderPython3Serializer
1891
- if is_python3_file
1892
- else RequestBuilderGenericSerializer
1893
- )
1894
- return retcls(code_model)
1427
+ ) -> Union[
1428
+ OperationSerializer,
1429
+ PagingOperationSerializer,
1430
+ LROOperationSerializer,
1431
+ LROPagingOperationSerializer,
1432
+ ]:
1433
+ retcls: Union[
1434
+ Type[OperationSerializer],
1435
+ Type[PagingOperationSerializer],
1436
+ Type[LROOperationSerializer],
1437
+ Type[LROPagingOperationSerializer],
1438
+ ] = OperationSerializer
1439
+ if builder.operation_type == "lropaging":
1440
+ retcls = LROPagingOperationSerializer
1441
+ elif builder.operation_type == "lro":
1442
+ retcls = LROOperationSerializer
1443
+ elif builder.operation_type == "paging":
1444
+ retcls = PagingOperationSerializer
1445
+ return retcls(code_model, async_mode, is_python3_file)