@autorest/python 6.27.4 → 6.28.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 (120) hide show
  1. package/generator/build/lib/pygen/black.py +3 -3
  2. package/generator/build/lib/pygen/codegen/__init__.py +2 -0
  3. package/generator/build/lib/pygen/codegen/_utils.py +4 -0
  4. package/generator/build/lib/pygen/codegen/models/base.py +2 -3
  5. package/generator/build/lib/pygen/codegen/models/base_builder.py +5 -3
  6. package/generator/build/lib/pygen/codegen/models/client.py +28 -19
  7. package/generator/build/lib/pygen/codegen/models/code_model.py +204 -33
  8. package/generator/build/lib/pygen/codegen/models/combined_type.py +12 -8
  9. package/generator/build/lib/pygen/codegen/models/constant_type.py +2 -3
  10. package/generator/build/lib/pygen/codegen/models/credential_types.py +6 -3
  11. package/generator/build/lib/pygen/codegen/models/dictionary_type.py +2 -3
  12. package/generator/build/lib/pygen/codegen/models/enum_type.py +47 -24
  13. package/generator/build/lib/pygen/codegen/models/imports.py +14 -12
  14. package/generator/build/lib/pygen/codegen/models/list_type.py +2 -3
  15. package/generator/build/lib/pygen/codegen/models/lro_operation.py +8 -4
  16. package/generator/build/lib/pygen/codegen/models/lro_paging_operation.py +2 -2
  17. package/generator/build/lib/pygen/codegen/models/model_type.py +34 -19
  18. package/generator/build/lib/pygen/codegen/models/operation.py +74 -31
  19. package/generator/build/lib/pygen/codegen/models/operation_group.py +82 -12
  20. package/generator/build/lib/pygen/codegen/models/paging_operation.py +10 -7
  21. package/generator/build/lib/pygen/codegen/models/parameter.py +10 -10
  22. package/generator/build/lib/pygen/codegen/models/parameter_list.py +7 -7
  23. package/generator/build/lib/pygen/codegen/models/primitive_types.py +23 -43
  24. package/generator/build/lib/pygen/codegen/models/property.py +9 -9
  25. package/generator/build/lib/pygen/codegen/models/request_builder.py +9 -15
  26. package/generator/build/lib/pygen/codegen/models/response.py +6 -8
  27. package/generator/build/lib/pygen/codegen/models/utils.py +11 -0
  28. package/generator/build/lib/pygen/codegen/serializers/__init__.py +228 -243
  29. package/generator/build/lib/pygen/codegen/serializers/base_serializer.py +19 -1
  30. package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +58 -36
  31. package/generator/build/lib/pygen/codegen/serializers/client_serializer.py +9 -5
  32. package/generator/build/lib/pygen/codegen/serializers/enum_serializer.py +17 -3
  33. package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +26 -14
  34. package/generator/build/lib/pygen/codegen/serializers/metadata_serializer.py +26 -8
  35. package/generator/build/lib/pygen/codegen/serializers/model_init_serializer.py +9 -4
  36. package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +65 -24
  37. package/generator/build/lib/pygen/codegen/serializers/operation_groups_serializer.py +20 -16
  38. package/generator/build/lib/pygen/codegen/serializers/operations_init_serializer.py +5 -10
  39. package/generator/build/lib/pygen/codegen/serializers/parameter_serializer.py +10 -7
  40. package/generator/build/lib/pygen/codegen/serializers/request_builders_serializer.py +10 -1
  41. package/generator/build/lib/pygen/codegen/serializers/sample_serializer.py +7 -10
  42. package/generator/build/lib/pygen/codegen/serializers/test_serializer.py +24 -28
  43. package/generator/build/lib/pygen/codegen/serializers/types_serializer.py +6 -1
  44. package/generator/build/lib/pygen/codegen/serializers/utils.py +1 -15
  45. package/generator/build/lib/pygen/codegen/templates/client_container.py.jinja2 +1 -1
  46. package/generator/build/lib/pygen/codegen/templates/config_container.py.jinja2 +1 -1
  47. package/generator/build/lib/pygen/codegen/templates/enum_container.py.jinja2 +1 -1
  48. package/generator/build/lib/pygen/codegen/templates/init.py.jinja2 +1 -1
  49. package/generator/build/lib/pygen/codegen/templates/model_container.py.jinja2 +1 -1
  50. package/generator/build/lib/pygen/codegen/templates/operation_group.py.jinja2 +4 -4
  51. package/generator/build/lib/pygen/codegen/templates/operation_groups_container.py.jinja2 +2 -0
  52. package/generator/build/lib/pygen/codegen/templates/operations_folder_init.py.jinja2 +2 -4
  53. package/generator/build/lib/pygen/codegen/templates/serialization.py.jinja2 +2 -68
  54. package/generator/build/lib/pygen/codegen/templates/test.py.jinja2 +3 -3
  55. package/generator/build/lib/pygen/codegen/templates/testpreparer.py.jinja2 +2 -2
  56. package/generator/build/lib/pygen/codegen/templates/vendor.py.jinja2 +4 -4
  57. package/generator/build/lib/pygen/preprocess/__init__.py +0 -4
  58. package/generator/component-detection-pip-report.json +2 -2
  59. package/generator/dev_requirements.txt +2 -2
  60. package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
  61. package/generator/pygen/black.py +3 -3
  62. package/generator/pygen/codegen/__init__.py +2 -0
  63. package/generator/pygen/codegen/_utils.py +4 -0
  64. package/generator/pygen/codegen/models/base.py +2 -3
  65. package/generator/pygen/codegen/models/base_builder.py +5 -3
  66. package/generator/pygen/codegen/models/client.py +28 -19
  67. package/generator/pygen/codegen/models/code_model.py +204 -33
  68. package/generator/pygen/codegen/models/combined_type.py +12 -8
  69. package/generator/pygen/codegen/models/constant_type.py +2 -3
  70. package/generator/pygen/codegen/models/credential_types.py +6 -3
  71. package/generator/pygen/codegen/models/dictionary_type.py +2 -3
  72. package/generator/pygen/codegen/models/enum_type.py +47 -24
  73. package/generator/pygen/codegen/models/imports.py +14 -12
  74. package/generator/pygen/codegen/models/list_type.py +2 -3
  75. package/generator/pygen/codegen/models/lro_operation.py +8 -4
  76. package/generator/pygen/codegen/models/lro_paging_operation.py +2 -2
  77. package/generator/pygen/codegen/models/model_type.py +34 -19
  78. package/generator/pygen/codegen/models/operation.py +74 -31
  79. package/generator/pygen/codegen/models/operation_group.py +82 -12
  80. package/generator/pygen/codegen/models/paging_operation.py +10 -7
  81. package/generator/pygen/codegen/models/parameter.py +10 -10
  82. package/generator/pygen/codegen/models/parameter_list.py +7 -7
  83. package/generator/pygen/codegen/models/primitive_types.py +23 -43
  84. package/generator/pygen/codegen/models/property.py +9 -9
  85. package/generator/pygen/codegen/models/request_builder.py +9 -15
  86. package/generator/pygen/codegen/models/response.py +6 -8
  87. package/generator/pygen/codegen/models/utils.py +11 -0
  88. package/generator/pygen/codegen/serializers/__init__.py +228 -243
  89. package/generator/pygen/codegen/serializers/base_serializer.py +19 -1
  90. package/generator/pygen/codegen/serializers/builder_serializer.py +58 -36
  91. package/generator/pygen/codegen/serializers/client_serializer.py +9 -5
  92. package/generator/pygen/codegen/serializers/enum_serializer.py +17 -3
  93. package/generator/pygen/codegen/serializers/general_serializer.py +26 -14
  94. package/generator/pygen/codegen/serializers/metadata_serializer.py +26 -8
  95. package/generator/pygen/codegen/serializers/model_init_serializer.py +9 -4
  96. package/generator/pygen/codegen/serializers/model_serializer.py +65 -24
  97. package/generator/pygen/codegen/serializers/operation_groups_serializer.py +20 -16
  98. package/generator/pygen/codegen/serializers/operations_init_serializer.py +5 -10
  99. package/generator/pygen/codegen/serializers/parameter_serializer.py +10 -7
  100. package/generator/pygen/codegen/serializers/request_builders_serializer.py +10 -1
  101. package/generator/pygen/codegen/serializers/sample_serializer.py +7 -10
  102. package/generator/pygen/codegen/serializers/test_serializer.py +24 -28
  103. package/generator/pygen/codegen/serializers/types_serializer.py +6 -1
  104. package/generator/pygen/codegen/serializers/utils.py +1 -15
  105. package/generator/pygen/codegen/templates/client_container.py.jinja2 +1 -1
  106. package/generator/pygen/codegen/templates/config_container.py.jinja2 +1 -1
  107. package/generator/pygen/codegen/templates/enum_container.py.jinja2 +1 -1
  108. package/generator/pygen/codegen/templates/init.py.jinja2 +1 -1
  109. package/generator/pygen/codegen/templates/model_container.py.jinja2 +1 -1
  110. package/generator/pygen/codegen/templates/operation_group.py.jinja2 +4 -4
  111. package/generator/pygen/codegen/templates/operation_groups_container.py.jinja2 +2 -0
  112. package/generator/pygen/codegen/templates/operations_folder_init.py.jinja2 +2 -4
  113. package/generator/pygen/codegen/templates/serialization.py.jinja2 +2 -68
  114. package/generator/pygen/codegen/templates/test.py.jinja2 +3 -3
  115. package/generator/pygen/codegen/templates/testpreparer.py.jinja2 +2 -2
  116. package/generator/pygen/codegen/templates/vendor.py.jinja2 +4 -4
  117. package/generator/pygen/preprocess/__init__.py +0 -4
  118. package/generator/pygen.egg-info/PKG-INFO +10 -1
  119. package/package.json +2 -2
  120. package/scripts/__pycache__/venvtools.cpython-310.pyc +0 -0
