@autorest/python 5.16.0 → 5.17.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 (92) hide show
  1. package/ChangeLog.md +43 -3
  2. package/README.md +30 -4
  3. package/autorest/__init__.py +1 -1
  4. package/autorest/codegen/__init__.py +48 -209
  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} +56 -40
  9. package/autorest/codegen/models/client.py +157 -48
  10. package/autorest/codegen/models/code_model.py +108 -254
  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_schema.py → dictionary_type.py} +41 -31
  15. package/autorest/codegen/models/enum_type.py +195 -0
  16. package/autorest/codegen/models/imports.py +23 -0
  17. package/autorest/codegen/models/list_type.py +134 -0
  18. package/autorest/codegen/models/lro_operation.py +77 -156
  19. package/autorest/codegen/models/lro_paging_operation.py +28 -11
  20. package/autorest/codegen/models/model_type.py +239 -0
  21. package/autorest/codegen/models/operation.py +303 -269
  22. package/autorest/codegen/models/operation_group.py +48 -89
  23. package/autorest/codegen/models/paging_operation.py +80 -123
  24. package/autorest/codegen/models/parameter.py +289 -396
  25. package/autorest/codegen/models/parameter_list.py +348 -360
  26. package/autorest/codegen/models/primitive_types.py +544 -0
  27. package/autorest/codegen/models/property.py +109 -139
  28. package/autorest/codegen/models/request_builder.py +105 -88
  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 +46 -37
  33. package/autorest/codegen/serializers/builder_serializer.py +604 -1146
  34. package/autorest/codegen/serializers/client_serializer.py +83 -88
  35. package/autorest/codegen/serializers/general_serializer.py +5 -64
  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 +40 -32
  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 +4 -13
  43. package/autorest/codegen/serializers/parameter_serializer.py +174 -0
  44. package/autorest/codegen/serializers/request_builders_serializer.py +12 -29
  45. package/autorest/codegen/serializers/utils.py +0 -142
  46. package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
  47. package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +7 -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 +7 -7
  60. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
  61. package/autorest/codegen/templates/operation_tools.jinja2 +8 -2
  62. package/autorest/codegen/templates/paging_operation.py.jinja2 +2 -2
  63. package/autorest/codegen/templates/request_builder.py.jinja2 +13 -11
  64. package/autorest/codegen/templates/setup.py.jinja2 +9 -3
  65. package/autorest/codegen/templates/vendor.py.jinja2 +1 -1
  66. package/autorest/jsonrpc/server.py +15 -3
  67. package/autorest/m4reformatter/__init__.py +1108 -0
  68. package/autorest/multiapi/models/code_model.py +1 -1
  69. package/autorest/multiapi/serializers/__init__.py +4 -4
  70. package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
  71. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
  72. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +3 -3
  73. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
  74. package/autorest/postprocess/__init__.py +202 -0
  75. package/autorest/postprocess/get_all.py +19 -0
  76. package/autorest/postprocess/venvtools.py +73 -0
  77. package/autorest/preprocess/__init__.py +209 -0
  78. package/autorest/preprocess/helpers.py +54 -0
  79. package/autorest/{namer → preprocess}/python_mappings.py +21 -16
  80. package/package.json +2 -2
  81. package/autorest/codegen/models/credential_model.py +0 -55
  82. package/autorest/codegen/models/credential_schema.py +0 -95
  83. package/autorest/codegen/models/credential_schema_policy.py +0 -73
  84. package/autorest/codegen/models/enum_schema.py +0 -225
  85. package/autorest/codegen/models/list_schema.py +0 -135
  86. package/autorest/codegen/models/object_schema.py +0 -303
  87. package/autorest/codegen/models/primitive_schemas.py +0 -495
  88. package/autorest/codegen/models/request_builder_parameter_list.py +0 -249
  89. package/autorest/codegen/models/schema_request.py +0 -55
  90. package/autorest/codegen/models/schema_response.py +0 -141
  91. package/autorest/namer/__init__.py +0 -23
  92. 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,44 @@ 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
+ RequestBuilderType,
33
34
  )
35
+ from .parameter_serializer import ParameterSerializer, PopKwargType
34
36
  from . import utils
35
37
 
36
38
  T = TypeVar("T")
37
39
  OrderedSet = Dict[T, None]
38
40
 
41
+ BuilderType = TypeVar(
42
+ "BuilderType",
43
+ bound=Union[
44
+ RequestBuilder,
45
+ Operation,
46
+ PagingOperation,
47
+ LROOperation,
48
+ LROPagingOperation,
49
+ OverloadedRequestBuilder,
50
+ ],
51
+ )
52
+ OperationType = TypeVar(
53
+ "OperationType",
54
+ bound=Union[Operation, PagingOperation, LROOperation, LROPagingOperation],
55
+ )
56
+
39
57
 
40
58
  def _escape_str(input_str: str) -> str:
41
59
  replace = input_str.replace("'", "\\'")
@@ -65,247 +83,145 @@ def _json_dumps_template(template_representation: Any) -> Any:
65
83
  )
66
84
 
67
85
 
68
- def _content_type_error_check(builder) -> List[str]:
69
- retval = ["else:"]
70
- retval.append(" raise ValueError(")
71
- retval.append(
72
- " \"The content_type '{}' is not one of the allowed values: \""
73
- )
74
- retval.append(f' "{builder.parameters.content_types}".format(content_type)')
75
- retval.append(" )")
76
- return retval
77
-
78
-
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("}")
87
- return retval
88
-
89
-
90
- def _serialize_grouped_body(builder) -> List[str]:
86
+ def _serialize_grouped_body(builder: BuilderType) -> List[str]:
91
87
  retval: List[str] = []
92
88
  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
- )
89
+ retval.append(f"{grouped_parameter.client_name} = None")
90
+ groupers = [p for p in builder.parameters if p.grouper]
91
+ for grouper in groupers:
92
+ retval.append(f"if {grouper.client_name} is not None:")
93
+ retval.extend(
94
+ [
95
+ f" {parameter} = {grouper.client_name}.{property}"
96
+ for property, parameter in grouper.property_to_parameter_name.items()
97
+ ]
98
+ )
104
99
  return retval
105
100
 
106
101
 
107
- def _serialize_flattened_body(builder) -> List[str]:
102
+ def _serialize_flattened_body(body_parameter: BodyParameter) -> List[str]:
108
103
  retval: List[str] = []
109
- if not builder.parameters.is_flattened:
104
+ if not body_parameter.property_to_parameter_name:
110
105
  raise ValueError(
111
106
  "This method can't be called if the operation doesn't need parameter flattening"
112
107
  )
113
108
 
114
- parameters = builder.parameters.get_from_predicate(
115
- lambda parameter: parameter.in_method_code
116
- )
117
109
  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
- ]
110
+ f"{property_name}={parameter_name}"
111
+ for property_name, parameter_name in body_parameter.property_to_parameter_name.items()
123
112
  )
124
- object_schema = cast(ObjectSchema, builder.parameters.body[0].schema)
113
+ model_type = cast(ModelType, body_parameter.type)
125
114
  retval.append(
126
- f"{builder.parameters.body[0].serialized_name} = _models.{object_schema.name}({parameter_string})"
115
+ f"{body_parameter.client_name} = _models.{model_type.name}({parameter_string})"
127
116
  )
128
117
  return retval
129
118
 
130
119
 
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
- )
120
+ def _serialize_multipart_body(builder: BuilderType) -> List[str]:
121
+ retval: List[str] = []
122
+ body_param = cast(MultipartBodyParameter, builder.parameters.body_parameter)
123
+ # we have to construct our form data before passing to the request as well
124
+ retval.append("# Construct form data")
125
+ retval.append(f"_{body_param.client_name} = {{")
126
+ for param in body_param.entries:
127
+ retval.append(f' "{param.rest_api_name}": {param.client_name},')
128
+ retval.append("}")
129
+ return retval
148
130
 
149
131
 
