@autorest/python 5.17.0 → 6.0.0-rc.1

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 (56) hide show
  1. package/ChangeLog.md +63 -1
  2. package/README.md +9 -0
  3. package/autorest/codegen/__init__.py +24 -30
  4. package/autorest/codegen/models/base_builder.py +17 -6
  5. package/autorest/codegen/models/base_type.py +6 -0
  6. package/autorest/codegen/models/client.py +9 -6
  7. package/autorest/codegen/models/code_model.py +20 -14
  8. package/autorest/codegen/models/dictionary_type.py +16 -1
  9. package/autorest/codegen/models/imports.py +57 -2
  10. package/autorest/codegen/models/list_type.py +16 -1
  11. package/autorest/codegen/models/lro_operation.py +4 -6
  12. package/autorest/codegen/models/lro_paging_operation.py +3 -9
  13. package/autorest/codegen/models/model_type.py +34 -16
  14. package/autorest/codegen/models/operation.py +47 -79
  15. package/autorest/codegen/models/operation_group.py +10 -9
  16. package/autorest/codegen/models/paging_operation.py +4 -6
  17. package/autorest/codegen/models/parameter.py +3 -7
  18. package/autorest/codegen/models/parameter_list.py +26 -35
  19. package/autorest/codegen/models/property.py +14 -0
  20. package/autorest/codegen/models/request_builder.py +32 -43
  21. package/autorest/codegen/serializers/__init__.py +12 -50
  22. package/autorest/codegen/serializers/builder_serializer.py +136 -49
  23. package/autorest/codegen/serializers/client_serializer.py +23 -32
  24. package/autorest/codegen/serializers/general_serializer.py +12 -12
  25. package/autorest/codegen/serializers/import_serializer.py +11 -22
  26. package/autorest/codegen/serializers/metadata_serializer.py +0 -2
  27. package/autorest/codegen/serializers/{model_base_serializer.py → model_serializer.py} +58 -44
  28. package/autorest/codegen/serializers/operation_groups_serializer.py +3 -7
  29. package/autorest/codegen/serializers/operations_init_serializer.py +2 -23
  30. package/autorest/codegen/serializers/patch_serializer.py +1 -3
  31. package/autorest/codegen/serializers/request_builders_serializer.py +2 -5
  32. package/autorest/codegen/serializers/utils.py +3 -4
  33. package/autorest/codegen/templates/client.py.jinja2 +6 -3
  34. package/autorest/codegen/templates/config.py.jinja2 +2 -2
  35. package/autorest/codegen/templates/metadata.json.jinja2 +4 -4
  36. package/autorest/codegen/templates/model.py.jinja2 +1 -1
  37. package/autorest/codegen/templates/model_init.py.jinja2 +5 -12
  38. package/autorest/codegen/templates/operation_group.py.jinja2 +16 -3
  39. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +2 -8
  40. package/autorest/codegen/templates/operation_tools.jinja2 +3 -1
  41. package/autorest/codegen/templates/patch.py.jinja2 +1 -2
  42. package/autorest/codegen/templates/request_builder.py.jinja2 +0 -7
  43. package/autorest/codegen/templates/request_builders.py.jinja2 +1 -4
  44. package/autorest/codegen/templates/rest_init.py.jinja2 +3 -8
  45. package/autorest/codegen/templates/serialization.py.jinja2 +2006 -0
  46. package/autorest/codegen/templates/setup.py.jinja2 +4 -0
  47. package/autorest/codegen/templates/vendor.py.jinja2 +10 -0
  48. package/autorest/m4reformatter/__init__.py +82 -58
  49. package/autorest/multiapi/models/client.py +12 -2
  50. package/autorest/multiapi/serializers/__init__.py +17 -8
  51. package/autorest/multiapi/serializers/import_serializer.py +4 -8
  52. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +1 -1
  53. package/autorest/preprocess/__init__.py +1 -0
  54. package/package.json +2 -2
  55. package/autorest/codegen/serializers/model_generic_serializer.py +0 -32
  56. package/autorest/codegen/serializers/model_python3_serializer.py +0 -72
@@ -47,7 +47,7 @@ class ModelType(BaseType): # pylint: disable=too-many-instance-attributes
47
47
  *,
48
48
  properties: Optional[List[Property]] = None,
49
49
  parents: Optional[List["ModelType"]] = None,