@@ -20,8 +20,8 @@ class LROPagingOperation(LROOperationBase[LROPagingResponse], PagingOperationBas
20
20
  def operation_type(self) -> str:
21
21
  return "lropaging"
22
22
 
23
- def cls_type_annotation(self, *, async_mode: bool) -> str:
24
- return f"ClsType[{Response.type_annotation(self.responses[0], async_mode=async_mode)}]"
23
+ def cls_type_annotation(self, *, async_mode: bool, **kwargs: Any) -> str:
24
+ return f"ClsType[{Response.type_annotation(self.responses[0], async_mode=async_mode, **kwargs)}]"
25
25
 
26
26
  def imports(self, async_mode: bool, **kwargs: Any) -> FileImport:
27
27
  lro_imports = LROOperationBase.imports(self, async_mode, **kwargs)
@@ -7,7 +7,7 @@ from enum import Enum
7
7
  from collections import OrderedDict
8
8
  from typing import Any, Dict, List, Optional, TYPE_CHECKING, cast
9
9
  import sys
10
- from .utils import add_to_pylint_disable
10
+ from .utils import add_to_pylint_disable, NamespaceType
11
11
  from .base import BaseType
12
12
  from .constant_type import ConstantType
13
13
  from .property import Property
@@ -82,6 +82,7 @@ class ModelType(BaseType): # pylint: disable=too-many-instance-attributes, too-
82
82
  self.snake_case_name: str = self.yaml_data["snakeCaseName"]
83
83
  self.cross_language_definition_id: Optional[str] = self.yaml_data.get("crossLanguageDefinitionId")
84
84
  self.usage: int = self.yaml_data.get("usage", UsageFlags.Input.value | UsageFlags.Output.value)
85
+ self.client_namespace: str = self.yaml_data.get("clientNamespace", code_model.namespace)
85
86
 
86
87
  @property
87
88
  def is_usage_output(self) -> bool:
@@ -254,8 +255,7 @@ class JSONModelType(ModelType):
254
255
  def type_annotation(self, **kwargs: Any) -> str:
255
256
  return "ET.Element" if self.is_xml else "JSON"
256
257
 
257
- @property
258
- def serialization_type(self) -> str:
258
+ def serialization_type(self, **kwargs: Any) -> str:
259
259
  return "object"
260
260
 
261
261
  def docstring_type(self, **kwargs: Any) -> str:
@@ -281,13 +281,18 @@ class GeneratedModelType(ModelType):
281
281
  def type_annotation(self, **kwargs: Any) -> str:
282
282
  is_operation_file = kwargs.pop("is_operation_file", False)
283
283
  skip_quote = kwargs.get("skip_quote", False)
284
- module_name = "_models." if kwargs.get("need_module_name", True) else ""
284
+ module_name = ""
285
+ if kwargs.get("need_model_alias", True):
286
+ serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
287
+ model_alias = self.code_model.get_unique_models_alias(serialize_namespace, self.client_namespace)
288
+ module_name = f"{model_alias}."
285
289
  file_name = f"{self.code_model.models_filename}." if self.internal else ""
286
290
  retval = module_name + file_name + self.name
287
291
  return retval if is_operation_file or skip_quote else f'"{retval}"'
288
292
 
289
293
  def docstring_type(self, **kwargs: Any) -> str:
290
- return f"~{self.code_model.namespace}.models.{self.type_annotation(need_module_name=False, skip_quote=True)}"
294
+ type_annotation = self.type_annotation(need_model_alias=False, skip_quote=True, **kwargs)
295
+ return f"~{self.code_model.namespace}.models.{type_annotation}"
291
296
 
292
297
  def docstring_text(self, **kwargs: Any) -> str:
293
298
  return self.name
@@ -298,32 +303,43 @@ class GeneratedModelType(ModelType):
298
303
 
299
304
  def imports(self, **kwargs: Any) -> FileImport:
300
305
  file_import = super().imports(**kwargs)
301
- relative_path = kwargs.pop("relative_path", None)
302
- if relative_path:
303
- # add import for models in operations or _types file
306
+ serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
307
+ relative_path = self.code_model.get_relative_import_path(serialize_namespace, self.client_namespace)
308
+ alias = self.code_model.get_unique_models_alias(serialize_namespace, self.client_namespace)
309
+ serialize_namespace_type = kwargs.get("serialize_namespace_type")
310
+ called_by_property = kwargs.get("called_by_property", False)
311
+ # add import for models in operations or _types file
312
+ if serialize_namespace_type in [NamespaceType.OPERATION, NamespaceType.CLIENT]:
304
313
  file_import.add_submodule_import(
305
314
  relative_path,
306
315
  "models",
307
316
  ImportType.LOCAL,
308
- alias="_models",
309
- typing_section=(TypingSection.TYPING if kwargs.get("model_typing") else TypingSection.REGULAR),
317
+ alias=alias,
310
318
  )
311
319
  if self.is_form_data:
312
320
  file_import.add_submodule_import(
313
- relative_path,
321
+ self.code_model.get_relative_import_path(serialize_namespace),
314
322
  "_model_base",
315
323
  ImportType.LOCAL,
316
- typing_section=(TypingSection.TYPING if kwargs.get("model_typing") else TypingSection.REGULAR),
317
324
  )
325
+ elif serialize_namespace_type == NamespaceType.TYPES_FILE or (
326
+ serialize_namespace_type == NamespaceType.MODEL and called_by_property
327
+ ):
328
+ file_import.add_submodule_import(
329
+ relative_path,
330
+ "models",
331
+ ImportType.LOCAL,
332
+ alias=alias,
333
+ typing_section=TypingSection.TYPING,
334
+ )
318
335
  return file_import
319
336
 
320
337
 
321
338
  class MsrestModelType(GeneratedModelType):
322
339
  base = "msrest"
323
340
 
324
- @property
325
- def serialization_type(self) -> str:
326
- return self.type_annotation(skip_quote=True) if self.internal else self.name
341
+ def serialization_type(self, **kwargs: Any) -> str:
342
+ return self.type_annotation(skip_quote=True, **kwargs) if self.internal else self.name
327
343
 
328
344
  @property
329
345
  def instance_check_template(self) -> str:
@@ -338,12 +354,11 @@ class MsrestModelType(GeneratedModelType):
338
354
  class DPGModelType(GeneratedModelType):
339
355
  base = "dpg"
340
356
 
341
- @property
342
- def serialization_type(self) -> str:
357
+ def serialization_type(self, **kwargs: Any) -> str:
343
358
  return (
344
- self.type_annotation(skip_quote=True)
359
+ self.type_annotation(skip_quote=True, **kwargs)
345
360
  if self.internal
346
- else self.type_annotation(need_module_name=False, skip_quote=True)
361
+ else self.type_annotation(need_model_alias=False, skip_quote=True, **kwargs)
347
362
  )
348
363
 
349
364
  @property
@@ -13,6 +13,7 @@ from typing import (
13
13
  Generic,
14
14
  TypeVar,
15
15
  cast,
16
+ Sequence,
16
17
  )
17
18
 
18
19
  from .request_builder_parameter import RequestBuilderParameter
@@ -34,7 +35,9 @@ from .parameter import (
34
35
  )
35
36
  from .parameter_list import ParameterList
36
37
  from .model_type import ModelType
38
+ from .primitive_types import BinaryIteratorType, BinaryType
37
39
  from .base import BaseType
40
+ from .combined_type import CombinedType
38
41
  from .request_builder import OverloadedRequestBuilder, RequestBuilder
39
42
  from ...utils import xml_serializable, json_serializable, NAME_LENGTH_LIMIT
40
43
 
@@ -54,7 +57,7 @@ def is_internal(target: Optional[BaseType]) -> bool:
54
57
 
55
58
 
56
59
  class OperationBase( # pylint: disable=too-many-public-methods,too-many-instance-attributes
57
- Generic[ResponseType], BaseBuilder[ParameterList, List["Operation"]]
60
+ Generic[ResponseType], BaseBuilder[ParameterList, Sequence["Operation"]]
58
61
  ):
59
62
  def __init__(
60
63
  self,
@@ -67,7 +70,7 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
67
70
  responses: List[ResponseType],
68
71
  exceptions: List[Response],
69
72
  *,
70
- overloads: Optional[List["Operation"]] = None,
73
+ overloads: Optional[Sequence["Operation"]] = None,
71
74
  ) -> None:
72
75
  super().__init__(
73
76
  code_model=code_model,
@@ -77,7 +80,7 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
77
80
  parameters=parameters,
78
81
  overloads=overloads,
79
82
  )
80
- self.overloads: List["Operation"] = overloads or []
83
+ self.overloads: Sequence["Operation"] = overloads or []
81
84
  self.responses = responses
82
85
  self.request_builder = request_builder
83
86
  self.deprecated = False
@@ -144,10 +147,10 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
144
147
  retval = add_to_pylint_disable(retval, "name-too-long")
145
148
  return retval
146
149
 
147
- def cls_type_annotation(self, *, async_mode: bool) -> str:
150
+ def cls_type_annotation(self, *, async_mode: bool, **kwargs: Any) -> str:
148
151
  if self.request_builder.method.lower() == "head" and self.code_model.options["head_as_boolean"]:
149
152
  return "ClsType[None]"
150
- return f"ClsType[{self.response_type_annotation(async_mode=async_mode)}]"
153
+ return f"ClsType[{self.response_type_annotation(async_mode=async_mode, **kwargs)}]"
151
154
 
152
155
  def _response_docstring_helper(self, attr_name: str, **kwargs: Any) -> str:
153
156
  responses_with_body = [r for r in self.responses if r.type]
@@ -207,21 +210,26 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
207
210
  e for e in self.exceptions if "default" not in e.status_codes and e.type and isinstance(e.type, ModelType)
208
211
  ]