150
- class _BuilderSerializerProtocol(ABC):
132
+ def _get_json_response_template_to_status_codes(
133
+ builder: OperationType,
134
+ ) -> Dict[str, List[str]]:
135
+ retval = defaultdict(list)
136
+ for response in builder.responses:
137
+ json_template = response.get_json_template_representation()
138
+ if not json_template:
139
+ continue
140
+ status_codes = [str(status_code) for status_code in response.status_codes]
141
+ response_json = _json_dumps_template(json_template)
142
+ retval[response_json].extend(status_codes)
143
+ return retval
144
+
145
+
146
+ class _BuilderBaseSerializer(Generic[BuilderType]): # pylint: disable=abstract-method
147
+ def __init__(
148
+ self, code_model: CodeModel, async_mode: bool, is_python3_file: bool
149
+ ) -> None:
150
+ self.code_model = code_model
151
+ self.async_mode = async_mode
152
+ self.is_python3_file = is_python3_file
153
+ self.parameter_serializer = ParameterSerializer()
154
+
151
155
  @property
152
156
  @abstractmethod
153
- def _is_in_class(self) -> bool:
157
+ def _need_self_param(self) -> bool:
154
158
  ...
155
159
 
156
160
  @property
157
161
  @abstractmethod
158
- def _function_definition(self) -> str:
162
+ def _function_def(self) -> str:
159
163
  """The def keyword for the builder we're serializing, i.e. 'def' or 'async def'"""
160
164
  ...
161
165
 
162
166
  @property
163
167
  @abstractmethod
164
- def _def(self) -> str:
165
- """The general definition of a function, i.e. def or async def"""
168
+ def _call_method(self) -> str:
169
+ """How to call network calls. Await if we have to await network calls"""
166
170
  ...
167
171
 
168
172
  @property
