@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
@@ -34,14 +34,13 @@ class DictionaryType(BaseType):
34
34
  def encode(self) -> Optional[str]:
35
35
  return self.element_type.encode if hasattr(self.element_type, "encode") else None # type: ignore
36
36
 
37
- @property
38
- def serialization_type(self) -> str:
37
+ def serialization_type(self, **kwargs: Any) -> str:
39
38
  """Returns the serialization value for msrest.
40
39
 
41
40
  :return: The serialization value for msrest
42
41
  :rtype: str
43
42
  """
44
- return f"{{{self.element_type.serialization_type}}}"
43
+ return f"{{{self.element_type.serialization_type(**kwargs)}}}"
45
44
 
46
45
  def type_annotation(self, **kwargs: Any) -> str:
47
46
  """The python type used for type annotation
@@ -7,6 +7,8 @@ from typing import Any, Dict, List, TYPE_CHECKING, Optional, cast
7
7
 
8
8
  from .base import BaseType
9
9
  from .imports import FileImport, ImportType, TypingSection
10
+ from .utils import NamespaceType
11
+
10
12
 
11
13
  if TYPE_CHECKING:
12
14
  from .code_model import CodeModel
@@ -63,9 +65,8 @@ class EnumValue(BaseType):
63
65
  client_default_value_declaration=client_default_value_declaration,
64
66
  )
65
67
 
66
- @property
67
- def serialization_type(self) -> str:
68
- return self.value_type.serialization_type
68
+ def serialization_type(self, **kwargs: Any) -> str:
69
+ return self.value_type.serialization_type(**kwargs)
69
70
 
70
71
  @property
71
72
  def instance_check_template(self) -> str:
@@ -75,7 +76,17 @@ class EnumValue(BaseType):
75
76
  file_import = FileImport(self.code_model)
76
77
  file_import.merge(self.value_type.imports(**kwargs))
77
78
  file_import.add_submodule_import("typing", "Literal", ImportType.STDLIB, TypingSection.REGULAR)
78
- file_import.add_submodule_import("._enums", self.enum_type.name, ImportType.LOCAL, TypingSection.REGULAR)
79
+ serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
80
+ file_import.add_submodule_import(
81
+ self.code_model.get_relative_import_path(
82
+ serialize_namespace,
83
+ self.code_model.get_imported_namespace_for_model(self.enum_type.client_namespace),
84
+ module_name=self.code_model.enums_filename,
85
+ ),
86
+ self.enum_type.name,
87
+ ImportType.LOCAL,
88
+ TypingSection.REGULAR,
89
+ )
79
90
 
80
91
  return file_import
81
92
 
@@ -124,18 +135,18 @@ class EnumType(BaseType):
124
135
  self.value_type = value_type
125
136
  self.internal: bool = self.yaml_data.get("internal", False)
126
137
  self.cross_language_definition_id: Optional[str] = self.yaml_data.get("crossLanguageDefinitionId")
138
+ self.client_namespace: str = self.yaml_data.get("clientNamespace", code_model.namespace)
127
139
 
128
140
  def __lt__(self, other):
129
141
  return self.name.lower() < other.name.lower()
130
142
 
131
- @property
132
- def serialization_type(self) -> str:
143
+ def serialization_type(self, **kwargs: Any) -> str:
133
144
  """Returns the serialization value for msrest.
134
145
 
135
146
  :return: The serialization value for msrest
136
147
  :rtype: str
137
148
  """
138
- return self.value_type.serialization_type
149
+ return self.value_type.serialization_type(**kwargs)
139
150
 
140
151
  def description(self, *, is_operation_file: bool) -> str:
141
152
  possible_values = [self.get_declaration(v.value) for v in self.values]
@@ -160,7 +171,12 @@ class EnumType(BaseType):
160
171
  :rtype: str
161
172
  """
162
173
  if self.code_model.options["models_mode"]:
163
- module_name = "_models." if kwargs.get("need_module_name", True) else ""
174
+
175
+ module_name = ""
176
+ if kwargs.get("need_model_alias", True):
177
+ serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
178
+ model_alias = self.code_model.get_unique_models_alias(serialize_namespace, self.client_namespace)
179
+ module_name = f"{model_alias}."
164
180
  file_name = f"{self.code_model.enums_filename}." if self.internal else ""
165
181
  model_name = module_name + file_name + self.name
166
182
  # we don't need quoted annotation in operation files, and need it in model folder files.
@@ -212,27 +228,34 @@ class EnumType(BaseType):
212
228
  )
213
229
 
214
230
  def imports(self, **kwargs: Any) -> FileImport:
215
- operation = kwargs.pop("operation", False)
216
231
  file_import = FileImport(self.code_model)
232
+ file_import.merge(self.value_type.imports(**kwargs))
217
233
  if self.code_model.options["models_mode"]:
218
234
  file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
219
- if not operation:
235
+
236
+ serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
237
+ relative_path = self.code_model.get_relative_import_path(serialize_namespace, self.client_namespace)
238
+ alias = self.code_model.get_unique_models_alias(serialize_namespace, self.client_namespace)
239
+ serialize_namespace_type = kwargs.get("serialize_namespace_type")
240
+ called_by_property = kwargs.get("called_by_property", False)
241
+ if serialize_namespace_type in [NamespaceType.OPERATION, NamespaceType.CLIENT]:
220
242
  file_import.add_submodule_import(
221
- "..",
243
+ relative_path,
222
244
  "models",
223
245
  ImportType.LOCAL,
224
- TypingSection.TYPING,
225
- alias="_models",
246
+ alias=alias,
247
+ typing_section=TypingSection.REGULAR,
226
248
  )