209
212
 
210
- def _imports_shared(self, async_mode: bool, **kwargs: Any) -> FileImport: # pylint: disable=unused-argument
213
+ def _imports_shared(self, async_mode: bool, **kwargs: Any) -> FileImport:
211
214
  file_import = FileImport(self.code_model)
212
215
  file_import.add_submodule_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
213
216
 
214
- response_types = [r.type_annotation(async_mode=async_mode, operation=self) for r in self.responses if r.type]
217
+ response_types = [r.type_annotation(async_mode=async_mode, **kwargs) for r in self.responses if r.type]
215
218
  if len(set(response_types)) > 1:
216
219
  file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
217
220
  if self.added_on:
221
+ serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
218
222
  file_import.add_submodule_import(
219
- f"{'.' if async_mode else ''}.._validation",
223
+ self.code_model.get_relative_import_path(serialize_namespace, module_name="_validation"),
220
224
  "api_version_validation",
221
225
  ImportType.LOCAL,
222
226
  )
223
227
  return file_import
224
228
 
229
+ @property
230
+ def need_import_iobase(self) -> bool:
231
+ return self.parameters.has_body and isinstance(self.parameters.body_parameter.type, CombinedType)
232
+
225
233
  def imports_for_multiapi(self, async_mode: bool, **kwargs: Any) -> FileImport:
226
234
  if self.abstract:
227
235
  return FileImport(self.code_model)
@@ -230,15 +238,23 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
230
238
  file_import.merge(
231
239
  param.imports_for_multiapi(
232
240
  async_mode,
233
- operation=self,
241
+ need_import_iobase=self.need_import_iobase,
234
242
  **kwargs,
235
243
  )
236
244
  )
237
245
  for response in self.responses:
238
- file_import.merge(response.imports_for_multiapi(async_mode=async_mode, operation=self, **kwargs))
246
+ file_import.merge(
247
+ response.imports_for_multiapi(
248
+ async_mode=async_mode, need_import_iobase=self.need_import_iobase, **kwargs
249
+ )
250
+ )
239
251
  if self.code_model.options["models_mode"]:
240
252
  for exception in self.exceptions:
241
- file_import.merge(exception.imports_for_multiapi(async_mode=async_mode, operation=self, **kwargs))
253
+ file_import.merge(
254
+ exception.imports_for_multiapi(
255
+ async_mode=async_mode, need_import_iobase=self.need_import_iobase, **kwargs
256
+ )
257
+ )
242
258
  return file_import
243
259
 
244
260
  @staticmethod
@@ -265,6 +281,7 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
265
281
  self,
266
282
  request_builder: Union[RequestBuilder, OverloadedRequestBuilder],
