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