227
- file_import.merge(self.value_type.imports(operation=operation, **kwargs))
228
- relative_path = kwargs.pop("relative_path", None)
229
- if self.code_model.options["models_mode"] and relative_path:
230
- # add import for enums in operations file
231
- file_import.add_submodule_import(
232
- relative_path,
233
- "models",
234
- ImportType.LOCAL,
235
- alias="_models",
236
- typing_section=(TypingSection.TYPING if kwargs.get("model_typing") else TypingSection.REGULAR),
237
- )
249
+ elif serialize_namespace_type == NamespaceType.TYPES_FILE or (
250
+ serialize_namespace_type == NamespaceType.MODEL and called_by_property
251
+ ):
252
+ file_import.add_submodule_import(
253
+ relative_path,
254
+ "models",
255
+ ImportType.LOCAL,
256
+ alias=alias,
257
+ typing_section=TypingSection.TYPING,
258
+ )
259
+
260
+ file_import.merge(self.value_type.imports(**kwargs))
238
261
  return file_import
@@ -5,6 +5,7 @@
5
5
  # --------------------------------------------------------------------------
6
6
  from enum import Enum, auto
7
7
  from typing import Dict, List, Optional, Tuple, Union, Set, TYPE_CHECKING
8
+ from .._utils import get_parent_namespace
8
9
 
9
10
  if TYPE_CHECKING:
10
11
  from .code_model import CodeModel
@@ -259,7 +260,7 @@ class FileImport:
259
260
  def add_msrest_import(
260
261
  self,
261
262
  *,
262
- relative_path: str,
263
+ serialize_namespace: str,
263
264
  msrest_import_type: MsrestImportType,
264
265
  typing_section: TypingSection,
265
266
  ):
@@ -271,21 +272,22 @@ class FileImport:
271
272
  if msrest_import_type == MsrestImportType.SerializerDeserializer:
272
273
  self.add_submodule_import("msrest", "Deserializer", ImportType.THIRDPARTY, typing_section)
273
274
  else:
275
+ # _serialization.py is always in root namespace
276
+ imported_namespace = self.code_model.namespace
274
277
  if self.code_model.options["multiapi"]:
275
- relative_path += "."
278
+ # for multiapi, the namespace is azure.mgmt.xxx.v20XX_XX_XX while _serialization.py is in azure.mgmt.xxx
279
+ imported_namespace = get_parent_namespace(imported_namespace)
276
280
  if msrest_import_type == MsrestImportType.Module:
277
- self.add_submodule_import(relative_path, "_serialization", ImportType.LOCAL, typing_section)
278
- else:
279
281
  self.add_submodule_import(
280
- f"{relative_path}_serialization",
281
- "Serializer",
282
+ self.code_model.get_relative_import_path(serialize_namespace, imported_namespace),
283
+ "_serialization",
282
284
  ImportType.LOCAL,
283
285
  typing_section,
284
286
  )
287
+ else:
288
+ relative_path = self.code_model.get_relative_import_path(
289
+ serialize_namespace, imported_namespace, module_name="_serialization"
290
+ )
291
+ self.add_submodule_import(relative_path, "Serializer", ImportType.LOCAL, typing_section)
285
292
  if msrest_import_type == MsrestImportType.SerializerDeserializer:
286
- self.add_submodule_import(
287
- f"{relative_path}_serialization",
288
- "Deserializer",
289
- ImportType.LOCAL,
290
- typing_section,
291
- )
293
+ self.add_submodule_import(relative_path, "Deserializer", ImportType.LOCAL, typing_section)
@@ -29,9 +29,8 @@ class ListType(BaseType):
29
29
  def encode(self) -> Optional[str]:
30
30
  return self.element_type.encode if hasattr(self.element_type, "encode") else None # type: ignore
31
31
 
32
- @property
33
- def serialization_type(self) -> str:
34
- return f"[{self.element_type.serialization_type}]"
32
+ def serialization_type(self, **kwargs: Any) -> str:
33
+ return f"[{self.element_type.serialization_type(**kwargs)}]"
35
34
 
36
35
  def type_annotation(self, **kwargs: Any) -> str:
37
36
  if (
@@ -92,9 +92,9 @@ class LROOperationBase(OperationBase[LROResponseType]):
92
92
  return lro_response.type_annotation(**kwargs)
93
93
  return "None"
94
94
 
95
- def cls_type_annotation(self, *, async_mode: bool) -> str:
95
+ def cls_type_annotation(self, *, async_mode: bool, **kwargs: Any) -> str:
96
96
  """We don't want the poller to show up in ClsType, so we call super() on response type annotation"""
97
- return f"ClsType[{Response.type_annotation(self.responses[0], async_mode=async_mode)}]"
97
+ return f"ClsType[{Response.type_annotation(self.responses[0], async_mode=async_mode, **kwargs)}]"
98
98
 
99
99
  def get_poller_with_response_type(self, async_mode: bool) -> str:
100
100
  return self.response_type_annotation(async_mode=async_mode)
@@ -132,8 +132,12 @@ class LROOperationBase(OperationBase[LROResponseType]):
132
132
  ):
133
133
  # used in the case if initial operation returns none
134
134
  # but final call returns a model
135
- relative_path = "..." if async_mode else ".."
136
- file_import.add_submodule_import(f"{relative_path}_model_base", "_deserialize", ImportType.LOCAL)
135
+ serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
136
+ file_import.add_submodule_import(
137
+ self.code_model.get_relative_import_path(serialize_namespace, module_name="_model_base"),
138
+ "_deserialize",
139
+ ImportType.LOCAL,
140
+ )
137
141
  file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
138
142
  file_import.add_submodule_import("typing", "cast", ImportType.STDLIB)
139
143
  return file_import
@@ -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,