267
283
  async_mode: bool,
284
+ serialize_namespace: str,
268
285
  ) -> FileImport:
269
286
  """Helper method to get a request builder import."""
270
287
  file_import = FileImport(self.code_model)
@@ -287,35 +304,49 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
287
304
  )
288
305
  if self.code_model.options["builders_visibility"] == "embedded" and async_mode:
289
306
  file_import.add_submodule_import(
290
- f"...{self.code_model.operations_folder_name}.{self.filename}",
307
+ self.code_model.get_relative_import_path(
308
+ serialize_namespace,
309
+ self.code_model.get_imported_namespace_for_operation(self.client_namespace),
310
+ module_name=self.filename,
311
+ ),
291
312
  request_builder.name,
292
313
  import_type=ImportType.LOCAL,
293
314
  )
294
315
  return file_import
295
316
 
317
+ @property
318
+ def need_deserialize(self) -> bool:
319
+ return any(r.type and not isinstance(r.type, BinaryIteratorType) for r in self.responses)
320
+
296
321
  def imports( # pylint: disable=too-many-branches, disable=too-many-statements
297
322
  self, async_mode: bool, **kwargs: Any
298
323
  ) -> FileImport:
299
324
  if self.abstract:
300
325
  return FileImport(self.code_model)
326
+
327
+ serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
301
328
  file_import = self._imports_shared(async_mode, **kwargs)
302
329
 
303
330
  for param in self.parameters.method:
304
331
  file_import.merge(
305
332
  param.imports(
306
333
  async_mode,
307
- operation=self,
334
+ need_import_iobase=self.need_import_iobase,
308
335
  **kwargs,
309
336
  )
310
337
  )
311
338
  for response in self.responses:
312
- file_import.merge(response.imports(async_mode=async_mode, operation=self, **kwargs))
339
+ file_import.merge(
340
+ response.imports(async_mode=async_mode, need_import_iobase=self.need_import_iobase, **kwargs)
341
+ )
313
342
  if self.code_model.options["models_mode"]:
314
343
  for exception in self.exceptions:
315
344
  file_import.merge(exception.imports(async_mode=async_mode, **kwargs))
316
345
 
317
346
  if self.parameters.has_body and self.parameters.body_parameter.flattened:
318
- file_import.merge(self.parameters.body_parameter.type.imports(operation=self, **kwargs))
347
+ file_import.merge(
348
+ self.parameters.body_parameter.type.imports(need_import_iobase=self.need_import_iobase, **kwargs)
349
+ )
319
350
  if not async_mode:
320
351
  for param in self.parameters.headers:
321
352
  if param.wire_name.lower() == "repeatability-request-id":
@@ -353,7 +384,6 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
353
384
  if self.deprecated:
354
385
  file_import.add_import("warnings", ImportType.STDLIB)
355
386
 
356
- relative_path = "..." if async_mode else ".."
357
387
  if self.has_etag:
358
388
  file_import.add_submodule_import(
359
389
  "exceptions",
@@ -361,8 +391,17 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
361
391
  ImportType.SDKCORE,
362
392
  )
363
393
  if not async_mode:
364
- file_import.add_submodule_import(f"{relative_path}_vendor", "prep_if_match", ImportType.LOCAL)
365
- file_import.add_submodule_import(f"{relative_path}_vendor", "prep_if_none_match", ImportType.LOCAL)
394
+ relative_path = self.code_model.get_relative_import_path(serialize_namespace, module_name="_vendor")
395
+ file_import.add_submodule_import(
396
+ relative_path,
397
+ "prep_if_match",
398
+ ImportType.LOCAL,
399
+ )
400
+ file_import.add_submodule_import(
401
+ relative_path,
402
+ "prep_if_none_match",
403
+ ImportType.LOCAL,
404
+ )
366
405
  if async_mode:
367
406
  file_import.add_submodule_import(
368
407
  "rest",
@@ -376,7 +415,7 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
376
415
  ImportType.SDKCORE,
377
416
  )
378
417
  if self.code_model.options["builders_visibility"] == "embedded" and not async_mode:
379
- file_import.merge(self.request_builder.imports())
418
+ file_import.merge(self.request_builder.imports(**kwargs))
380
419
  file_import.add_submodule_import(
381
420
  f"{'' if self.code_model.is_azure_flavor else 'runtime.'}pipeline",
382
421
  "PipelineResponse",
@@ -393,34 +432,36 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
393
432
  "distributed_trace",
394
433
  ImportType.SDKCORE,
395
434
  )
396
- file_import.merge(self.get_request_builder_import(self.request_builder, async_mode))
435
+ file_import.merge(self.get_request_builder_import(self.request_builder, async_mode, serialize_namespace))
397
436
  if self.overloads:
398
437
  file_import.add_submodule_import("typing", "overload", ImportType.STDLIB)
399
438
  if self.code_model.options["models_mode"] == "dpg":