50
- discriminated_subtypes: Optional[Dict[str, str]] = None,
50
+ discriminated_subtypes: Optional[Dict[str, "ModelType"]] = None,
51
51
  ) -> None:
52
52
  super().__init__(yaml_data=yaml_data, code_model=code_model)
53
53
  self.name: str = self.yaml_data["name"]
@@ -61,6 +61,7 @@ class ModelType(BaseType): # pylint: disable=too-many-instance-attributes
61
61
  )
62
62
  self._created_json_template_representation = False
63
63
  self.is_public: bool = self.yaml_data.get("isPublic", True)
64
+ self.snake_case_name: str = self.yaml_data["snakeCaseName"]
64
65
 
65
66
  @property
66
67
  def is_xml(self) -> bool:
@@ -111,6 +112,10 @@ class ModelType(BaseType): # pylint: disable=too-many-instance-attributes
111
112
  # but we don't want to write a serialization context for an object.
112
113
  return super().xml_serialization_ctxt
113
114
 
115
+ @property
116
+ def discriminated_subtypes_name_mapping(self) -> Dict[str, str]:
117
+ return {k: v.name for k, v in self.discriminated_subtypes.items()}
118
+
114
119
  def get_json_template_representation(
115
120
  self,
116
121
  *,
@@ -121,6 +126,11 @@ class ModelType(BaseType): # pylint: disable=too-many-instance-attributes
121
126
  if self._created_json_template_representation:
122
127
  return "..." # do this to avoid loop
123
128
  self._created_json_template_representation = True
129
+ if self.discriminated_subtypes:
130
+ # we will instead print the discriminated subtypes
131
+ self._created_json_template_representation = False
132
+ return self.snake_case_name
133
+
124
134
  # don't add additional properties, because there's not really a concept of
125
135
  # additional properties in the template
126
136
  representation = {
@@ -135,20 +145,30 @@ class ModelType(BaseType): # pylint: disable=too-many-instance-attributes
135
145
  if not (p.is_discriminator or p.client_name == "additional_properties")
136
146
  ]
137
147
  }
138
- try:
139
- # add discriminator prop if there is one
140
- discriminator = next(p for p in self.properties if p.is_discriminator)
141
- representation[discriminator.rest_api_name] = (
142
- self.discriminator_value or discriminator.rest_api_name
143
- )
144
- except StopIteration:
145
- pass
148
+ if self.discriminator and self.discriminator_value:
149
+ representation[
150
+ f'"{self.discriminator.rest_api_name}"'
151
+ ] = f'"{self.discriminator_value}"'
146
152
 
147
153
  # once we've finished, we want to reset created_json_template_representation to false
148
154
  # so we can call it again
149
155
  self._created_json_template_representation = False
150
156
  return representation
151
157
 
158
+ def get_polymorphic_subtypes(self, polymorphic_subtypes: List["ModelType"]) -> None:
159
+ is_polymorphic_subtype = (
160
+ self.discriminator_value and not self.discriminated_subtypes
161
+ )
162
+ if (
163
+ self.name not in (m.name for m in polymorphic_subtypes)
164
+ and is_polymorphic_subtype
165
+ ):
166
+ polymorphic_subtypes.append(self)
167
+ for discriminated_subtype in self.discriminated_subtypes.values():
168
+ discriminated_subtype.get_polymorphic_subtypes(polymorphic_subtypes)
169
+ for property in self.properties:
170
+ property.get_polymorphic_subtypes(polymorphic_subtypes)
171
+
152
172
  @classmethod
153
173
  def from_yaml(
154
174
  cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
@@ -172,7 +192,10 @@ class ModelType(BaseType): # pylint: disable=too-many-instance-attributes
172
192
  ]
173
193
  self.properties = _get_properties(self, properties)
174
194
  # checking to see if this is a polymorphic class
175
- self.discriminated_subtypes = self.yaml_data.get("discriminatedSubtypes", {})
195
+ self.discriminated_subtypes = {
196
+ k: cast(ModelType, build_type(v, code_model))
197
+ for k, v in self.yaml_data.get("discriminatedSubtypes", {}).items()
198
+ }
176
199
 
177
200
  @property
178
201
  def has_readonly_or_constant_property(self) -> bool:
@@ -215,13 +238,8 @@ class ModelType(BaseType): # pylint: disable=too-many-instance-attributes
215
238
  relative_path, "models", ImportType.LOCAL, alias="_models"