169
173
  @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"""
174
+ def serializer_name(self) -> str:
210
175
  ...
211
176
 
212
177
  @abstractmethod
213
- def response_docstring(self, builder) -> List[str]:
178
+ def response_docstring(self, builder: BuilderType) -> List[str]:
214
179
  """Response portion of the docstring"""
215
180
  ...
216
181
 
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]:
182
+ def decorators(self, builder: BuilderType) -> List[str]:
267
183
  """Decorators for the method"""
268
184
  retval: List[str] = []
185
+ if builder.is_overload:
186
+ return ["@overload"]
269
187
  if self.code_model.options["tracing"] and builder.want_tracing:
270
- retval.append(f"@distributed_trace{'_async' if async_mode else ''}")
188
+ retval.append(f"@distributed_trace{'_async' if self.async_mode else ''}")
271
189
  return retval
272
190
 
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,
191
+ def _method_signature(self, builder: BuilderType) -> str:
192
+ return self.parameter_serializer.serialize_method(
193
+ function_def=self._function_def,
278
194
  method_name=builder.name,
279
- is_in_class=self._is_in_class,
195
+ need_self_param=self._need_self_param,
280
196
  method_param_signatures=builder.method_signature(
281
- self._want_inline_type_hints
197
+ self.async_mode or self.is_python3_file, self.async_mode
282
198
  ),
283
- ignore_inconsistent_return_statements=(response_type_annotation == "None"),
199
+ pylint_disable=builder.pylint_disable,
284
200
  )
285
201
 
286
- def _response_type_annotation_wrapper(self, builder) -> List[str]:
287
- return []
288
-
289
202
  def method_signature_and_response_type_annotation(
290
- self, builder, async_mode: bool, *, want_decorators: Optional[bool] = True
203
+ self, builder: BuilderType, *, want_decorators: Optional[bool] = True
291
204
  ) -> 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)
205
+ response_type_annotation = builder.response_type_annotation(
206
+ async_mode=self.async_mode
207
+ )
208
+ method_signature = self._method_signature(builder)
209
+ decorators = self.decorators(builder)
298
210
  decorators_str = ""
299
211
  if decorators and want_decorators:
300
212
  decorators_str = "\n".join(decorators) + "\n"
301
213
  return (
302
214
  decorators_str
303
- + self._method_signature_and_response_type_annotation_template(
304
- method_signature, response_type_annotation
215
+ + utils.method_signature_and_response_type_annotation_template(
216
+ is_python3_file=self.is_python3_file,
217
+ method_signature=method_signature,
218
+ response_type_annotation=response_type_annotation,
305
219
  )
306
220
  )
307
221
 
308
- def description_and_summary(self, builder) -> List[str]:
222
+ def description_and_summary( # pylint: disable=no-self-use
223
+ self, builder: BuilderType
224
+ ) -> List[str]:
309
225
  description_list: List[str] = []
310
226
  description_list.append(
311
227
  f"{ builder.summary.strip() if builder.summary else builder.description.strip() }"
@@ -316,180 +232,109 @@ class _BuilderBaseSerializer(
316
232
  description_list.append("")
317
233
  return description_list
318
234
 
235
+ def example_template(self, builder: BuilderType) -> List[str]:
236
+ template = []
237
+ if builder.abstract:
238
+ return []
239
+ if self._json_input_example_template(builder):
240
+ template.append("")
241
+ template += self._json_input_example_template(builder)
242
+ return template
243
+
319
244
  def param_description( # pylint: disable=no-self-use
320
- self, builder: Union[RequestBuilder, Operation]
245
+ self, builder: BuilderType
321
246
  ) -> List[str]:
322
247
  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
- ]:
248
+ for param in builder.parameters.method:
249
+ if not param.in_docstring:
250
+ continue
328
251
  description_list.extend(
329
- f":{param.description_keyword} { param.serialized_name }: { param.description }".replace(
252
+ f":{param.description_keyword} { param.client_name }: { param.description }".replace(
330
253
  "\n", "\n "
331
254
  ).split(
332
255
  "\n"
333
256
  )
334
257
  )
258
+ docstring_type = param.docstring_type(async_mode=self.async_mode)
335
259
  description_list.append(
336
- f":{param.docstring_type_keyword} { param.serialized_name }: { param.docstring_type }"
260
+ f":{param.docstring_type_keyword} {param.client_name}: {docstring_type}"
337
261
  )
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
262
  return description_list
351
263
 
352
- def param_description_and_response_docstring(self, builder) -> List[str]:
264
+ def param_description_and_response_docstring(
265
+ self, builder: BuilderType
266
+ ) -> List[str]:
353
267
  if builder.abstract:
354
268
  return []
355
269
  return self.param_description(builder) + self.response_docstring(builder)
356
270
 
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
390
-
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:
271
+ def _json_input_example_template(self, builder: BuilderType) -> List[str]:
272
+ template: List[str] = []
273
+ if self.code_model.options["models_mode"]:
274
+ # No input template if we have models
275
+ return template
276
+ if (
277
+ not builder.parameters.has_body
278
+ or builder.parameters.body_parameter.flattened
279
+ ):
280
+ # No input template if now body parameter
281
+ return template
282
+ if builder.overloads:
283
+ # if there's overloads, we do the json input example template on the overload
284
+ return template
285
+
286
+ body_param = builder.parameters.body_parameter
287
+ if not isinstance(body_param.type, (ListType, DictionaryType, ModelType)):
288
+ return template
289
+
290
+ if isinstance(body_param.type, ModelType) and body_param.type.discriminator:
291
+ discriminator_name = body_param.type.discriminator.client_name
292
+ discriminator_values = body_param.type.discriminated_subtypes.keys()
402
293
  template.append(
403
294
  "{} = '{}'".format(
404
- discriminator_name, "' or '".join(subtype_map.values())
295
+ discriminator_name, "' or '".join(discriminator_values)
405
296
  )
406
297
  )
407
298
  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(),
427
- )
428
- template.extend(
429
- f"{property_with_discriminator.name} = {polymorphic_property}".splitlines()
430
- )
431
- if i != num_schemas - 1:
432
- template.append("# OR")
433
- template.append("")
434
299
  template.append(
435
300
  "# JSON input template you can fill out and use as your body input."
436
301
  )
437
302
  json_template = _json_dumps_template(
438
- builder.parameters.json_body.get_json_template_representation(),
303
+ body_param.type.get_json_template_representation(),
439
304
  )
440
305
  template.extend(
441
- f"{self._json_example_param_name(builder)} = {json_template}".splitlines()
306
+ f"{builder.parameters.body_parameter.client_name} = {json_template}".splitlines()
442
307
  )
443
308
  return template
444
309
 
445
- @property
446
- @abstractmethod
447
- def serializer_name(self) -> str:
448
- ...
449
-
450
310
  def _serialize_parameter(self, param: Parameter, kwarg_name: str) -> List[str]:
451
- function_name = "header" if kwarg_name == "headers" else "query"
452
311
  set_parameter = "_{}['{}'] = {}".format(
453
312
  kwarg_name,
454
313
  param.rest_api_name,
455
- utils.build_serialize_data_call(param, function_name, self.serializer_name),
314
+ self.parameter_serializer.serialize_parameter(param, self.serializer_name),
456
315
  )
457
- if param.required:
316
+ if not param.optional:
458
317
  retval = [set_parameter]
459
318
  else:
460
319
  retval = [
461
- f"if {param.full_serialized_name} is not None:",
320
+ f"if {param.full_client_name} is not None:",
462
321
  f" {set_parameter}",
463
322
  ]
464
323
  return retval
465
324
 
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
325
+ def serialize_path(self, builder: BuilderType) -> List[str]:
326
+ return self.parameter_serializer.serialize_path(
327
+ builder.parameters.path, self.serializer_name
328
+ )
484
329
 
485
330
 
486
331
  ############################## REQUEST BUILDERS ##############################
487
332
 
488
333
 
489
- class _RequestBuilderBaseSerializer(
490
- _BuilderBaseSerializer
334
+ class RequestBuilderSerializer(
335
+ _BuilderBaseSerializer[RequestBuilderType]
491
336
  ): # pylint: disable=abstract-method
492
- def description_and_summary(self, builder) -> List[str]:
337
+ def description_and_summary(self, builder: RequestBuilderType) -> List[str]:
493
338
  retval = super().description_and_summary(builder)
494
339
  retval += [
495
340
  "See https://aka.ms/azsdk/python/protocol/quickstart for how to incorporate this "
@@ -498,54 +343,42 @@ class _RequestBuilderBaseSerializer(
498
343
  ]
499
344
  return retval
500
345
 
346
+ @property
347
+ def _call_method(self) -> str:
348
+ return ""
349
+
501
350
  @property
502
351
  def serializer_name(self) -> str:
503
352
  return "_SERIALIZER"
504
353
 
505
354
  @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]:
355
+ def declare_non_inputtable_constants(builder: RequestBuilderType) -> List[str]:
356
+ def _get_value(param):
357
+ param_type = cast(ConstantType, param.type)
358
+ if param.location in [ParameterLocation.HEADER, ParameterLocation.QUERY]:
509
359
  kwarg_dict = (
510
360
  "headers"
511
- if param.location == ParameterLocation.Header
361
+ if param.location == ParameterLocation.HEADER
512
362
  else "params"
513
363
  )
514
- return f"_{kwarg_dict}.pop('{param.rest_api_name}', {param.constant_declaration})"
515
- return f"{param.constant_declaration}"
364
+ return f"_{kwarg_dict}.pop('{param.rest_api_name}', {param_type.get_declaration()})"
365
+ return f"{param_type.get_declaration()}"
516
366
 
517
367
  return [
518
- f"{p.serialized_name} = {_get_value(p)}"
368
+ f"{p.client_name} = {_get_value(p)}"
519
369
  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
370
+ if not p.in_method_signature
523
371
  ]
524
372
 
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
373
  @property
536
- def _def(self) -> str:
374
+ def _function_def(self) -> str:
537
375
  return "def"
538
376
 
539
377
  @property
540
- def _is_in_class(self) -> bool:
378
+ def _need_self_param(self) -> bool:
541
379
  return False
542
380
 
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]:
381
+ def response_docstring(self, builder: RequestBuilderType) -> List[str]:
549
382
  response_str = (
550
383
  f":return: Returns an :class:`~azure.core.rest.HttpRequest` that you will pass to the client's "
551
384
  + "`send_request` method. See https://aka.ms/azsdk/python/protocol/quickstart for how to "
@@ -554,29 +387,19 @@ class _RequestBuilderBaseSerializer(
554
387
  rtype_str = f":rtype: ~azure.core.rest.HttpRequest"
555
388
  return [response_str, rtype_str]
556
389
 
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),
390
+ def pop_kwargs_from_signature(self, builder: RequestBuilderType) -> List[str]:
391
+ return self.parameter_serializer.pop_kwargs_from_signature(
392
+ builder.parameters.kwargs_to_pop(is_python3_file=self.is_python3_file),
570
393
  check_kwarg_dict=True,
571
- pop_headers_kwarg=utils.PopKwargType.CASE_INSENSITIVE
394
+ pop_headers_kwarg=PopKwargType.CASE_INSENSITIVE
572
395
  if bool(builder.parameters.headers)
573
- else utils.PopKwargType.NO,
574
- pop_params_kwarg=utils.PopKwargType.CASE_INSENSITIVE
396
+ else PopKwargType.NO,
397
+ pop_params_kwarg=PopKwargType.CASE_INSENSITIVE
575
398
  if bool(builder.parameters.query)
576
- else utils.PopKwargType.NO,
399
+ else PopKwargType.NO,
577
400
  )
578
401
 
579
- def create_http_request(self, builder) -> List[str]:
402
+ def create_http_request(self, builder: RequestBuilderType) -> List[str]:
580
403
  retval = ["return HttpRequest("]
581
404
  retval.append(f' method="{builder.method}",')
582
405
  retval.append(" url=_url,")
@@ -584,20 +407,25 @@ class _RequestBuilderBaseSerializer(
584
407
  retval.append(" params=_params,")
585
408
  if builder.parameters.headers:
586
409
  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
- )
410
+ if (
411
+ builder.parameters.has_body
412
+ and builder.parameters.body_parameter.in_method_signature
413
+ ):
414
+ body_param = builder.parameters.body_parameter
415
+ if body_param.constant or (
416
+ self.is_python3_file
417
+ and body_param.method_location != ParameterMethodLocation.KWARG
418
+ ):
419
+ # we only need to pass it through if it's not a kwarg or it's a popped kwarg
420
+ retval.append(
421
+ f" {builder.parameters.body_parameter.client_name}="
422
+ f"{builder.parameters.body_parameter.client_name},"
423
+ )
596
424
  retval.append(" **kwargs")
597
425
  retval.append(")")
598
426
  return retval
599
427
 
600
- def serialize_headers(self, builder) -> List[str]:
428
+ def serialize_headers(self, builder: RequestBuilderType) -> List[str]:
601
429
  retval = ["# Construct headers"]
602
430
  for parameter in builder.parameters.headers:
603
431
  retval.extend(
@@ -608,7 +436,7 @@ class _RequestBuilderBaseSerializer(
608
436
  )
609
437
  return retval
610
438
 
611
- def serialize_query(self, builder) -> List[str]:
439
+ def serialize_query(self, builder: RequestBuilderType) -> List[str]:
612
440
  retval = ["# Construct parameters"]
613
441
  for parameter in builder.parameters.query:
614
442
  retval.extend(
@@ -619,7 +447,7 @@ class _RequestBuilderBaseSerializer(
619
447
  )
620
448
  return retval
621
449
 
622
- def construct_url(self, builder) -> str:
450
+ def construct_url(self, builder: RequestBuilderType) -> str:
623
451
  if any(
624
452
  o
625
453
  for o in ["low_level_client", "version_tolerant"]
@@ -631,74 +459,13 @@ class _RequestBuilderBaseSerializer(
631
459
  return f"_url = {url_value}{' # pylint: disable=line-too-long' if len(url_value) > 114 else ''}"
632
460
 
633
461
 
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
462
  ############################## NORMAL OPERATIONS ##############################
696
463
 
697
464
 
698
- class _OperationBaseSerializer(
699
- _BuilderBaseSerializer
465
+ class _OperationSerializer(
466
+ _BuilderBaseSerializer[OperationType]
700
467
  ): # pylint: disable=abstract-method
701
- def description_and_summary(self, builder) -> List[str]:
468
+ def description_and_summary(self, builder: OperationType) -> List[str]:
702
469
  retval = super().description_and_summary(builder)
703
470
  if builder.deprecated:
704
471
  retval.append(".. warning::")
@@ -706,27 +473,55 @@ class _OperationBaseSerializer(
706
473
  retval.append("")
707
474
  return retval
708
475
 
476
+ def example_template(self, builder: OperationType) -> List[str]:
477
+ retval = super().example_template(builder)
478
+ if self.code_model.options["models_mode"]:
479
+ return retval
480
+ if _get_json_response_template_to_status_codes(builder):
481
+ retval.append("")
482
+ for (
483
+ response_body,
484
+ status_codes,
485
+ ) in _get_json_response_template_to_status_codes(builder).items():
486
+ retval.append(
487
+ "# response body for status code(s): {}".format(
488
+ ", ".join(status_codes)
489
+ )
490
+ )
491
+ retval.extend(f"response.json() == {response_body}".splitlines())
492
+ return retval
493
+
494
+ def make_pipeline_call(self, builder: OperationType) -> List[str]:
495
+ return [
496
+ f"pipeline_response = {self._call_method}self._client._pipeline.run( # type: ignore # pylint: disable=protected-access",
497
+ " request,",
498
+ f" stream={builder.has_stream_response},",
499
+ " **kwargs",
500
+ ")",
501
+ ]
502
+
503
+ @property
504
+ def _function_def(self) -> str:
505
+ return "async def" if self.async_mode else "def"
506
+
709
507
  @property
710
- def _is_in_class(self) -> bool:
508
+ def _need_self_param(self) -> bool:
711
509
  return True
712
510
 
713
511
  @property
714
512
  def serializer_name(self) -> str:
715
513
  return "self._serialize"
716
514
 
717
- def decorators(self, builder, async_mode: bool) -> List[str]:
515
+ def decorators(self, builder: OperationType) -> List[str]:
718
516
  """Decorators for the method"""
719
- super_decorators = super().decorators(builder, async_mode)
517
+ super_decorators = super().decorators(builder)
720
518
  if builder.abstract:
721
519
  super_decorators.append("@abc.abstractmethod")
722
520
  return super_decorators
723
521
 
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
522
+ def param_description(
523
+ self, builder: OperationType
524
+ ) -> List[str]: # pylint: disable=no-self-use
730
525
  description_list = super().param_description(builder)
731
526
  if not self.code_model.options["version_tolerant"]:
732
527
  description_list.append(
@@ -734,308 +529,247 @@ class _OperationBaseSerializer(
734
529
  )
735
530
  return description_list
736
531
 
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(
532
+ def pop_kwargs_from_signature(self, builder: OperationType) -> List[str]:
533
+ kwargs_to_pop = builder.parameters.kwargs_to_pop(
534
+ is_python3_file=self.is_python3_file
535
+ )
536
+ kwargs = self.parameter_serializer.pop_kwargs_from_signature(
767
537
  kwargs_to_pop,
768
538
  check_kwarg_dict=True,
769
- pop_headers_kwarg=utils.PopKwargType.CASE_INSENSITIVE
539
+ pop_headers_kwarg=PopKwargType.CASE_INSENSITIVE
770
540
  if builder.has_kwargs_to_pop_with_default(
771
- kwargs_to_pop, ParameterLocation.Header
541
+ kwargs_to_pop, ParameterLocation.HEADER
772
542
  )
773
- else utils.PopKwargType.SIMPLE,
774
- pop_params_kwarg=utils.PopKwargType.CASE_INSENSITIVE
543
+ else PopKwargType.SIMPLE,
544
+ pop_params_kwarg=PopKwargType.CASE_INSENSITIVE
775
545
  if builder.has_kwargs_to_pop_with_default(
776
- kwargs_to_pop, ParameterLocation.Query
546
+ kwargs_to_pop, ParameterLocation.QUERY
777
547
  )
778
- else utils.PopKwargType.SIMPLE,
548
+ else PopKwargType.SIMPLE,
549
+ check_client_input=not self.code_model.options["multiapi"],
779
550
  )
780
551
  kwargs.append(
781
552
  f"cls = kwargs.pop('cls', None) {self.cls_type_annotation(builder)}"
782
553
  )
783
554
  return kwargs
784
555
 
785
- def cls_type_annotation(self, builder) -> str:
786
- return f"# type: ClsType[{self._response_type_annotation(builder, modify_if_head_as_boolean=False)}]"
556
+ def cls_type_annotation(self, builder: OperationType) -> str:
557
+ return f"# type: {builder.cls_type_annotation(async_mode=self.async_mode)}"
787
558
 
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)}"
559
+ def response_docstring(self, builder: OperationType) -> List[str]:
560
+ response_str = (
561
+ f":return: {builder.response_docstring_text(async_mode=self.async_mode)}"
562
+ )
817
563
  rtype_str = (
818
- f":rtype: {self._response_docstring_type_template(builder).format(rtype)}"
564
+ f":rtype: {builder.response_docstring_type(async_mode=self.async_mode)}"
819
565
  )
820
566
  return [
821
567
  response_str,
822
568
  rtype_str,
823
- ":raises: ~azure.core.exceptions.HttpResponseError",
569
+ ":raises ~azure.core.exceptions.HttpResponseError:",
824
570
  ]
825
571
 
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
572
+ def _serialize_body_parameter(self, builder: OperationType) -> List[str]:
573
+ """We need to serialize params if they're not meant to be streamed in.
846
574
 