400
- if self.parameters.has_body:
439
+ relative_path = self.code_model.get_relative_import_path(serialize_namespace, module_name="_model_base")
440
+ body_param = self.parameters.body_parameter if self.parameters.has_body else None
441
+ if body_param and not isinstance(body_param.type, BinaryType):
401
442
  if self.has_form_data_body:
402
- file_import.add_submodule_import(relative_path, "_model_base", ImportType.LOCAL)
443
+ file_import.add_submodule_import(
444
+ self.code_model.get_relative_import_path(serialize_namespace), "_model_base", ImportType.LOCAL
445
+ )
403
446
  elif xml_serializable(self.parameters.body_parameter.default_content_type):
404
447
  file_import.add_submodule_import(
405
- f"{relative_path}_model_base",
448
+ relative_path,
406
449
  "_get_element",
407
450
  ImportType.LOCAL,
408
451
  )
409
452
  elif json_serializable(self.parameters.body_parameter.default_content_type):
410
453
  file_import.add_submodule_import(
411
- f"{relative_path}_model_base",
454
+ relative_path,
412
455
  "SdkJSONEncoder",
413
456
  ImportType.LOCAL,
414
457
  )
415
458
  file_import.add_import("json", ImportType.STDLIB)
416
459
  if any(xml_serializable(str(r.default_content_type)) for r in self.responses):
417
- file_import.add_submodule_import(f"{relative_path}_model_base", "_deserialize_xml", ImportType.LOCAL)
418
- elif any(r.type for r in self.responses):
419
- file_import.add_submodule_import(f"{relative_path}_model_base", "_deserialize", ImportType.LOCAL)
460
+ file_import.add_submodule_import(relative_path, "_deserialize_xml", ImportType.LOCAL)
461
+ elif self.need_deserialize:
462
+ file_import.add_submodule_import(relative_path, "_deserialize", ImportType.LOCAL)
420
463
  if self.default_error_deserialization or self.non_default_errors:
421
- file_import.add_submodule_import(
422
- f"{relative_path}_model_base", "_failsafe_deserialize", ImportType.LOCAL
423
- )
464
+ file_import.add_submodule_import(relative_path, "_failsafe_deserialize", ImportType.LOCAL)
424
465
  return file_import
425
466
 
426
467
  def get_response_from_status(self, status_code: Optional[Union[str, int]]) -> ResponseType:
@@ -465,7 +506,9 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
465
506
  responses = [cast(ResponseType, get_response(r, code_model)) for r in yaml_data["responses"]]
466
507
  exceptions = [Response.from_yaml(e, code_model) for e in yaml_data["exceptions"]]
467
508
  parameter_list = ParameterList.from_yaml(yaml_data, code_model)
468
- overloads = [cls.from_yaml(overload, code_model, client) for overload in yaml_data.get("overloads", [])]
509
+ overloads = [
510
+ cast(Operation, cls.from_yaml(overload, code_model, client)) for overload in yaml_data.get("overloads", [])
511
+ ]
469
512
 
470
513
  return cls(
471
514
  yaml_data=yaml_data,
@@ -9,8 +9,8 @@ from .utils import OrderedSet
9
9
 
10
10
  from .base import BaseModel
11
11
  from .operation import get_operation
12
- from .imports import FileImport, ImportType, TypingSection
13
- from .utils import add_to_pylint_disable
12
+ from .imports import FileImport, ImportType, TypingSection, MsrestImportType
13
+ from .utils import add_to_pylint_disable, NamespaceType
14
14
  from .lro_operation import LROOperation
15
15
  from .lro_paging_operation import LROPagingOperation
16
16
  from ...utils import NAME_LENGTH_LIMIT
@@ -46,6 +46,10 @@ class OperationGroup(BaseModel):
46
46
  for op_group in self.yaml_data.get("operationGroups", [])
47
47
  ]
48
48
  self.link_lro_initial_operations()
49
+ self.client_namespace: str = self.yaml_data.get("clientNamespace", code_model.namespace)
50
+ self.has_parent_operation_group: bool = False
51
+ for og in self.operation_groups:
52
+ og.has_parent_operation_group = True
49
53
 
50
54
  @property
51
55
  def has_abstract_operations(self) -> bool:
@@ -66,11 +70,11 @@ class OperationGroup(BaseModel):
66
70
  base_classes.append(f"{self.client.name}MixinABC")
67
71
  return ", ".join(base_classes)
68
72
 
69
- def imports_for_multiapi(self, async_mode: bool) -> FileImport:
73
+ def imports_for_multiapi(self, async_mode: bool, **kwargs) -> FileImport:
70
74
  file_import = FileImport(self.code_model)
71
75
  relative_path = ".." if async_mode else "."
72
76
  for operation in self.operations:
73
- file_import.merge(operation.imports_for_multiapi(async_mode, relative_path=relative_path))
77
+ file_import.merge(operation.imports_for_multiapi(async_mode, **kwargs))
74
78
  if (self.code_model.model_types or self.code_model.enums) and self.code_model.options[
75
79
  "models_mode"
76
80
  ] == "msrest":
@@ -94,30 +98,96 @@ class OperationGroup(BaseModel):
94
98
  """Whether any of its operations need validation"""
95
99
  return any(o for o in self.operations if o.need_validation)
96
100
 
97
- def imports(self, async_mode: bool) -> FileImport:
101
+ def imports(self, async_mode: bool, **kwargs: Any) -> FileImport:
98
102
  file_import = FileImport(self.code_model)
99
103
 