216
239
  )
217
240
  else:
218
- # a little hacky, but we only do this for version tolerant
219
- # models files, which are all python3 only
220
- models_filename = self.code_model.get_models_filename(
221
- is_python3_file=True
222
- )
223
241
  file_import.add_submodule_import(
224
- f"{relative_path}models.{models_filename}",
242
+ f"{relative_path}models.{self.code_model.models_filename}",
225
243
  self.name,
226
244
  ImportType.LOCAL,
227
245
  )
@@ -3,7 +3,6 @@
3
3
  # Licensed under the MIT License. See License.txt in the project root for
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
- import logging
7
6
  from itertools import chain
8
7
  from typing import (
9
8
  Dict,
@@ -43,8 +42,6 @@ from .request_builder import OverloadedRequestBuilder, RequestBuilder
43
42
  if TYPE_CHECKING:
44
43
  from .code_model import CodeModel
45
44
 
46
- _LOGGER = logging.getLogger(__name__)
47
-
48
45
  ResponseType = TypeVar(
49
46
  "ResponseType",
50
47
  bound=Union[Response, PagingResponse, LROResponse, LROPagingResponse],
@@ -67,7 +64,6 @@ class OperationBase( # pylint: disable=too-many-public-methods
67
64
  overloads: Optional[List["Operation"]] = None,
68
65
  public: bool = True,
69
66
  want_tracing: bool = True,
70
- abstract: bool = False,
71
67
  ) -> None:
72
68
  super().__init__(
73
69
  code_model=code_model,
@@ -75,7 +71,6 @@ class OperationBase( # pylint: disable=too-many-public-methods
75
71
  name=name,
76
72
  parameters=parameters,
77
73
  overloads=overloads,
78
- abstract=abstract,
79
74
  want_tracing=want_tracing,
80
75
  )
81
76
  self.overloads: List["Operation"] = overloads or []
@@ -204,9 +199,8 @@ class OperationBase( # pylint: disable=too-many-public-methods
204
199
  file_import.add_submodule_import(
205
200
  "typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL
206
201
  )
207
- if not self.abstract:
208
- for param in self.parameters.method:
209
- file_import.merge(param.imports(async_mode, **kwargs))
202
+ for param in self.parameters.method:
203
+ file_import.merge(param.imports(async_mode, **kwargs))
210
204
 
211
205
  response_types = [
212
206
  r.type_annotation(async_mode=async_mode) for r in self.responses if r.type
@@ -218,6 +212,8 @@ class OperationBase( # pylint: disable=too-many-public-methods
218
212
  return file_import
219
213
 
220
214
  def imports_for_multiapi(self, async_mode: bool, **kwargs: Any) -> FileImport:
215
+ if self.abstract:
216
+ return FileImport()
221
217
  file_import = self._imports_shared(async_mode, **kwargs)
222
218
  for response in self.responses:
223
219
  file_import.merge(
@@ -273,22 +269,16 @@ class OperationBase( # pylint: disable=too-many-public-methods
273
269
  alias="rest",
274
270
  )
275
271
  if self.code_model.options["builders_visibility"] == "embedded" and async_mode:
276
- suffix = (
277
- "_py3"
278
- if self.code_model.options["add_python3_operation_files"]
279
- and not self.code_model.options["python3_only"]
280
- else ""
281
- )
282
272
  file_import.add_submodule_import(
283
- f"...{self.code_model.operations_folder_name}.{self.filename}{suffix}",
273
+ f"...{self.code_model.operations_folder_name}.{self.filename}",
284
274
  request_builder.name,
285
275
  import_type=ImportType.LOCAL,
286
276
  )
287
277
  return file_import
288
278
 
289
- def imports(
290
- self, async_mode: bool, is_python3_file: bool, **kwargs: Any
291
- ) -> FileImport:
279
+ def imports(self, async_mode: bool, **kwargs: Any) -> FileImport:
280
+ if self.abstract:
281
+ return FileImport()
292
282
  file_import = self._imports_shared(async_mode, **kwargs)
293
283
 
294
284
  for response in self.responses:
@@ -301,48 +291,44 @@ class OperationBase( # pylint: disable=too-many-public-methods
301
291
  file_import.merge(self.parameters.body_parameter.type.imports(**kwargs))
302
292
 
303
293
  # Exceptions
304
- if self.abstract:
305
- file_import.add_import("abc", ImportType.STDLIB)
306
- else:
307
- file_import.add_submodule_import(
308
- "azure.core.exceptions", "map_error", ImportType.AZURECORE
309
- )
310
- if self.code_model.options["azure_arm"]:
311
- file_import.add_submodule_import(
312
- "azure.mgmt.core.exceptions", "ARMErrorFormat", ImportType.AZURECORE
313
- )
314
- file_import.add_submodule_import(
315
- "azure.core.exceptions", "HttpResponseError", ImportType.AZURECORE
316
- )
294
+ file_import.add_submodule_import(
295
+ "azure.core.exceptions", "map_error", ImportType.AZURECORE
296
+ )
297
+ if self.code_model.options["azure_arm"]:
317
298
  file_import.add_submodule_import(
318
- "azure.core.exceptions",
319
- "ClientAuthenticationError",
320
- ImportType.AZURECORE,
299
+ "azure.mgmt.core.exceptions", "ARMErrorFormat", ImportType.AZURECORE
321
300
  )
301
+ file_import.add_submodule_import(
302
+ "azure.core.exceptions", "HttpResponseError", ImportType.AZURECORE
303
+ )
304
+ file_import.add_submodule_import(
305
+ "azure.core.exceptions",
306
+ "ClientAuthenticationError",
307
+ ImportType.AZURECORE,
308
+ )
309
+ file_import.add_submodule_import(
310
+ "azure.core.exceptions", "ResourceNotFoundError", ImportType.AZURECORE
311
+ )
312
+ file_import.add_submodule_import(
313
+ "azure.core.exceptions", "ResourceExistsError", ImportType.AZURECORE
314
+ )
315
+
316
+ if self.has_kwargs_to_pop_with_default(
317
+ self.parameters.kwargs_to_pop, ParameterLocation.HEADER
318
+ ) or self.has_kwargs_to_pop_with_default(
319
+ self.parameters.kwargs_to_pop, ParameterLocation.QUERY
320
+ ):
322
321
  file_import.add_submodule_import(
323
- "azure.core.exceptions", "ResourceNotFoundError", ImportType.AZURECORE
322
+ "azure.core.utils", "case_insensitive_dict", ImportType.AZURECORE
324
323
  )
324
+ if self.deprecated:
325
+ file_import.add_import("warnings", ImportType.STDLIB)
326
+
327
+ if self.code_model.need_request_converter:
328
+ relative_path = "..." if async_mode else ".."
325
329
  file_import.add_submodule_import(
326
- "azure.core.exceptions", "ResourceExistsError", ImportType.AZURECORE
330
+ f"{relative_path}_vendor", "_convert_request", ImportType.LOCAL
327
331
  )
328
-
329
- kwargs_to_pop = self.parameters.kwargs_to_pop(is_python3_file)
330
- if self.has_kwargs_to_pop_with_default(
331
- kwargs_to_pop, ParameterLocation.HEADER
332
- ) or self.has_kwargs_to_pop_with_default(
333
- kwargs_to_pop, ParameterLocation.QUERY
334
- ):
335
- file_import.add_submodule_import(
336
- "azure.core.utils", "case_insensitive_dict", ImportType.AZURECORE
337
- )
338
- if self.deprecated:
339
- file_import.add_import("warnings", ImportType.STDLIB)
340
-
341
- if self.code_model.need_request_converter:
342
- relative_path = "..." if async_mode else ".."
343
- file_import.add_submodule_import(
344
- f"{relative_path}_vendor", "_convert_request", ImportType.LOCAL
345
- )
346
332
  if async_mode:
347
333
  file_import.add_submodule_import(
348
334
  "azure.core.pipeline.transport",
@@ -382,10 +368,9 @@ class OperationBase( # pylint: disable=too-many-public-methods
382
368
  f"distributed_trace",
383
369
  ImportType.AZURECORE,
384
370
  )
385
- if not self.abstract:
386
- file_import.merge(
387
- self.get_request_builder_import(self.request_builder, async_mode)
388
- )
371
+ file_import.merge(
372
+ self.get_request_builder_import(self.request_builder, async_mode)
373
+ )
389
374
  if self.overloads:
390
375
  file_import.add_submodule_import("typing", "overload", ImportType.STDLIB)
391
376
  return file_import
@@ -439,20 +424,6 @@ class OperationBase( # pylint: disable=too-many-public-methods
439
424
  cls.from_yaml(overload, code_model)
440
425
  for overload in yaml_data.get("overloads", [])
441
426
  ]
442
- abstract = False
443
- if (
444
- code_model.options["version_tolerant"]
445
- and parameter_list.has_body
446
- and isinstance(parameter_list.body_parameter, MultipartBodyParameter)
447
- ):
448
- _LOGGER.warning(
449
- 'Not going to generate operation "%s" because it has multipart / urlencoded body parameters. '
450
- "Multipart / urlencoded body parameters are not supported for version tolerant generation right now. "
451
- 'Please write your own custom operation in the "_patch.py" file '
452
- "following https://aka.ms/azsdk/python/dpcodegen/python/customize",
453
- name,
454
- )
455
- abstract = True
456
427
 
457
428
  return cls(
458
429
  yaml_data=yaml_data,
@@ -464,23 +435,20 @@ class OperationBase( # pylint: disable=too-many-public-methods
464
435
  responses=responses,
465
436
  exceptions=exceptions,
466
437
  want_tracing=not yaml_data["isOverload"],
467
- abstract=abstract,
468
438
  )
469
439
 
470
440
 
471
441
  class Operation(OperationBase[Response]):
472
- def imports(
473
- self, async_mode: bool, is_python3_file: bool, **kwargs: Any
474
- ) -> FileImport:
475
- file_import = super().imports(async_mode, is_python3_file, **kwargs)
442
+ def imports(self, async_mode: bool, **kwargs: Any) -> FileImport:
443
+ file_import = super().imports(async_mode, **kwargs)
444
+ if self.abstract:
445
+ return file_import
476
446
  if async_mode:
477
447
  file_import.add_submodule_import(
478
448
  f"azure.core.tracing.decorator_async",
479
449
  f"distributed_trace_async",
480
450
  ImportType.AZURECORE,
481
451
  )
482
- if self.abstract:
483
- return file_import
484
452
  if (
485
453
  self.has_response_body
486
454
  and not self.has_optional_return_type
@@ -36,14 +36,11 @@ class OperationGroup(BaseModel):
36
36
  def has_abstract_operations(self) -> bool:
37
37
  return any(o for o in self.operations if o.abstract)
38
38
 
39
- def base_class(self, async_mode: bool) -> str:
39
+ @property
40
+ def base_class(self) -> str:
40
41
  base_classes: List[str] = []
41
42
  if self.is_mixin and self.code_model.need_mixin_abc:
42
43
  base_classes.append("MixinABC")
43
- if not (async_mode or self.code_model.options["python3_only"]):
44
- base_classes.append("object")
45
- if self.has_abstract_operations:
46
- base_classes.append("abc.ABC")
47
44
  return ", ".join(base_classes)
48
45
 
49
46
  def imports_for_multiapi(self, async_mode: bool) -> FileImport:
@@ -69,15 +66,13 @@ class OperationGroup(BaseModel):
69
66
  return " # type: ignore"
70
67
  return ""
71
68
 
72
- def imports(self, async_mode: bool, is_python3_file: bool) -> FileImport:
69
+ def imports(self, async_mode: bool) -> FileImport:
73
70
  file_import = FileImport()
74
71
 
75
72
  relative_path = "..." if async_mode else ".."
76
73
  for operation in self.operations:
77
74
  file_import.merge(
78
- operation.imports(
79
- async_mode, is_python3_file, relative_path=relative_path
80
- )
75
+ operation.imports(async_mode, relative_path=relative_path)
81
76
  )
82
77
  # for multiapi
83
78
  if not self.code_model.options["version_tolerant"]:
@@ -89,6 +84,12 @@ class OperationGroup(BaseModel):
89
84
  )
90
85
  if self.code_model.need_mixin_abc:
91
86
  file_import.add_submodule_import(".._vendor", "MixinABC", ImportType.LOCAL)
87
+ if self.has_abstract_operations:
88
+ file_import.add_submodule_import(
89
+ ".._vendor", "raise_if_not_implemented", ImportType.LOCAL
90
+ )
91
+ if all(o.abstract for o in self.operations):
92
+ return file_import
92
93
  file_import.add_submodule_import(
93
94
  "typing", "TypeVar", ImportType.STDLIB, TypingSection.CONDITIONAL
94
95
  )
@@ -38,7 +38,6 @@ class PagingOperationBase(OperationBase[PagingResponseType]):
38
38
  overloads: Optional[List[Operation]] = None,
39
39
  public: bool = True,
40
40
  want_tracing: bool = True,
41
- abstract: bool = False,
42
41
  override_success_response_to_200: bool = False,
43
42
  ) -> None:
44
43
  super().__init__(
@@ -52,7 +51,6 @@ class PagingOperationBase(OperationBase[PagingResponseType]):
52
51
  overloads=overloads,
53
52
  public=public,
54
53
  want_tracing=want_tracing,
55
- abstract=abstract,
56
54
  )
57
55
  self.next_request_builder: Optional[
58
56
  Union[RequestBuilder, OverloadedRequestBuilder]
@@ -127,11 +125,11 @@ class PagingOperationBase(OperationBase[PagingResponseType]):
127
125
  def has_optional_return_type(self) -> bool:
128
126
  return False
129
127
 
130
- def imports(
131
- self, async_mode: bool, is_python3_file: bool, **kwargs: Any
132
- ) -> FileImport:
128
+ def imports(self, async_mode: bool, **kwargs: Any) -> FileImport:
129
+ if self.abstract:
130
+ return FileImport()
133
131
  file_import = self._imports_shared(async_mode, **kwargs)
134
- file_import.merge(super().imports(async_mode, is_python3_file, **kwargs))
132
+ file_import.merge(super().imports(async_mode, **kwargs))
135
133
  if self.code_model.options["tracing"] and self.want_tracing:
136
134
  file_import.add_submodule_import(
137
135
  "azure.core.tracing.decorator",
@@ -179,15 +179,11 @@ class _ParameterBase(
179
179
  def in_method_signature(self) -> bool:
180
180
  ...
181
181
 
182
- def method_signature(self, is_python3_file: bool, async_mode: bool) -> str:
182
+ def method_signature(self, async_mode: bool) -> str:
183
183
  type_annot = self.type_annotation(async_mode=async_mode)
184
- if is_python3_file:
185
- if self.client_default_value is not None or self.optional:
186
- return f"{self.client_name}: {type_annot} = {self.client_default_value_declaration},"
187
- return f"{self.client_name}: {type_annot},"
188
184
  if self.client_default_value is not None or self.optional:
189
- return f"{self.client_name}={self.client_default_value_declaration}, # type: {type_annot}"
190
- return f"{self.client_name}, # type: {type_annot}"
185
+ return f"{self.client_name}: {type_annot} = {self.client_default_value_declaration},"
186
+ return f"{self.client_name}: {type_annot},"
191
187
 
192
188
 
193
189
  class _BodyParameterBase(_ParameterBase):
@@ -235,49 +235,36 @@ class _ParameterListBase(
235
235
  """Sorted method params. First positional, then keyword only, then kwarg"""
236
236
  return self.positional + self.keyword_only + self.kwarg
237
237
 
238
- def method_signature(self, is_python3_file: bool, async_mode: bool) -> List[str]:
238
+ def method_signature(self, async_mode: bool) -> List[str]:
239
239
  """Method signature for this parameter list."""
240
240
  return method_signature_helper(
241
- positional=self.method_signature_positional(is_python3_file, async_mode),
242
- keyword_only=self.method_signature_keyword_only(
243
- is_python3_file, async_mode
244
- ),
245
- kwarg_params=self.method_signature_kwargs(is_python3_file),
241
+ positional=self.method_signature_positional(async_mode),
242
+ keyword_only=self.method_signature_keyword_only(async_mode),
243
+ kwarg_params=self.method_signature_kwargs,
246
244
  )
247
245
 
248
- def method_signature_positional(
249
- self, is_python3_file: bool, async_mode: bool
250
- ) -> List[str]:
246
+ def method_signature_positional(self, async_mode: bool) -> List[str]:
251
247
  """Signature for positional parameters"""
252
- return [
253
- parameter.method_signature(is_python3_file, async_mode)
254
- for parameter in self.positional
255
- ]
248
+ return [parameter.method_signature(async_mode) for parameter in self.positional]
256
249
 
257
- def method_signature_keyword_only(
258
- self, is_python3_file: bool, async_mode: bool
259
- ) -> List[str]:
250
+ def method_signature_keyword_only(self, async_mode: bool) -> List[str]:
260
251
  """Signature for keyword only parameters"""
261
- if not (self.keyword_only and is_python3_file):
252
+ if not self.keyword_only:
262
253
  return []
263
254
  return ["*,"] + [
264
- parameter.method_signature(is_python3_file, async_mode)
265
- for parameter in self.keyword_only
255
+ parameter.method_signature(async_mode) for parameter in self.keyword_only
266
256
  ]
267
257
 
268
- @staticmethod
269
- def method_signature_kwargs(is_python3_file: bool) -> List[str]:
258
+ @property
259
+ def method_signature_kwargs(self) -> List[str]:
270
260
  """Signature for kwargs"""
271
- return ["**kwargs: Any"] if is_python3_file else ["**kwargs # type: Any"]
261
+ return ["**kwargs: Any"]
272
262
 
273
- def kwargs_to_pop(
274
- self, is_python3_file: bool
275
- ) -> List[Union[ParameterType, BodyParameterType]]:
263
+ @property
264
+ def kwargs_to_pop(self) -> List[Union[ParameterType, BodyParameterType]]:
276
265
  """Method kwargs we want to pop"""
277
266
  # don't want to pop bodies unless it's a constant
278
267
  kwargs_to_pop = self.kwarg
279
- if not is_python3_file:
280
- kwargs_to_pop += self.keyword_only
281
268
  return [
282
269
  k
283
270
  for k in kwargs_to_pop
@@ -416,10 +403,15 @@ class RequestBuilderParameterList(_RequestBuilderParameterList):
416
403
  class OverloadedRequestBuilderParameterList(_RequestBuilderParameterList):
417
404
  """Parameter list for OverloadedRequestBuilder"""
418
405
 
419
- def method_signature(self, is_python3_file: bool, async_mode: bool) -> List[str]:
420
- return self.method_signature_positional(
421
- is_python3_file, async_mode
422
- ) + self.method_signature_kwargs(is_python3_file)
406
+ def method_signature_keyword_only(self, async_mode: bool) -> List[str]:
407
+ """Signature for keyword only parameters"""
408
+ if not self.keyword_only:
409
+ return []
410
+ return ["*,"] + [
411
+ parameter.method_signature(async_mode)
412
+ for parameter in self.keyword_only
413
+ if parameter.location != ParameterLocation.BODY
414
+ ]
423
415
 
424
416
 
425
417
  class _ClientGlobalParameterList(
@@ -471,13 +463,12 @@ class ClientGlobalParameterList(_ClientGlobalParameterList[ClientParameter]):
471
463
  except StopIteration:
472
464
  return None
473
465
 
474
- def kwargs_to_pop(
475
- self, is_python3_file: bool
476
- ) -> List[Union[ClientParameter, BodyParameter]]:
466
+ @property
467
+ def kwargs_to_pop(self) -> List[Union[ClientParameter, BodyParameter]]:
477
468
  """We only want to pass base url path parameters in the client"""
478
469
  return [
479
470
  k
480
- for k in super().kwargs_to_pop(is_python3_file=is_python3_file)
471
+ for k in super().kwargs_to_pop
481
472
  if k.location == ParameterLocation.ENDPOINT_PATH
482
473
  ]
483
474
 
@@ -13,6 +13,7 @@ from .utils import add_to_description, add_to_pylint_disable
13
13
 
14
14
  if TYPE_CHECKING:
15
15
  from .code_model import CodeModel
16
+ from .model_type import ModelType
16
17
 
17
18
 
18
19
  class Property(BaseModel): # pylint: disable=too-many-instance-attributes
@@ -105,6 +106,19 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
105
106
  description=description,
106
107
  )
107
108
 
109
+ def get_polymorphic_subtypes(self, polymorphic_subtypes: List["ModelType"]) -> None:
110
+ from .model_type import ModelType
111
+
112
+ if isinstance(self.type, ModelType):
113
+ is_polymorphic_subtype = (
114
+ self.type.discriminator_value and not self.type.discriminated_subtypes
115
+ )
116
+ if (
117
+ self.type.name not in (m.name for m in polymorphic_subtypes)
118
+ and is_polymorphic_subtype
119
+ ):
120
+ polymorphic_subtypes.append(self.type)
121
+
108
122
  @property
109
123
  def validation(self) -> Optional[Dict[str, Any]]:
110
124
  retval: Dict[str, Any] = {}