847
- def _has_json_example_template(self, builder) -> bool:
848
- return builder.parameters.has_body
849
-
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]
575
+ This function serializes the body params that need to be serialized.
576
+ """
577
+ retval: List[str] = []
578
+ body_param = cast(BodyParameter, builder.parameters.body_parameter)
579
+ body_kwarg_name = builder.request_builder.parameters.body_parameter.client_name
580
+ send_xml = builder.parameters.body_parameter.type.is_xml
581
+ xml_serialization_ctxt = (
582
+ body_param.type.xml_serialization_ctxt if send_xml else None
583
+ )
584
+ ser_ctxt_name = "serialization_ctxt"
585
+ if xml_serialization_ctxt and self.code_model.options["models_mode"]:
586
+ retval.append(f'{ser_ctxt_name} = {{"xml": {{{xml_serialization_ctxt}}}}}')
861
587
  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 })"
588
+ is_xml_cmd = ", is_xml=True" if send_xml else ""
589
+ serialization_ctxt_cmd = (
590
+ f", {ser_ctxt_name}={ser_ctxt_name}" if xml_serialization_ctxt else ""
865
591
  )
866
- return f"_{body_kwarg_to_pass} = {body_param.serialized_name}"
592
+ create_body_call = (
593
+ f"_{body_kwarg_name} = self._serialize.body({body_param.client_name}, "
594
+ f"'{body_param.type.serialization_type}'{is_xml_cmd}{serialization_ctxt_cmd})"
595
+ )
596
+ else:
597
+ create_body_call = f"_{body_kwarg_name} = {body_param.client_name}"
598
+ if body_param.optional:
599
+ retval.append(f"if {body_param.client_name} is not None:")
600
+ retval.append(" " + create_body_call)
601
+ retval.append("else:")
602
+ retval.append(f" _{body_kwarg_name} = None")
603
+ else:
604
+ retval.append(create_body_call)
605
+ return retval
867
606
 
868
- def _serialize_body(
869
- self, builder, body_param: Parameter, body_kwarg: str
607
+ def _create_body_parameter(
608
+ self,
609
+ builder: OperationType,
870
610
  ) -> List[str]:
611
+ """Create the body parameter before we pass it as either json or content to the request builder"""
871
612
  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)
613
+ body_param = cast(BodyParameter, builder.parameters.body_parameter)
614
+ if hasattr(body_param, "entries"):
615
+ return _serialize_multipart_body(builder)
616
+ body_kwarg_name = builder.request_builder.parameters.body_parameter.client_name
617
+ if isinstance(body_param.type, BinaryType):
618
+ retval.append(f"_{body_kwarg_name} = {body_param.client_name}")
892
619
  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")
620
+ retval.extend(self._serialize_body_parameter(builder))
898
621
  return retval
899
622
 
900
- def _set_body_content_kwarg(
901
- self, builder, body_param: Parameter, body_kwarg: Parameter
902
- ) -> List[str]:
623
+ def _initialize_overloads(self, builder: OperationType) -> List[str]:
903
624
  retval: List[str] = []
904
- if (
905
- body_kwarg.serialized_name == "data"
906
- or body_kwarg.serialized_name == "files"
907
- ):
908
- return retval
625
+ same_content_type = (
626
+ len(
627
+ set(
628
+ o.parameters.body_parameter.default_content_type
629
+ for o in builder.overloads
630
+ )
631
+ )
632
+ == 1
633
+ )
634
+ if same_content_type:
635
+ default_content_type = builder.overloads[
636
+ 0
637
+ ].parameters.body_parameter.default_content_type
638
+ retval.append(f'content_type = content_type or "{default_content_type}"')
639
+ for overload in builder.overloads:
640
+ retval.append(
641
+ f"_{overload.request_builder.parameters.body_parameter.client_name} = None"
642
+ )
909
643
  try:
910
- if not body_param.style == ParameterStyle.binary:
911
- retval.extend(
912
- self._serialize_body(
913
- builder, body_param, body_kwarg.serialized_name
644
+ # if there is a binary overload, we do a binary check first.
645
+ binary_overload = cast(
646
+ OperationType,
647
+ next(
648
+ (
649
+ o
650
+ for o in builder.overloads
651
+ if isinstance(o.parameters.body_parameter.type, BinaryType)
914
652
  )
653
+ ),
654
+ )
655
+ binary_body_param = binary_overload.parameters.body_parameter
656
+ retval.append(
657
+ f"if {binary_body_param.type.instance_check_template.format(binary_body_param.client_name)}:"
658
+ )
659
+ if binary_body_param.default_content_type and not same_content_type:
660
+ retval.append(
661
+ f' content_type = content_type or "{binary_body_param.default_content_type}"'
915
662
  )
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
663
  retval.extend(
937
- self._set_body_content_kwarg(
938
- builder, builder.parameters.body[0], body_kwargs[0]
939
- )
664
+ f" {l}" for l in self._create_body_parameter(binary_overload)
940
665
  )
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
666
+ retval.append("else:")
667
+ other_overload = cast(
668
+ OperationType,
669
+ next(
670
+ (
671
+ o
672
+ for o in builder.overloads
673
+ if not isinstance(o.parameters.body_parameter.type, BinaryType)
674
+ )
675
+ ),
676
+ )
677
+ retval.extend(
678
+ f" {l}" for l in self._create_body_parameter(other_overload)
679
+ )
680
+ if (
681
+ other_overload.parameters.body_parameter.default_content_type
682
+ and not same_content_type
683
+ ):
684
+ retval.append(
685
+ " content_type = content_type or "
686
+ f'"{other_overload.parameters.body_parameter.default_content_type}"'
946
687
  )
688
+ except StopIteration:
689
+ for idx, overload in enumerate(builder.overloads):
947
690
  if_statement = "if" if idx == 0 else "elif"
691
+ body_param = overload.parameters.body_parameter
948
692
  retval.append(
949
- f'{if_statement} content_type.split(";")[0] in {body_kwarg.pre_semicolon_content_types}:'
693
+ f"{if_statement} {body_param.type.instance_check_template.format(body_param.client_name)}:"
950
694
  )
695
+ if body_param.default_content_type and not same_content_type:
696
+ retval.append(
697
+ f' content_type = content_type or "{body_param.default_content_type}"'
698
+ )
951
699
  retval.extend(
952
- [
953
- " " + line
954
- for line in self._set_body_content_kwarg(
955
- builder, body_param, body_kwarg
956
- )
957
- ]
700
+ f" {l}"
701
+ for l in self._create_body_parameter(cast(OperationType, overload))
958
702
  )
959
- retval.extend(_content_type_error_check(builder))
960
-
961
703
  return retval
962
704
 
963
- def _call_request_builder_helper( # pylint: disable=too-many-statements
705
+ def _create_request_builder_call(
964
706
  self,
965
- builder,
966
- request_builder: RequestBuilder,
707
+ builder: OperationType,
708
+ request_builder: RequestBuilderType,
967
709
  template_url: Optional[str] = None,
968
710
  is_next_request: bool = False,
969
711
  ) -> 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
-
712
+ retval: List[str] = []
994
713
  if self.code_model.options["builders_visibility"] == "embedded":
995
714
  request_path_name = request_builder.name
996
715
  else:
997
- builder_group_name = request_builder.builder_group_name
716
+ group_name = request_builder.group_name
998
717
  request_path_name = "rest{}.{}".format(
999
- ("_" + builder_group_name) if builder_group_name else "",
718
+ ("_" + group_name) if group_name else "",
1000
719
  request_builder.name,
1001
720
  )
1002
- retval.append("")
1003
721
  retval.append(f"request = {request_path_name}(")
1004
722
  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
- ):
723
+ if parameter.location == ParameterLocation.BODY:
724
+ # going to pass in body later based off of overloads
1011
725
  continue
1012
726
  if (
1013
727
  is_next_request
1014
- and not bool(builder.next_request_builder)
728
+ and builder.operation_type == "paging"
729
+ and not bool(builder.next_request_builder) # type: ignore
1015
730
  and not self.code_model.options["reformat_next_link"]
1016
- and parameter.location == ParameterLocation.Query
731
+ and parameter.location == ParameterLocation.QUERY
1017
732
  ):
1018
733
  # if we don't want to reformat query parameters for next link calls
1019
734
  # in paging operations with a single swagger operation defintion,
1020
735
  # we skip passing query params when building the next request
1021
736
  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},")
737
+ retval.append(
738
+ f" {parameter.client_name}={parameter.name_in_high_level_operation},"
739
+ )
740
+ if request_builder.overloads:
741
+ for overload in request_builder.overloads:
742
+ body_param = cast(
743
+ RequestBuilderBodyParameter, overload.parameters.body_parameter
744
+ )
745
+ retval.append(
746
+ f" {body_param.client_name}={body_param.name_in_high_level_operation},"
747
+ )
748
+ elif request_builder.parameters.has_body:
749
+ body_param = cast(
750
+ RequestBuilderBodyParameter, request_builder.parameters.body_parameter
751
+ )
752
+ retval.append(
753
+ f" {body_param.client_name}={body_param.name_in_high_level_operation},"
754
+ )
1026
755
  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
756
  template_url = template_url or f"self.{builder.name}.metadata['url']"
1032
757
  retval.append(f" template_url={template_url},")
1033
758
  retval.append(" headers=_headers,")
1034
759
  retval.append(" params=_params,")
1035
760
  retval.append(f")")
761
+ return retval
762
+
763
+ def _postprocess_http_request(
764
+ self, builder: OperationType, template_url: Optional[str] = None
765
+ ) -> List[str]:
766
+ retval: List[str] = []
1036
767
  if not self.code_model.options["version_tolerant"]:
1037
768
  pass_files = ""
1038
- if builder.parameters.multipart:
769
+ if (
770
+ builder.parameters.has_body
771
+ and builder.parameters.body_parameter.client_name == "files"
772
+ ):
1039
773
  pass_files = ", _files"
1040
774
  retval.append(f"request = _convert_request(request{pass_files})")
1041
775
  if builder.parameters.path:
@@ -1051,17 +785,46 @@ class _OperationBaseSerializer(
1051
785
  )
1052
786
  return retval
1053
787
 
1054
- def call_request_builder(self, builder) -> List[str]:
788
+ def _call_request_builder_helper( # pylint: disable=too-many-statements
789
+ self,
790
+ builder: OperationType,
791
+ request_builder: RequestBuilderType,
792
+ template_url: Optional[str] = None,
793
+ is_next_request: bool = False,
794
+ ) -> List[str]:
795
+ retval = []
796
+ if builder.parameters.grouped:
797
+ # request builders don't allow grouped parameters, so we group them before making the call
798
+ retval.extend(_serialize_grouped_body(builder))
799
+ if builder.parameters.has_body and builder.parameters.body_parameter.flattened:
800
+ # unflatten before passing to request builder as well
801
+ retval.extend(_serialize_flattened_body(builder.parameters.body_parameter))
802
+ if builder.overloads:
803
+ # we are only dealing with two overloads. If there are three, we generate an abstract operation
804
+ retval.extend(self._initialize_overloads(builder))
805
+ elif builder.parameters.has_body:
806
+ # non-overloaded body
807
+ retval.extend(self._create_body_parameter(builder))
808
+ retval.append("")
809
+ retval.extend(
810
+ self._create_request_builder_call(
811
+ builder, request_builder, template_url, is_next_request
812
+ )
813
+ )
814
+ retval.extend(self._postprocess_http_request(builder, template_url))
815
+ return retval
816
+
817
+ def call_request_builder(self, builder: OperationType) -> List[str]:
1055
818
  return self._call_request_builder_helper(builder, builder.request_builder)
1056
819
 
1057
820
  def response_headers_and_deserialization(
1058
821
  self,
1059
- response: SchemaResponse,
822
+ response: Response,
1060
823
  ) -> List[str]:
1061
824
  retval: List[str] = [
1062
825
  (
1063
- f"response_headers['{response_header.name}']=self._deserialize('{response_header.serialization_type}', "
1064
- f"response.headers.get('{response_header.name}'))"
826
+ f"response_headers['{response_header.rest_api_name}']=self._deserialize("
827
+ f"'{response_header.serialization_type}', response.headers.get('{response_header.rest_api_name}'))"
1065
828
  )
1066
829
  for response_header in response.headers
1067
830
  ]
@@ -1070,20 +833,21 @@ class _OperationBaseSerializer(
1070
833
  if response.is_stream_response:
1071
834
  retval.append(
1072
835
  "deserialized = {}".format(
1073
- "response"
836
+ "response.iter_bytes()"
1074
837
  if self.code_model.options["version_tolerant"]
1075
838
  else "response.stream_download(self._client._pipeline)"
1076
839
  )
1077
840
  )
1078
- elif response.has_body:
841
+ elif response.type:
1079
842
  if self.code_model.options["models_mode"]:
1080
843
  retval.append(
1081
844
  f"deserialized = self._deserialize('{response.serialization_type}', pipeline_response)"
1082
845
  )
1083
846
  else:
1084
- is_xml = any(["xml" in ct for ct in response.content_types])
1085
847
  deserialized_value = (
1086
- "ET.fromstring(response.text())" if is_xml else "response.json()"
848
+ "ET.fromstring(response.text())"
849
+ if response.type.is_xml
850
+ else "response.json()"
1087
851
  )
1088
852
  retval.append(f"if response.content:")
1089
853
  retval.append(f" deserialized = {deserialized_value}")
@@ -1091,20 +855,21 @@ class _OperationBaseSerializer(
1091
855
  retval.append(f" deserialized = None")
1092
856
  return retval
1093
857
 
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)}:"]
858
+ def handle_error_response(self, builder: OperationType) -> List[str]:
859
+ retval = [
860
+ f"if response.status_code not in {str(builder.success_status_codes)}:"
861
+ ]
1101
862
  retval.append(
1102
863
  " map_error(status_code=response.status_code, response=response, error_map=error_map)"
1103
864
  )
1104
865
  error_model = ""
1105
- if builder.default_exception and self.code_model.options["models_mode"]:
866
+ if (
867
+ builder.default_error_deserialization
868
+ and self.code_model.options["models_mode"]
869
+ ):
1106
870
  retval.append(
1107
- f" error = self._deserialize.failsafe_deserialize({builder.default_exception}, pipeline_response)"
871
+ f" error = self._deserialize.failsafe_deserialize({builder.default_error_deserialization}, "
872
+ "pipeline_response)"
1108
873
  )
1109
874
  error_model = ", model=error"
1110
875
  retval.append(
@@ -1117,7 +882,7 @@ class _OperationBaseSerializer(
1117
882
  )
1118
883
  return retval
1119
884
 
1120
- def handle_response(self, builder) -> List[str]:
885
+ def handle_response(self, builder: OperationType) -> List[str]:
1121
886
  retval: List[str] = ["response = pipeline_response.http_response"]
1122
887
  retval.append("")
1123
888
  retval.extend(self.handle_error_response(builder))
@@ -1128,9 +893,9 @@ class _OperationBaseSerializer(
1128
893
  retval.append("response_headers = {}")
1129
894
  if builder.has_response_body or builder.any_response_has_headers:
1130
895
  if len(builder.responses) > 1:
1131
- for status_code in builder.success_status_code:
896
+ for status_code in builder.success_status_codes:
1132
897
  response = builder.get_response_from_status(status_code)
1133
- if response.headers or response.has_body:
898
+ if response.headers or response.type:
1134
899
  retval.append(f"if response.status_code == {status_code}:")
1135
900
  retval.extend(
1136
901
  [
@@ -1149,9 +914,7 @@ class _OperationBaseSerializer(
1149
914
  if builder.has_optional_return_type or self.code_model.options["models_mode"]:
1150
915
  deserialized = "deserialized"
1151
916
  else:
1152
- deserialized = (
1153
- f"cast({self._response_type_annotation(builder)}, deserialized)"
1154
- )
917
+ deserialized = f"cast({builder.response_type_annotation(async_mode=self.async_mode)}, deserialized)"
1155
918
  retval.append("if cls:")
1156
919
  retval.append(
1157
920
  " return cls(pipeline_response, {}, {})".format(
@@ -1169,23 +932,22 @@ class _OperationBaseSerializer(
1169
932
  retval.append("return 200 <= response.status_code <= 299")
1170
933
  return retval
1171
934
 
1172
- def error_map(self, builder) -> List[str]:
935
+ def error_map(self, builder: OperationType) -> List[str]:
1173
936
  retval = ["error_map = {"]
1174
- if builder.status_code_exceptions:
1175
- if not 401 in builder.status_code_exceptions_status_codes:
937
+ if builder.non_default_errors:
938
+ if not 401 in builder.non_default_error_status_codes:
1176
939
  retval.append(" 401: ClientAuthenticationError,")
1177
- if not 404 in builder.status_code_exceptions_status_codes:
940
+ if not 404 in builder.non_default_error_status_codes:
1178
941
  retval.append(" 404: ResourceNotFoundError,")
1179
- if not 409 in builder.status_code_exceptions_status_codes:
942
+ if not 409 in builder.non_default_error_status_codes:
1180
943
  retval.append(" 409: ResourceExistsError,")
1181
- for excep in builder.status_code_exceptions:
944
+ for excep in builder.non_default_errors:
1182
945
  error_model_str = ""
1183
946
  if (
1184
- isinstance(excep.schema, ObjectSchema)
1185
- and excep.is_exception
947
+ isinstance(excep.type, ModelType)
1186
948
  and self.code_model.options["models_mode"]
1187
949
  ):
1188
- error_model_str = f", model=self._deserialize(_models.{excep.serialization_type}, response)"
950
+ error_model_str = f", model=self._deserialize(_models.{excep.type.serialization_type}, response)"
1189
951
  error_format_str = (
1190
952
  ", error_format=ARMErrorFormat"
1191
953
  if self.code_model.options["azure_arm"]
@@ -1223,99 +985,46 @@ class _OperationBaseSerializer(
1223
985
  return retval
1224
986
 
1225
987
  @staticmethod
1226
- def get_metadata_url(builder) -> str:
988
+ def get_metadata_url(builder: OperationType) -> str:
1227
989
  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"
990
+ return f"{builder.name}.metadata = {{'url': { url }}} # type: ignore"
1241
991
 
1242
992
  @property
1243
993
  def _call_method(self) -> str:
1244
- return ""
1245
-
1246
-
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
-
994
+ return "await " if self.async_mode else ""
1265
995
 
1266
- class SyncOperationPython3Serializer(_SyncOperationBaseSerializer):
1267
- @property
1268
- def _want_inline_type_hints(self) -> bool:
1269
- return True
1270
996
 
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 "
997
+ class OperationSerializer(_OperationSerializer[Operation]):
998
+ ...
1297
999
 
1298
1000
 
1299
1001
  ############################## PAGING OPERATIONS ##############################
1300
1002
 
1003
+ PagingOperationType = TypeVar(
1004
+ "PagingOperationType", bound=Union[PagingOperation, LROPagingOperation]
1005
+ )
1006
+
1301
1007
 
1302
- class _PagingOperationBaseSerializer(
1303
- _OperationBaseSerializer
1008
+ class _PagingOperationSerializer(
1009
+ _OperationSerializer[PagingOperationType]
1304
1010
  ): # 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
1011
+ def __init__(
1012
+ self, code_model: CodeModel, async_mode: bool, is_python3_file: bool
1013
+ ) -> None:
1014
+ # for pylint reasons need to redefine init
1015
+ # probably because inheritance is going too deep
1016
+ super().__init__(code_model, async_mode, is_python3_file)
1017
+ self.code_model = code_model
1018
+ self.async_mode = async_mode
1019
+ self.is_python3_file = is_python3_file
1020
+ self.parameter_serializer = ParameterSerializer()
1021
+
1022
+ def serialize_path(self, builder: PagingOperationType) -> List[str]:
1023
+ return self.parameter_serializer.serialize_path(
1024
+ builder.parameters.path, self.serializer_name
1315
1025
  )
1316
- return f"# type: ClsType[{interior}]"
1317
1026
 
1318
- def decorators(self, builder, async_mode: bool) -> List[str]:
1027
+ def decorators(self, builder: PagingOperationType) -> List[str]:
1319
1028
  """Decorators for the method"""
1320
1029
  retval: List[str] = []
1321
1030
  if self.code_model.options["tracing"] and builder.want_tracing:
@@ -1324,7 +1033,7 @@ class _PagingOperationBaseSerializer(
1324
1033
  retval.append("@abc.abstractmethod")
1325
1034
  return retval
1326
1035
 
1327
- def call_next_link_request_builder(self, builder) -> List[str]:
1036
+ def call_next_link_request_builder(self, builder: PagingOperationType) -> List[str]:
1328
1037
  if builder.next_request_builder:
1329
1038
  request_builder = builder.next_request_builder
1330
1039
  template_url = (
@@ -1341,7 +1050,7 @@ class _PagingOperationBaseSerializer(
1341
1050
  builder, request_builder, template_url=template_url, is_next_request=True
1342
1051
  )
1343
1052
 
1344
- def _prepare_request_callback(self, builder) -> List[str]:
1053
+ def _prepare_request_callback(self, builder: PagingOperationType) -> List[str]:
1345
1054
  retval = ["def prepare_request(next_link=None):"]
1346
1055
  retval.append(" if not next_link:")
1347
1056
  retval.extend(
@@ -1363,17 +1072,13 @@ class _PagingOperationBaseSerializer(
1363
1072
  return retval
1364
1073
 
1365
1074
  @property
1366
- @abstractmethod
1367
- def _list_type_returned_to_users(self) -> str:
1368
- ...
1369
-
1370
- @staticmethod
1371
- @abstractmethod
1372
- def _pager(builder) -> str:
1373
- ...
1075
+ def _function_def(self) -> str:
1076
+ return "def"
1374
1077
 
1375
- def _extract_data_callback(self, builder) -> List[str]:
1376
- retval = [f"{self._def} extract_data(pipeline_response):"]
1078
+ def _extract_data_callback(self, builder: PagingOperationType) -> List[str]:
1079
+ retval = [
1080
+ f"{'async ' if self.async_mode else ''}def extract_data(pipeline_response):"
1081
+ ]
1377
1082
  response = builder.responses[0]
1378
1083
  deserialized = (
1379
1084
  f'self._deserialize("{response.serialization_type}", pipeline_response)'
@@ -1381,7 +1086,7 @@ class _PagingOperationBaseSerializer(
1381
1086
  else "pipeline_response.http_response.json()"
1382
1087
  )
1383
1088
  retval.append(f" deserialized = {deserialized}")
1384
- item_name = builder.item_name(self.code_model)
1089
+ item_name = builder.item_name
1385
1090
  list_of_elem = (
1386
1091
  f".{item_name}"
1387
1092
  if self.code_model.options["models_mode"]
@@ -1391,29 +1096,22 @@ class _PagingOperationBaseSerializer(
1391
1096
  retval.append(" if cls:")
1392
1097
  retval.append(" list_of_elem = cls(list_of_elem)")
1393
1098
 
1394
- next_link_name = builder.next_link_name
1395
- if not next_link_name:
1396
- next_link_property = "None"
1099
+ continuation_token_name = builder.continuation_token_name
1100
+ if not continuation_token_name:
1101
+ cont_token_property = "None"
1397
1102
  elif self.code_model.options["models_mode"]:
1398
- next_link_property = f"deserialized.{next_link_name} or None"
1103
+ cont_token_property = f"deserialized.{continuation_token_name} or None"
1399
1104
  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
- )
1105
+ cont_token_property = f'deserialized.get("{continuation_token_name}", None)'
1106
+ list_type = "AsyncList" if self.async_mode else "iter"
1107
+ retval.append(f" return {cont_token_property}, {list_type}(list_of_elem)")
1404
1108
  return retval
1405
1109
 
1406
- def _get_next_callback(self, builder) -> List[str]:
1407
- retval = [f"{self._def} get_next(next_link=None):"]
1110
+ def _get_next_callback(self, builder: PagingOperationType) -> List[str]:
1111
+ retval = [f"{'async ' if self.async_mode else ''}def get_next(next_link=None):"]
1408
1112
  retval.append(" request = prepare_request(next_link)")
1409
1113
  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(" )")
1114
+ retval.extend([f" {l}" for l in self.make_pipeline_call(builder)])
1417
1115
  retval.append(" response = pipeline_response.http_response")
1418
1116
  retval.append("")
1419
1117
  retval.extend([f" {line}" for line in self.handle_error_response(builder)])
@@ -1421,7 +1119,7 @@ class _PagingOperationBaseSerializer(
1421
1119
  retval.append(" return pipeline_response")
1422
1120
  return retval
1423
1121
 
1424
- def set_up_params_for_pager(self, builder) -> List[str]:
1122
+ def set_up_params_for_pager(self, builder: PagingOperationType) -> List[str]:
1425
1123
  retval = []
1426
1124
  retval.extend(self.error_map(builder))
1427
1125
  retval.extend(self._prepare_request_callback(builder))
@@ -1432,100 +1130,41 @@ class _PagingOperationBaseSerializer(
1432
1130
  return retval
1433
1131
 
1434
1132
 
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)
1133
+ class PagingOperationSerializer(_PagingOperationSerializer[PagingOperation]):
1134
+ ...
1489
1135
 
1490
1136
 
1491
1137
  ############################## LRO OPERATIONS ##############################
1492
1138
 
1139
+ LROOperationType = TypeVar(
1140
+ "LROOperationType", bound=Union[LROOperation, LROPagingOperation]
1141
+ )
1493
1142
 
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
-
1508
- @abstractmethod
1509
- def _poller(self, builder) -> str:
1510
- ...
1511
1143
 
1512
- @property
1513
- @abstractmethod
1514
- def _polling_method_type(self):
1515
- ...
1144
+ class _LROOperationSerializer(_OperationSerializer[LROOperationType]):
1145
+ def __init__(
1146
+ self, code_model: CodeModel, async_mode: bool, is_python3_file: bool
1147
+ ) -> None:
1148
+ # for pylint reasons need to redefine init
1149
+ # probably because inheritance is going too deep
1150
+ super().__init__(code_model, async_mode, is_python3_file)
1151
+ self.code_model = code_model
1152
+ self.async_mode = async_mode
1153
+ self.is_python3_file = is_python3_file
1154
+ self.parameter_serializer = ParameterSerializer()
1516
1155
 
1517
- def param_description(self, builder) -> List[str]:
1156
+ def param_description(self, builder: LROOperationType) -> List[str]:
1518
1157
  retval = super().param_description(builder)
1519
1158
  retval.append(
1520
1159
  ":keyword str continuation_token: A continuation token to restart a poller from a saved state."
1521
1160
  )
1522
1161
  retval.append(
1523
- f":keyword polling: By default, your polling method will be {self._default_polling_method(builder)}. "
1162
+ f":keyword polling: By default, your polling method will be {builder.get_polling_method(self.async_mode)}. "
1524
1163
  "Pass in False for this operation to not poll, or pass in your own initialized polling object for a"
1525
1164
  " personal polling strategy."
1526
1165
  )
1527
1166
  retval.append(
1528
- f":paramtype polling: bool or ~azure.core.polling.{self._polling_method_type}"
1167
+ f":paramtype polling: bool or ~{builder.get_base_polling_method_path(self.async_mode)}"
1529
1168
  )
1530
1169
  retval.append(
1531
1170
  ":keyword int polling_interval: Default waiting time between two polls for LRO operations "
@@ -1533,9 +1172,15 @@ class _LROOperationBaseSerializer(
1533
1172
  )
1534
1173
  return retval
1535
1174
 
1536
- def initial_call(self, builder) -> List[str]:
1175
+ def serialize_path(self, builder: LROOperationType) -> List[str]:
1176
+ return self.parameter_serializer.serialize_path(
1177
+ builder.parameters.path, self.serializer_name
1178
+ )
1179
+
1180
+ def initial_call(self, builder: LROOperationType) -> List[str]:
1537
1181
  retval = [
1538
- f"polling = kwargs.pop('polling', True) # type: Union[bool, {self._polling_method_type}]"
1182
+ "polling = kwargs.pop('polling', True) # type: Union[bool, "
1183
+ f"{builder.get_base_polling_method(self.async_mode)}]"
1539
1184
  ]
1540
1185
  retval.append("lro_delay = kwargs.pop(")
1541
1186
  retval.append(" 'polling_interval',")
@@ -1550,7 +1195,7 @@ class _LROOperationBaseSerializer(
1550
1195
  )
1551
1196
  retval.extend(
1552
1197
  [
1553
- f" {parameter.serialized_name}={parameter.serialized_name},"
1198
+ f" {parameter.client_name}={parameter.client_name},"
1554
1199
  for parameter in builder.parameters.method
1555
1200
  ]
1556
1201
  )
@@ -1562,7 +1207,7 @@ class _LROOperationBaseSerializer(
1562
1207
  retval.append("kwargs.pop('error_map', None)")
1563
1208
  return retval
1564
1209
 
1565
- def return_lro_poller(self, builder) -> List[str]:
1210
+ def return_lro_poller(self, builder: LROOperationType) -> List[str]:
1566
1211
  retval = []
1567
1212
  lro_options_str = (
1568
1213
  "lro_options={'final-state-via': '"
@@ -1579,40 +1224,46 @@ class _LROOperationBaseSerializer(
1579
1224
  retval.extend(
1580
1225
  [
1581
1226
  "if polling is True:",
1582
- f" polling_method = cast({self._polling_method_type}, {self._default_polling_method(builder)}(",
1227
+ f" polling_method = cast({builder.get_base_polling_method(self.async_mode)}, "
1228
+ f"{builder.get_polling_method(self.async_mode)}(",
1583
1229
  " lro_delay,",
1584
1230
  f" {lro_options_str}",
1585
1231
  f" {path_format_arguments_str}",
1586
1232
  " **kwargs",
1587
- f")) # type: {self._polling_method_type}",
1233
+ f")) # type: {builder.get_base_polling_method(self.async_mode)}",
1588
1234
  ]
1589
1235
  )
1590
1236
  retval.append(
1591
- f"elif polling is False: polling_method = cast({self._polling_method_type}, "
1592
- f"{self._default_no_polling_method(builder)}())"
1237
+ f"elif polling is False: polling_method = cast({builder.get_base_polling_method(self.async_mode)}, "
1238
+ f"{builder.get_no_polling_method(self.async_mode)}())"
1593
1239
  )
1594
1240
  retval.append("else: polling_method = polling")
1595
1241
  retval.append("if cont_token:")
1596
- retval.append(f" return {self._poller(builder)}.from_continuation_token(")
1242
+ retval.append(
1243
+ f" return {builder.get_poller(self.async_mode)}.from_continuation_token("
1244
+ )
1597
1245
  retval.append(" polling_method=polling_method,")
1598
1246
  retval.append(" continuation_token=cont_token,")
1599
1247
  retval.append(" client=self._client,")
1600
1248
  retval.append(" deserialization_callback=get_long_running_output")
1601
1249
  retval.append(" )")
1602
1250
  retval.append(
1603
- f"return {self._poller(builder)}"
1251
+ f"return {builder.get_poller(self.async_mode)}"
1604
1252
  "(self._client, raw_result, get_long_running_output, polling_method)"
1605
1253
  )
1606
1254
  return retval
1607
1255
 
1608
- def get_long_running_output(self, builder) -> List[str]:
1609
- retval = ["def get_long_running_output(pipeline_response):"]
1256
+ def get_long_running_output(self, builder: LROOperationType) -> List[str]:
1257
+ pylint_disable = ""
1258
+ if not builder.lro_response:
1259
+ pylint_disable = " # pylint: disable=inconsistent-return-statements"
1260
+ retval = [f"def get_long_running_output(pipeline_response):{pylint_disable}"]
1610
1261
  if builder.lro_response:
1611
- if builder.lro_response.has_headers:
1262
+ if builder.lro_response.headers:
1612
1263
  retval.append(" response_headers = {}")
1613
1264
  if (
1614
1265
  not self.code_model.options["models_mode"]
1615
- or builder.lro_response.has_headers
1266
+ or builder.lro_response.headers
1616
1267
  ):
1617
1268
  retval.append(" response = pipeline_response.http_response")
1618
1269
  retval.extend(
@@ -1627,268 +1278,75 @@ class _LROOperationBaseSerializer(
1627
1278
  retval.append(
1628
1279
  " return cls(pipeline_response, {}, {})".format(
1629
1280
  "deserialized"
1630
- if builder.lro_response and builder.lro_response.has_body
1281
+ if builder.lro_response and builder.lro_response.type
1631
1282
  else "None",
1632
1283
  "response_headers"
1633
- if builder.lro_response and builder.lro_response.has_headers
1284
+ if builder.lro_response and builder.lro_response.headers
1634
1285
  else "{}",
1635
1286
  )
1636
1287
  )
1637
- if builder.lro_response and builder.lro_response.has_body:
1288
+ if builder.lro_response and builder.lro_response.type:
1638
1289
  retval.append(" return deserialized")
1639
1290
  return retval
1640
1291
 
1641
1292
 
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
-
1293
+ class LROOperationSerializer(_LROOperationSerializer[LROOperation]):
1294
+ ...
1676
1295
 
1677
- class SyncLROOperationGenericSerializer(
1678
- _SyncLROOperationBaseSerializer, SyncOperationGenericSerializer
1679
- ):
1680
- pass
1681
1296
 
1297
+ ############################## LRO PAGING OPERATIONS ##############################
1682
1298
 
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 {}"
1699
-
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
-
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
- )
1712
-
1713
- def _default_no_polling_method(self, builder) -> str:
1714
- return builder.get_default_no_polling_method(async_mode=True)
1715
1299
 
1300
+ class LROPagingOperationSerializer(
1301
+ _LROOperationSerializer[LROPagingOperation],
1302
+ _PagingOperationSerializer[LROPagingOperation],
1303
+ ): # pylint: disable=abstract-method
1716
1304
  @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 ##############################
1305
+ def _call_method(self) -> str:
1306
+ return "await " if self.async_mode else ""
1725
1307
 
1308
+ @property
1309
+ def _function_def(self) -> str:
1310
+ return "async def" if self.async_mode else "def"
1726
1311
 
1727
- class _LROPagingOperationBaseSerializer(
1728
- _LROOperationBaseSerializer, _PagingOperationBaseSerializer
1729
- ): # pylint: disable=abstract-method
1730
- def get_long_running_output(self, builder) -> List[str]:
1312
+ def get_long_running_output(self, builder: LROPagingOperation) -> List[str]:
1731
1313
  retval = ["def get_long_running_output(pipeline_response):"]
1732
- retval.append(f" {self._def} internal_get_next(next_link=None):")
1314
+ retval.append(f" {self._function_def} internal_get_next(next_link=None):")
1733
1315
  retval.append(" if next_link is None:")
1734
1316
  retval.append(" return pipeline_response")
1735
1317
  retval.append(f" return {self._call_method}get_next(next_link)")
1736
1318
  retval.append("")
1737
- retval.append(f" return {self._pager(builder)}(")
1319
+ retval.append(f" return {builder.get_pager(self.async_mode)}(")
1738
1320
  retval.append(" internal_get_next, extract_data")
1739
1321
  retval.append(" )")
1740
1322
  return retval
1741
1323
 
1742
- def decorators(self, builder, async_mode: bool) -> List[str]:
1324
+ def decorators(self, builder: LROPagingOperation) -> List[str]: # type: ignore
1743
1325
  """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
- )
1326
+ return _LROOperationSerializer.decorators(self, builder) # type: ignore
1832
1327
 
1833
1328
 
1834
1329
  def get_operation_serializer(
1835
- builder,
1330
+ builder: Operation,
1836
1331
  code_model,
1837
1332
  async_mode: bool,
1838
1333
  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)
1334
+ ) -> Union[
1335
+ OperationSerializer,
1336
+ PagingOperationSerializer,
1337
+ LROOperationSerializer,
1338
+ LROPagingOperationSerializer,
1339
+ ]:
1340
+ retcls: Union[
1341
+ Type[OperationSerializer],
1342
+ Type[PagingOperationSerializer],
1343
+ Type[LROOperationSerializer],
1344
+ Type[LROPagingOperationSerializer],
1345
+ ] = OperationSerializer
1346
+ if builder.operation_type == "lropaging":
1347
+ retcls = LROPagingOperationSerializer
1348
+ elif builder.operation_type == "lro":
1349
+ retcls = LROOperationSerializer
1350
+ elif builder.operation_type == "paging":
1351
+ retcls = PagingOperationSerializer
1352
+ return retcls(code_model, async_mode, is_python3_file)