100
- relative_path = ("..." if async_mode else "..") + ("." if self.client.is_subclient else "")
104
+ serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
101
105
  for operation in self.operations:
102
- file_import.merge(operation.imports(async_mode, relative_path=relative_path))
106
+ file_import.merge(operation.imports(async_mode, **kwargs))
103
107
  if not self.code_model.options["combine_operation_files"]:
104
108
  for og in self.operation_groups:
105
109
  file_import.add_submodule_import(
106
- ".",
110
+ self.code_model.get_relative_import_path(
111
+ serialize_namespace,
112
+ self.code_model.get_imported_namespace_for_operation(self.client_namespace, async_mode),
113
+ ),
107
114
  og.class_name,
108
115
  ImportType.LOCAL,
109
116
  )
117
+ else:
118
+ for og in self.operation_groups:
119
+ namespace = self.code_model.get_serialize_namespace(
120
+ og.client_namespace, async_mode, NamespaceType.OPERATION
121
+ )
122
+ if namespace != serialize_namespace:
123
+ file_import.add_submodule_import(
124
+ self.code_model.get_relative_import_path(
125
+ serialize_namespace,
126
+ self.code_model.get_imported_namespace_for_operation(og.client_namespace, async_mode),
127
+ )
128
+ + f".{og.filename}",
129
+ og.class_name,
130
+ ImportType.LOCAL,
131
+ )
110
132
  # for multiapi
111
133
  if (
112
134
  (self.code_model.public_model_types)
113
135
  and self.code_model.options["models_mode"] == "msrest"
114
136
  and not self.is_mixin
115
137
  ):
116
- file_import.add_submodule_import(relative_path, "models", ImportType.LOCAL, alias="_models")
138
+ file_import.add_submodule_import(
139
+ self.code_model.get_relative_import_path(serialize_namespace),
140
+ "models",
141
+ ImportType.LOCAL,
142
+ alias="_models",
143
+ )
117
144
  if self.is_mixin:
118
- file_import.add_submodule_import(".._vendor", f"{self.client.name}MixinABC", ImportType.LOCAL)
145
+ file_import.add_submodule_import(
146
+ # XxxMixinABC is always defined in _vendor of client namespace
147
+ self.code_model.get_relative_import_path(
148
+ serialize_namespace,
149
+ self.code_model.get_imported_namespace_for_client(self.client.client_namespace, async_mode),
150
+ module_name="_vendor",
151
+ ),
152
+ f"{self.client.name}MixinABC",
153
+ ImportType.LOCAL,
154
+ )
155
+ else:
156
+ file_import.add_submodule_import(
157
+ "" if self.code_model.is_azure_flavor else "runtime",
158
+ f"{'Async' if async_mode else ''}PipelineClient",
159
+ ImportType.SDKCORE,
160
+ )
161
+ file_import.add_submodule_import(
162
+ self.code_model.get_relative_import_path(
163
+ serialize_namespace,
164
+ self.code_model.get_imported_namespace_for_client(self.client.client_namespace, async_mode),
165
+ module_name="_configuration",
166
+ ),
167
+ f"{self.client.name}Configuration",
168
+ ImportType.LOCAL,
169
+ )
170
+ file_import.add_msrest_import(
171
+ serialize_namespace=kwargs.get("serialize_namespace", self.code_model.namespace),
172
+ msrest_import_type=MsrestImportType.Serializer,
173
+ typing_section=TypingSection.REGULAR,
174
+ )
175
+ file_import.add_msrest_import(
176
+ serialize_namespace=kwargs.get("serialize_namespace", self.code_model.namespace),
177
+ msrest_import_type=MsrestImportType.SerializerDeserializer,
178
+ typing_section=TypingSection.REGULAR,
179
+ )
119
180
  if self.has_abstract_operations:
120
- file_import.add_submodule_import(".._vendor", "raise_if_not_implemented", ImportType.LOCAL)
181
+ file_import.add_submodule_import(
182
+ # raise_if_not_implemented is always defined in _vendor of top namespace
183
+ self.code_model.get_relative_import_path(
184
+ serialize_namespace,
185
+ self.code_model.get_imported_namespace_for_client(self.code_model.namespace, async_mode),
186
+ module_name="_vendor",
187
+ ),
188
+ "raise_if_not_implemented",
189
+ ImportType.LOCAL,
190
+ )
121
191
  if all(o.abstract for o in self.operations):
122
192
  return file_import
123
193
  file_import.add_submodule_import("typing", "TypeVar", ImportType.STDLIB, TypingSection.CONDITIONAL)
@@ -128,7 +198,7 @@ class OperationGroup(BaseModel):
128
198
 
129
199
  @property
130
200
  def filename(self) -> str:
131
- return self.operations[0].filename
201
+ return self.operations[0].filename if self.operations else "_operations"
132
202
 
133
203
  @property
134
204
  def is_mixin(self) -> bool:
@@ -103,8 +103,8 @@ class PagingOperationBase(OperationBase[PagingResponseType]):
103
103
  def operation_type(self) -> str:
104
104
  return "paging"
105
105
 
106
- def cls_type_annotation(self, *, async_mode: bool) -> str:
107
- return f"ClsType[{Response.type_annotation(self.responses[0], async_mode=async_mode)}]"
106
+ def cls_type_annotation(self, *, async_mode: bool, **kwargs: Any) -> str:
107
+ return f"ClsType[{Response.type_annotation(self.responses[0], async_mode=async_mode, **kwargs)}]"
108
108
 
109
109
  def _imports_shared(self, async_mode: bool, **kwargs: Any) -> FileImport:
110
110
  file_import = super()._imports_shared(async_mode, **kwargs)
@@ -117,7 +117,7 @@ class PagingOperationBase(OperationBase[PagingResponseType]):
117
117
  and self.code_model.options["builders_visibility"] == "embedded"
118
118
  and not async_mode
119
119
  ):
120
- file_import.merge(self.next_request_builder.imports())
120
+ file_import.merge(self.next_request_builder.imports(**kwargs))
121
121
  return file_import
122
122
 
123
123
  @property
@@ -129,6 +129,7 @@ class PagingOperationBase(OperationBase[PagingResponseType]):
129
129
  return FileImport(self.code_model)
130
130
  file_import = self._imports_shared(async_mode, **kwargs)
131
131
  file_import.merge(super().imports(async_mode, **kwargs))
132
+ serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
132
133
  if self.code_model.options["tracing"] and self.want_tracing:
133
134
  file_import.add_submodule_import(
134
135
  "azure.core.tracing.decorator",
@@ -136,7 +137,9 @@ class PagingOperationBase(OperationBase[PagingResponseType]):
136
137
  ImportType.SDKCORE,
137
138
  )
138
139
  if self.next_request_builder:
139
- file_import.merge(self.get_request_builder_import(self.next_request_builder, async_mode))
140
+ file_import.merge(
141
+ self.get_request_builder_import(self.next_request_builder, async_mode, serialize_namespace)
142
+ )
140
143
  elif any(p.is_api_version for p in self.client.parameters):
141
144
  file_import.add_import("urllib.parse", ImportType.STDLIB)
142
145
  file_import.add_submodule_import(
@@ -145,10 +148,10 @@ class PagingOperationBase(OperationBase[PagingResponseType]):
145
148
  ImportType.SDKCORE,
146
149
  )
147
150
  if self.code_model.options["models_mode"] == "dpg":
148
- relative_path = "..." if async_mode else ".."
151
+ relative_path = self.code_model.get_relative_import_path(serialize_namespace, module_name="_model_base")
149
152
  file_import.merge(self.item_type.imports(**kwargs))
150
- if self.default_error_deserialization or any(r.type for r in self.responses):
151
- file_import.add_submodule_import(f"{relative_path}_model_base", "_deserialize", ImportType.LOCAL)
153
+ if self.default_error_deserialization or self.need_deserialize:
154
+ file_import.add_submodule_import(relative_path, "_deserialize", ImportType.LOCAL)
152
155
  return file_import
153
156
 
154
157
 
@@ -155,23 +155,23 @@ class _ParameterBase(BaseModel, abc.ABC): # pylint: disable=too-many-instance-a
155
155
  def docstring_type(self, **kwargs: Any) -> str:
156
156
  return self.type.docstring_type(**kwargs)
157
157
 
158
- @property
159
- def serialization_type(self) -> str:
160
- return self.type.serialization_type
158
+ def serialization_type(self, **kwargs: Any) -> str:
159
+ return self.type.serialization_type(**kwargs)
161
160
 
162
- def _imports_shared(self, async_mode: bool, **_: Any) -> FileImport:
161
+ def _imports_shared(self, async_mode: bool, **kwargs: Any) -> FileImport: # pylint: disable=unused-argument
163
162
  file_import = FileImport(self.code_model)
164
163
  if self.optional and self.client_default_value is None:
165
164
  file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB)
165
+ serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
166
166
  if self.added_on and self.implementation != "Client":
167
167
  file_import.add_submodule_import(
168
- f"{'.' if async_mode else ''}.._validation",
168
+ self.code_model.get_relative_import_path(serialize_namespace, module_name="_validation"),
169
169
  "api_version_validation",
170
170
  ImportType.LOCAL,
171
171
  )
172
172
  if isinstance(self.type, CombinedType) and self.type.name:
173
173
  file_import.add_submodule_import(
174
- "..." if async_mode else "..",
174
+ self.code_model.get_relative_import_path(serialize_namespace),
175
175
  "_types",
176
176
  ImportType.LOCAL,
177
177
  TypingSection.TYPING,
@@ -212,8 +212,8 @@ class _ParameterBase(BaseModel, abc.ABC): # pylint: disable=too-many-instance-a
212
212
  @abc.abstractmethod
213
213
  def in_method_signature(self) -> bool: ...
214
214
 
215
- def method_signature(self, async_mode: bool) -> str:
216
- type_annotation = self.type_annotation(async_mode=async_mode)
215
+ def method_signature(self, async_mode: bool, **kwargs: Any) -> str:
216
+ type_annotation = self.type_annotation(async_mode=async_mode, **kwargs)
217
217
  if self.client_default_value is not None or self.optional:
218
218
  return f"{self.client_name}: {type_annotation} = {self.client_default_value_declaration},"
219
219
  if self.default_to_unset_sentinel:
@@ -272,9 +272,9 @@ class BodyParameter(_ParameterBase):
272
272
  def imports(self, async_mode: bool, **kwargs: Any) -> FileImport:
273
273
  file_import = super().imports(async_mode, **kwargs)
274
274
  if self.is_form_data:
275
- relative_path = "..." if async_mode else ".."
275
+ serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
276
276
  file_import.add_submodule_import(
277
- f"{relative_path}_vendor",
277
+ self.code_model.get_relative_import_path(serialize_namespace, module_name="_vendor"),
278
278
  "prepare_multipart_form_data",
279
279
  ImportType.LOCAL,
280
280
  )