@autorest/python 5.12.1 → 5.12.5

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 (30) hide show
  1. package/ChangeLog.md +58 -0
  2. package/autorest/black/__init__.py +4 -1
  3. package/autorest/codegen/models/client.py +18 -16
  4. package/autorest/codegen/models/credential_schema.py +3 -3
  5. package/autorest/codegen/models/dictionary_schema.py +1 -1
  6. package/autorest/codegen/models/enum_schema.py +2 -2
  7. package/autorest/codegen/models/imports.py +90 -50
  8. package/autorest/codegen/models/list_schema.py +1 -1
  9. package/autorest/codegen/models/lro_operation.py +10 -8
  10. package/autorest/codegen/models/object_schema.py +2 -2
  11. package/autorest/codegen/models/operation.py +19 -19
  12. package/autorest/codegen/models/operation_group.py +7 -7
  13. package/autorest/codegen/models/paging_operation.py +7 -7
  14. package/autorest/codegen/models/parameter.py +5 -7
  15. package/autorest/codegen/models/primitive_schemas.py +2 -2
  16. package/autorest/codegen/models/property.py +1 -1
  17. package/autorest/codegen/models/request_builder.py +5 -5
  18. package/autorest/codegen/models/request_builder_parameter.py +0 -2
  19. package/autorest/codegen/models/schema_response.py +1 -1
  20. package/autorest/codegen/serializers/general_serializer.py +7 -7
  21. package/autorest/codegen/serializers/import_serializer.py +44 -46
  22. package/autorest/codegen/serializers/metadata_serializer.py +12 -10
  23. package/autorest/codegen/serializers/model_base_serializer.py +6 -6
  24. package/autorest/codegen/templates/metadata.json.jinja2 +3 -3
  25. package/autorest/codegen/templates/operation.py.jinja2 +2 -0
  26. package/autorest/codegen/templates/paging_operation.py.jinja2 +3 -1
  27. package/autorest/multiapi/models/imports.py +1 -1
  28. package/autorest/multiapi/serializers/import_serializer.py +1 -1
  29. package/package.json +3 -2
  30. package/requirements.txt +14 -0
package/ChangeLog.md CHANGED
@@ -1,5 +1,63 @@
1
1
  # Change Log
2
2
 
3
+ ### 2022-01-26 - 5.12.5
4
+
5
+ | Library | Min Version
6
+ | --------------- | -------
7
+ |`@autorest/core` | `3.6.2`
8
+ |`@autorest/modelerfour` | `4.19.1`
9
+ |`azure-core` dep of generated code | `1.20.1`
10
+ |`msrest` dep of generated code | `0.6.21`
11
+ |`azure-mgmt-core` dep of generated code (If generating mgmt plane code) | `1.3.0`
12
+
13
+ **Bug Fixes**
14
+
15
+ - Fix usage of `--black` flag outside of repo #1126
16
+ - Remove unused `metadata` value for `version-tolerant` generations #1127
17
+
18
+ ### 2022-01-14 - 5.12.4
19
+
20
+ | Library | Min Version
21
+ | --------------- | -------
22
+ |`@autorest/core` | `3.6.2`
23
+ |`@autorest/modelerfour` | `4.19.1`
24
+ |`azure-core` dep of generated code | `1.20.1`
25
+ |`msrest` dep of generated code | `0.6.21`
26
+ |`azure-mgmt-core` dep of generated code (If generating mgmt plane code) | `1.3.0`
27
+
28
+ **Bug Fixes**
29
+
30
+ - Remove duplicate generation of properties in classes that inherit from multiple classes #1120
31
+
32
+ ### 2022-01-13 - 5.12.3
33
+
34
+ | Library | Min Version
35
+ | --------------- | -------
36
+ |`@autorest/core` | `3.6.2`
37
+ |`@autorest/modelerfour` | `4.19.1`
38
+ |`azure-core` dep of generated code | `1.20.1`
39
+ |`msrest` dep of generated code | `0.6.21`
40
+ |`azure-mgmt-core` dep of generated code (If generating mgmt plane code) | `1.3.0`
41
+
42
+ **Bug Fixes**
43
+
44
+ - Unify multiapi constant behavior with single API version #1119
45
+ - Clean up docstrings by removing descriptions for client constants on methods and request builders #1119
46
+
47
+ ### 2022-01-11 - 5.12.2
48
+
49
+ | Library | Min Version
50
+ | --------------- | -------
51
+ |`@autorest/core` | `3.6.2`
52
+ |`@autorest/modelerfour` | `4.19.1`
53
+ |`azure-core` dep of generated code | `1.20.1`
54
+ |`msrest` dep of generated code | `0.6.21`
55
+ |`azure-mgmt-core` dep of generated code (If generating mgmt plane code) | `1.3.0`
56
+
57
+ **Bug Fixes**
58
+
59
+ - Fix installation of autorest python package #1118
60
+
3
61
  ### 2022-01-10 - 5.12.1
4
62
 
5
63
  | Library | Min Version
@@ -18,7 +18,10 @@ class BlackScriptPlugin(Plugin):
18
18
 
19
19
  def __init__(self, autorestapi):
20
20
  super(BlackScriptPlugin, self).__init__(autorestapi)
21
- self.output_folder: Path = Path(self._autorestapi.get_value("output-folder")).resolve()
21
+ output_folder_uri = self._autorestapi.get_value("outputFolderUri")
22
+ if output_folder_uri.startswith("file:"):
23
+ output_folder_uri = output_folder_uri[5:]
24
+ self.output_folder = Path(output_folder_uri)
22
25
 
23
26
  def process(self) -> bool:
24
27
  # apply format_file on every file in the output folder
@@ -33,27 +33,27 @@ class Client:
33
33
  def _imports_shared(self, async_mode: bool) -> FileImport:
34
34
  file_import = FileImport()
35
35
 
36
- file_import.add_from_import("msrest", "Serializer", ImportType.AZURECORE)
37
- file_import.add_from_import("msrest", "Deserializer", ImportType.AZURECORE)
38
- file_import.add_from_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
36
+ file_import.add_submodule_import("msrest", "Serializer", ImportType.AZURECORE)
37
+ file_import.add_submodule_import("msrest", "Deserializer", ImportType.AZURECORE)
38
+ file_import.add_submodule_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
39
39
 
40
40
  any_optional_gp = any(not gp.required for gp in self.parameters)
41
41
 
42
42
  if any_optional_gp or self.code_model.service_client.parameters.host:
43
- file_import.add_from_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
43
+ file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
44
44
 
45
45
  if self.code_model.options["azure_arm"]:
46
- file_import.add_from_import(
46
+ file_import.add_submodule_import(
47
47
  "azure.mgmt.core", self.pipeline_class(async_mode), ImportType.AZURECORE
48
48
  )
49
49
  else:
50
- file_import.add_from_import(
50
+ file_import.add_submodule_import(
51
51
  "azure.core", self.pipeline_class(async_mode), ImportType.AZURECORE
52
52
  )
53
53
 
54
54
  for gp in self.code_model.global_parameters:
55
55
  file_import.merge(gp.imports())
56
- file_import.add_from_import(
56
+ file_import.add_submodule_import(
57
57
  "._configuration", f"{self.code_model.class_name}Configuration",
58
58
  ImportType.LOCAL
59
59
  )
@@ -63,35 +63,37 @@ class Client:
63
63
  def imports(self, async_mode: bool) -> FileImport:
64
64
  file_import = self._imports_shared(async_mode)
65
65
  if async_mode:
66
- file_import.add_from_import("typing", "Awaitable", ImportType.STDLIB)
67
- file_import.add_from_import(
66
+ file_import.add_submodule_import("typing", "Awaitable", ImportType.STDLIB)
67
+ file_import.add_submodule_import(
68
68
  "azure.core.rest", "AsyncHttpResponse", ImportType.AZURECORE, TypingSection.CONDITIONAL
69
69
  )
70
70
  else:
71
- file_import.add_from_import(
71
+ file_import.add_submodule_import(
72
72
  "azure.core.rest", "HttpResponse", ImportType.AZURECORE, TypingSection.CONDITIONAL
73
73
  )
74
- file_import.add_from_import("azure.core.rest", "HttpRequest", ImportType.AZURECORE, TypingSection.CONDITIONAL)
74
+ file_import.add_submodule_import(
75
+ "azure.core.rest", "HttpRequest", ImportType.AZURECORE, TypingSection.CONDITIONAL
76
+ )
75
77
  for og in self.code_model.operation_groups:
76
- file_import.add_from_import(
78
+ file_import.add_submodule_import(
77
79
  f".{self.code_model.operations_folder_name}", og.class_name, ImportType.LOCAL
78
80
  )
79
81
 
80
82
  if self.code_model.sorted_schemas:
81
83
  path_to_models = ".." if async_mode else "."
82
- file_import.add_from_import(path_to_models, "models", ImportType.LOCAL)
84
+ file_import.add_submodule_import(path_to_models, "models", ImportType.LOCAL)
83
85
  else:
84
86
  # in this case, we have client_models = {} in the service client, which needs a type annotation
85
87
  # this import will always be commented, so will always add it to the typing section
86
- file_import.add_from_import("typing", "Dict", ImportType.STDLIB, TypingSection.TYPING)
87
- file_import.add_from_import("copy", "deepcopy", ImportType.STDLIB)
88
+ file_import.add_submodule_import("typing", "Dict", ImportType.STDLIB, TypingSection.TYPING)
89
+ file_import.add_submodule_import("copy", "deepcopy", ImportType.STDLIB)
88
90
  return file_import
89
91
 
90
92
  def imports_for_multiapi(self, async_mode: bool) -> FileImport:
91
93
  file_import = self._imports_shared(async_mode)
92
94
  try:
93
95
  mixin_operation = next(og for og in self.code_model.operation_groups if og.is_empty_operation_group)
94
- file_import.add_from_import("._operations_mixin", mixin_operation.class_name, ImportType.LOCAL)
96
+ file_import.add_submodule_import("._operations_mixin", mixin_operation.class_name, ImportType.LOCAL)
95
97
  except StopIteration:
96
98
  pass
97
99
  return file_import
@@ -44,7 +44,7 @@ class AzureKeyCredentialSchema(CredentialSchema):
44
44
 
45
45
  def imports(self) -> FileImport:
46
46
  file_import = FileImport()
47
- file_import.add_from_import(
47
+ file_import.add_submodule_import(
48
48
  "azure.core.credentials",
49
49
  "AzureKeyCredential",
50
50
  ImportType.AZURECORE,
@@ -76,13 +76,13 @@ class TokenCredentialSchema(CredentialSchema):
76
76
  def imports(self) -> FileImport:
77
77
  file_import = FileImport()
78
78
  if self.async_mode:
79
- file_import.add_from_import(
79
+ file_import.add_submodule_import(
80
80
  "azure.core.credentials_async", "AsyncTokenCredential",
81
81
  ImportType.AZURECORE,
82
82
  typing_section=TypingSection.TYPING
83
83
  )
84
84
  else:
85
- file_import.add_from_import(
85
+ file_import.add_submodule_import(
86
86
  "azure.core.credentials", "TokenCredential",
87
87
  ImportType.AZURECORE,
88
88
  typing_section=TypingSection.TYPING
@@ -98,6 +98,6 @@ class DictionarySchema(BaseSchema):
98
98
 
99
99
  def imports(self) -> FileImport:
100
100
  file_import = FileImport()
101
- file_import.add_from_import("typing", "Dict", ImportType.STDLIB, TypingSection.CONDITIONAL)
101
+ file_import.add_submodule_import("typing", "Dict", ImportType.STDLIB, TypingSection.CONDITIONAL)
102
102
  file_import.merge(self.element_type.imports())
103
103
  return file_import
@@ -178,7 +178,7 @@ class EnumSchema(BaseSchema):
178
178
 
179
179
  def imports(self) -> FileImport:
180
180
  file_import = FileImport()
181
- file_import.add_from_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
181
+ file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
182
182
  file_import.merge(self.enum_type.imports())
183
183
  return file_import
184
184
 
@@ -186,7 +186,7 @@ class EnumSchema(BaseSchema):
186
186
  imports = self.imports()
187
187
  # we import every enum since we can get extremely long imports
188
188
  # if we import my name
189
- imports.add_from_import("." + self.enum_file_name, "*", ImportType.LOCAL)
189
+ imports.add_submodule_import("." + self.enum_file_name, "*", ImportType.LOCAL)
190
190
  return imports
191
191
 
192
192
  class HiddenModelEnumSchema(EnumSchema):
@@ -4,8 +4,7 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  from enum import Enum
7
- from typing import Dict, Optional, Set, Tuple, Union
8
-
7
+ from typing import Dict, List, Optional, Tuple, Union, Set
9
8
 
10
9
  class ImportType(str, Enum):
11
10
  STDLIB = "stdlib"
@@ -18,81 +17,122 @@ class TypingSection(str, Enum):
18
17
  CONDITIONAL = "conditional" # is a typing import when we're dealing with files that py2 will use, else regular
19
18
  TYPING = "typing" # never a typing import
20
19
 
20
+ class ImportModel:
21
+ def __init__(
22
+ self,
23
+ typing_section: TypingSection,
24
+ import_type: ImportType,
25
+ module_name: str,
26
+ *,
27
+ submodule_name: Optional[str] = None,
28
+ alias: Optional[str] = None,
29
+ ):
30
+ self.typing_section = typing_section
31
+ self.import_type = import_type
32
+ self.module_name = module_name
33
+ self.submodule_name = submodule_name
34
+ self.alias = alias
35
+
36
+ def __eq__(self, other):
37
+ try:
38
+ return (
39
+ self.typing_section == other.typing_section and
40
+ self.import_type == other.import_type and
41
+ self.module_name == other.module_name and
42
+ self.submodule_name == other.submodule_name and
43
+ self.alias == other.alias
44
+ )
45
+ except AttributeError:
46
+ return False
47
+
48
+ def __hash__(self):
49
+ retval: int = 0
50
+ for attr in dir(self):
51
+ if attr[0] != "_":
52
+ retval += hash(getattr(self, attr))
53
+ return retval
21
54
 
22
55
  class FileImport:
23
56
  def __init__(
24
57
  self,
25
- imports: Dict[
26
- TypingSection,
27
- Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]]
28
- ] = None
58
+ imports: List[ImportModel] = None
29
59
  ) -> None:
30
- # Basic implementation
31
- # First level dict: TypingSection
32
- # Second level dict: ImportType
33
- # Third level dict: the package name.
34
- # Fourth level set: None if this import is a "import", the name to import if it's a "from"
35
- self._imports: Dict[
36
- TypingSection,
37
- Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]]
38
- ] = imports or dict()
60
+ self.imports = imports or []
39
61
  # has sync and async type definitions
40
62
  self.type_definitions: Dict[str, Tuple[str, str]] = {}
41
63
 
42
- def _add_import(
43
- self,
44
- from_section: str,
45
- import_type: ImportType,
46
- name_import: Optional[Union[str, Tuple[str, str]]] = None,
47
- typing_section: TypingSection = TypingSection.REGULAR
48
- ) -> None:
49
- self._imports.setdefault(
50
- typing_section, dict()
51
- ).setdefault(
52
- import_type, dict()
53
- ).setdefault(
54
- from_section, set()
55
- ).add(name_import)
64
+ def _append_import(self, import_model: ImportModel) -> None:
65
+ if not any(
66
+ i for i in self.imports
67
+ if all(
68
+ getattr(i, attr) == getattr(import_model, attr)
69
+ for attr in dir(i)
70
+ if attr[0] != "_"
71
+ )
72
+ ):
73
+ self.imports.append(import_model)
74
+
75
+ def get_imports_from_section(self, typing_section: TypingSection) -> List[ImportModel]:
76
+ return [i for i in self.imports if i.typing_section == typing_section]
56
77
 
57
- def add_from_import(
78
+ def add_submodule_import(
58
79
  self,
59
- from_section: str,
60
- name_import: str,
80
+ module_name: str,
81
+ submodule_name: str,
61
82
  import_type: ImportType,
62
83
  typing_section: TypingSection = TypingSection.REGULAR,
63
84
  alias: Optional[str] = None,
64
85
  ) -> None:
65
86
  """Add an import to this import block.
66
87
  """
67
- self._add_import(
68
- from_section, import_type, (name_import, alias) if alias else name_import, typing_section
69
- )
88
+ self._append_import(ImportModel(
89
+ typing_section=typing_section,
90
+ import_type=import_type,
91
+ module_name=module_name,
92
+ submodule_name=submodule_name,
93
+ alias=alias,
94
+ ))
70
95
 
71
96
  def add_import(
72
97
  self,
73
- name_import: str,
98
+ module_name: str,
74
99
  import_type: ImportType,
75
100
  typing_section: TypingSection = TypingSection.REGULAR
76
101
  ) -> None:
77
102
  # Implementation detail: a regular import is just a "from" with no from
78
- self._add_import(name_import, import_type, None, typing_section)
79
-
80
- @property
81
- def imports(self) -> Dict[
82
- TypingSection,
83
- Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]]
84
- ]:
85
- return self._imports
103
+ self._append_import(ImportModel(
104
+ typing_section=typing_section,
105
+ import_type=import_type,
106
+ module_name=module_name,
107
+ ))
86
108
 
87
109
  def define_mypy_type(self, type_name: str, type_value: str, async_type_value: Optional[str] = None):
88
- self._add_import("typing", ImportType.STDLIB, "TypeVar", TypingSection.CONDITIONAL)
110
+ self.add_submodule_import("typing", "TypeVar", ImportType.STDLIB, TypingSection.CONDITIONAL)
89
111
  self.type_definitions[type_name] = (type_value, async_type_value or type_value)
90
112
 
91
113
  def merge(self, file_import: "FileImport") -> None:
92
114
  """Merge the given file import format."""
93
- for typing_section, import_type_dict in file_import.imports.items():
94
- for import_type, package_list in import_type_dict.items():
95
- for package_name, module_list in package_list.items():
96
- for module_name in module_list:
97
- self._add_import(package_name, import_type, module_name, typing_section)
115
+ for i in file_import.imports:
116
+ self._append_import(i)
98
117
  self.type_definitions.update(file_import.type_definitions)
118
+
119
+ def to_dict(self) -> Dict[
120
+ TypingSection,
121
+ Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]]
122
+ ]:
123
+ retval: Dict[
124
+ TypingSection,
125
+ Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]]
126
+ ] = dict()
127
+ for i in self.imports:
128
+ name_import: Optional[Union[str, Tuple[str, str]]] = None
129
+ if i.submodule_name:
130
+ name_import = (i.submodule_name, i.alias) if i.alias else i.submodule_name
131
+ retval.setdefault(
132
+ i.typing_section, dict()
133
+ ).setdefault(
134
+ i.import_type, dict()
135
+ ).setdefault(
136
+ i.module_name, set()
137
+ ).add(name_import)
138
+ return retval
@@ -108,6 +108,6 @@ class ListSchema(BaseSchema):
108
108
 
109
109
  def imports(self) -> FileImport:
110
110
  file_import = FileImport()
111
- file_import.add_from_import("typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL)
111
+ file_import.add_submodule_import("typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL)
112
112
  file_import.merge(self.element_type.imports())
113
113
  return file_import
@@ -140,28 +140,30 @@ class LROOperation(Operation):
140
140
  file_import = super().imports_for_multiapi(async_mode)
141
141
  poller_import_path = ".".join(self.get_poller_path(async_mode).split(".")[:-1])
142
142
  poller = self.get_poller(async_mode)
143
- file_import.add_from_import(poller_import_path, poller, ImportType.AZURECORE, TypingSection.CONDITIONAL)
143
+ file_import.add_submodule_import(poller_import_path, poller, ImportType.AZURECORE, TypingSection.CONDITIONAL)
144
144
  return file_import
145
145
 
146
146
  def imports(self, async_mode: bool) -> FileImport:
147
147
  file_import = super().imports(async_mode)
148
- file_import.add_from_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
148
+ file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
149
149
 
150
150
  poller_import_path = ".".join(self.get_poller_path(async_mode).split(".")[:-1])
151
151
  poller = self.get_poller(async_mode)
152
- file_import.add_from_import(poller_import_path, poller, ImportType.AZURECORE)
152
+ file_import.add_submodule_import(poller_import_path, poller, ImportType.AZURECORE)
153
153
 
154
154
  default_polling_method_import_path = ".".join(
155
155
  self.get_default_polling_method_path(async_mode, self.code_model.options['azure_arm']).split(".")[:-1]
156
156
  )
157
157
  default_polling_method = self.get_default_polling_method(async_mode, self.code_model.options['azure_arm'])
158
- file_import.add_from_import(default_polling_method_import_path, default_polling_method, ImportType.AZURECORE)
158
+ file_import.add_submodule_import(
159
+ default_polling_method_import_path, default_polling_method, ImportType.AZURECORE
160
+ )
159
161
 
160
162
  default_no_polling_method_import_path = ".".join(
161
163
  self.get_default_no_polling_method_path(async_mode).split(".")[:-1]
162
164
  )
163
165
  default_no_polling_method = self.get_default_no_polling_method(async_mode)
164
- file_import.add_from_import(
166
+ file_import.add_submodule_import(
165
167
  default_no_polling_method_import_path, default_no_polling_method, ImportType.AZURECORE
166
168
  )
167
169
 
@@ -169,10 +171,10 @@ class LROOperation(Operation):
169
171
  self.get_base_polling_method_path(async_mode).split(".")[:-1]
170
172
  )
171
173
  base_polling_method = self.get_base_polling_method(async_mode)
172
- file_import.add_from_import(base_polling_method_import_path, base_polling_method, ImportType.AZURECORE)
174
+ file_import.add_submodule_import(base_polling_method_import_path, base_polling_method, ImportType.AZURECORE)
173
175
 
174
176
  if async_mode:
175
- file_import.add_from_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
177
+ file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
176
178
  if self.lro_response and self.lro_response.has_body and not self.code_model.options["models_mode"]:
177
- file_import.add_from_import("json", "loads", import_type=ImportType.STDLIB, alias="_loads")
179
+ file_import.add_submodule_import("json", "loads", import_type=ImportType.STDLIB, alias="_loads")
178
180
  return file_import
@@ -213,7 +213,7 @@ class ObjectSchema(BaseSchema): # pylint: disable=too-many-instance-attributes
213
213
  def imports(self) -> FileImport:
214
214
  file_import = FileImport()
215
215
  if self.is_exception:
216
- file_import.add_from_import("azure.core.exceptions", "HttpResponseError", ImportType.AZURECORE)
216
+ file_import.add_submodule_import("azure.core.exceptions", "HttpResponseError", ImportType.AZURECORE)
217
217
  return file_import
218
218
 
219
219
  class HiddenModelObjectSchema(ObjectSchema):
@@ -240,7 +240,7 @@ class HiddenModelObjectSchema(ObjectSchema):
240
240
 
241
241
  def imports(self) -> FileImport:
242
242
  file_import = FileImport()
243
- file_import.add_from_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
243
+ file_import.add_submodule_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
244
244
  return file_import
245
245
 
246
246
  def get_object_schema(code_model) -> Type[ObjectSchema]:
@@ -147,7 +147,7 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
147
147
 
148
148
  def _imports_shared(self, async_mode: bool) -> FileImport: # pylint: disable=unused-argument
149
149
  file_import = FileImport()
150
- file_import.add_from_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
150
+ file_import.add_submodule_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
151
151
  for param in self.parameters.method:
152
152
  file_import.merge(param.imports())
153
153
 
@@ -160,10 +160,10 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
160
160
  file_import.merge(cast(BaseSchema, response.schema).imports())
161
161
 
162
162
  if len([r for r in self.responses if r.has_body]) > 1:
163
- file_import.add_from_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
163
+ file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
164
164
 
165
165
  if self.is_stream_response:
166
- file_import.add_from_import("typing", "IO", ImportType.STDLIB, TypingSection.CONDITIONAL)
166
+ file_import.add_submodule_import("typing", "IO", ImportType.STDLIB, TypingSection.CONDITIONAL)
167
167
  return file_import
168
168
 
169
169
 
@@ -174,24 +174,24 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
174
174
  file_import = self._imports_shared(async_mode)
175
175
 
176
176
  # Exceptions
177
- file_import.add_from_import("azure.core.exceptions", "map_error", ImportType.AZURECORE)
177
+ file_import.add_submodule_import("azure.core.exceptions", "map_error", ImportType.AZURECORE)
178
178
  if self.code_model.options["azure_arm"]:
179
- file_import.add_from_import("azure.mgmt.core.exceptions", "ARMErrorFormat", ImportType.AZURECORE)
180
- file_import.add_from_import("azure.core.exceptions", "HttpResponseError", ImportType.AZURECORE)
179
+ file_import.add_submodule_import("azure.mgmt.core.exceptions", "ARMErrorFormat", ImportType.AZURECORE)
180
+ file_import.add_submodule_import("azure.core.exceptions", "HttpResponseError", ImportType.AZURECORE)
181
181
 
182
182
 
183
183
  file_import.add_import("functools", ImportType.STDLIB)
184
- file_import.add_from_import("typing", "Callable", ImportType.STDLIB, TypingSection.CONDITIONAL)
185
- file_import.add_from_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
186
- file_import.add_from_import("typing", "Dict", ImportType.STDLIB, TypingSection.CONDITIONAL)
187
- file_import.add_from_import("typing", "TypeVar", ImportType.STDLIB, TypingSection.CONDITIONAL)
188
- file_import.add_from_import("typing", "Generic", ImportType.STDLIB, TypingSection.CONDITIONAL)
189
- file_import.add_from_import("azure.core.pipeline", "PipelineResponse", ImportType.AZURECORE)
190
- file_import.add_from_import("azure.core.rest", "HttpRequest", ImportType.AZURECORE)
184
+ file_import.add_submodule_import("typing", "Callable", ImportType.STDLIB, TypingSection.CONDITIONAL)
185
+ file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
186
+ file_import.add_submodule_import("typing", "Dict", ImportType.STDLIB, TypingSection.CONDITIONAL)
187
+ file_import.add_submodule_import("typing", "TypeVar", ImportType.STDLIB, TypingSection.CONDITIONAL)
188
+ file_import.add_submodule_import("typing", "Generic", ImportType.STDLIB, TypingSection.CONDITIONAL)
189
+ file_import.add_submodule_import("azure.core.pipeline", "PipelineResponse", ImportType.AZURECORE)
190
+ file_import.add_submodule_import("azure.core.rest", "HttpRequest", ImportType.AZURECORE)
191
191
  if async_mode:
192
- file_import.add_from_import("azure.core.pipeline.transport", "AsyncHttpResponse", ImportType.AZURECORE)
192
+ file_import.add_submodule_import("azure.core.pipeline.transport", "AsyncHttpResponse", ImportType.AZURECORE)
193
193
  else:
194
- file_import.add_from_import("azure.core.pipeline.transport", "HttpResponse", ImportType.AZURECORE)
194
+ file_import.add_submodule_import("azure.core.pipeline.transport", "HttpResponse", ImportType.AZURECORE)
195
195
 
196
196
  # Deprecation
197
197
  # FIXME: Replace with "the YAML contains deprecated:true"
@@ -202,14 +202,14 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
202
202
  builder_group_name = self.request_builder.builder_group_name
203
203
  rest_import_path = "..." if async_mode else ".."
204
204
  if builder_group_name:
205
- file_import.add_from_import(
205
+ file_import.add_submodule_import(
206
206
  f"{rest_import_path}{self.code_model.rest_layer_name}",
207
- name_import=builder_group_name,
207
+ builder_group_name,
208
208
  import_type=ImportType.LOCAL,
209
209
  alias=f"rest_{builder_group_name}"
210
210
  )
211
211
  else:
212
- file_import.add_from_import(
212
+ file_import.add_submodule_import(
213
213
  rest_import_path,
214
214
  self.code_model.rest_layer_name,
215
215
  import_type=ImportType.LOCAL,
@@ -219,7 +219,7 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
219
219
  file_import.merge(self.request_builder.imports())
220
220
  if self.code_model.need_request_converter:
221
221
  relative_path = "..." if async_mode else ".."
222
- file_import.add_from_import(
222
+ file_import.add_submodule_import(
223
223
  f"{relative_path}_vendor", "_convert_request", ImportType.LOCAL
224
224
  )
225
225
  if self.code_model.options["version_tolerant"] and (
@@ -58,23 +58,23 @@ class OperationGroup(BaseModel):
58
58
 
59
59
  def imports(self, async_mode: bool) -> FileImport:
60
60
  file_import = FileImport()
61
- file_import.add_from_import("azure.core.exceptions", "ClientAuthenticationError", ImportType.AZURECORE)
62
- file_import.add_from_import("azure.core.exceptions", "ResourceNotFoundError", ImportType.AZURECORE)
63
- file_import.add_from_import("azure.core.exceptions", "ResourceExistsError", ImportType.AZURECORE)
61
+ file_import.add_submodule_import("azure.core.exceptions", "ClientAuthenticationError", ImportType.AZURECORE)
62
+ file_import.add_submodule_import("azure.core.exceptions", "ResourceNotFoundError", ImportType.AZURECORE)
63
+ file_import.add_submodule_import("azure.core.exceptions", "ResourceExistsError", ImportType.AZURECORE)
64
64
  for operation in self.operations:
65
65
  file_import.merge(operation.imports(async_mode))
66
66
  if self.code_model.options["tracing"]:
67
67
  if async_mode:
68
- file_import.add_from_import(
68
+ file_import.add_submodule_import(
69
69
  "azure.core.tracing.decorator_async", "distributed_trace_async", ImportType.AZURECORE,
70
70
  )
71
71
  else:
72
- file_import.add_from_import(
72
+ file_import.add_submodule_import(
73
73
  "azure.core.tracing.decorator", "distributed_trace", ImportType.AZURECORE,
74
74
  )
75
75
  local_path = "..." if async_mode else ".."
76
76
  if self.code_model.has_schemas and self.code_model.options["models_mode"]:
77
- file_import.add_from_import(local_path, "models", ImportType.LOCAL, alias="_models")
77
+ file_import.add_submodule_import(local_path, "models", ImportType.LOCAL, alias="_models")
78
78
  if self.code_model.options["builders_visibility"] == "embedded" and async_mode:
79
79
  if not self.code_model.options["combine_operation_files"]:
80
80
  operation_group_name = "" if self.is_empty_operation_group else self.name
@@ -88,7 +88,7 @@ class OperationGroup(BaseModel):
88
88
  python3_only = self.code_model.options["python3_only"]
89
89
  typed_sync_operation_file = self.code_model.options["add_python3_operation_files"]
90
90
  suffix = "_py3" if typed_sync_operation_file and not python3_only else ""
91
- file_import.add_from_import(
91
+ file_import.add_submodule_import(
92
92
  f"...{self.code_model.operations_folder_name}.{self.filename}{suffix}",
93
93
  request_builder.name,
94
94
  import_type=ImportType.LOCAL
@@ -125,9 +125,9 @@ class PagingOperation(Operation):
125
125
  def _imports_shared(self, async_mode: bool) -> FileImport:
126
126
  file_import = super()._imports_shared(async_mode)
127
127
  if async_mode:
128
- file_import.add_from_import("typing", "AsyncIterable", ImportType.STDLIB, TypingSection.CONDITIONAL)
128
+ file_import.add_submodule_import("typing", "AsyncIterable", ImportType.STDLIB, TypingSection.CONDITIONAL)
129
129
  else:
130
- file_import.add_from_import("typing", "Iterable", ImportType.STDLIB, TypingSection.CONDITIONAL)
130
+ file_import.add_submodule_import("typing", "Iterable", ImportType.STDLIB, TypingSection.CONDITIONAL)
131
131
  if (
132
132
  self.next_request_builder and
133
133
  self.code_model.options["builders_visibility"] == "embedded"
@@ -141,7 +141,7 @@ class PagingOperation(Operation):
141
141
  pager_import_path = ".".join(self.get_pager_path(async_mode).split(".")[:-1])
142
142
  pager = self.get_pager(async_mode)
143
143
 
144
- file_import.add_from_import(pager_import_path, pager, ImportType.AZURECORE, TypingSection.CONDITIONAL)
144
+ file_import.add_submodule_import(pager_import_path, pager, ImportType.AZURECORE, TypingSection.CONDITIONAL)
145
145
 
146
146
  return file_import
147
147
 
@@ -151,16 +151,16 @@ class PagingOperation(Operation):
151
151
  pager_import_path = ".".join(self.get_pager_path(async_mode).split(".")[:-1])
152
152
  pager = self.get_pager(async_mode)
153
153
 
154
- file_import.add_from_import(pager_import_path, pager, ImportType.AZURECORE)
154
+ file_import.add_submodule_import(pager_import_path, pager, ImportType.AZURECORE)
155
155
 
156
156
  if async_mode:
157
- file_import.add_from_import("azure.core.async_paging", "AsyncList", ImportType.AZURECORE)
157
+ file_import.add_submodule_import("azure.core.async_paging", "AsyncList", ImportType.AZURECORE)
158
158
 
159
159
  if self.code_model.options["tracing"]:
160
- file_import.add_from_import(
160
+ file_import.add_submodule_import(
161
161
  "azure.core.tracing.decorator", "distributed_trace", ImportType.AZURECORE,
162
162
  )
163
163
  if not self.code_model.options["models_mode"]:
164
- file_import.add_from_import("json", "loads", ImportType.STDLIB, alias="_loads")
164
+ file_import.add_submodule_import("json", "loads", ImportType.STDLIB, alias="_loads")
165
165
 
166
166
  return file_import
@@ -177,8 +177,6 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
177
177
  return not(
178
178
  # don't put accept in signature
179
179
  self.rest_api_name == "Accept"
180
- # if i'm multiapi, don't add constants
181
- or (self.code_model.options["multiapi"] and self.constant)
182
180
  # If i'm not in the method code, no point in being in signature
183
181
  or not self.in_method_code
184
182
  # If I'm grouped, my grouper will be on signature, not me
@@ -302,8 +300,6 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
302
300
  @property
303
301
  def is_kwarg(self) -> bool:
304
302
  # this means "am I in **kwargs?"
305
- if self.code_model.options["multiapi"]:
306
- return self.rest_api_name == "Content-Type"
307
303
  return self.rest_api_name == "Content-Type" or (self.constant and self.rest_api_name != "Accept")
308
304
 
309
305
  @property
@@ -313,7 +309,9 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
313
309
 
314
310
  @property
315
311
  def is_hidden(self) -> bool:
316
- return self.serialized_name in _HIDDEN_KWARGS
312
+ return self.serialized_name in _HIDDEN_KWARGS or (
313
+ self.yaml_data["implementation"] == "Client" and self.constant
314
+ )
317
315
 
318
316
  @property
319
317
  def is_positional(self) -> bool:
@@ -356,9 +354,9 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
356
354
  def imports(self) -> FileImport:
357
355
  file_import = self.schema.imports()
358
356
  if not self.required:
359
- file_import.add_from_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
357
+ file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
360
358
  if self.has_multiple_content_types or self._is_io_json:
361
- file_import.add_from_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
359
+ file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
362
360
 
363
361
  return file_import
364
362
 
@@ -116,7 +116,7 @@ class IOSchema(PrimitiveSchema):
116
116
 
117
117
  def imports(self) -> FileImport:
118
118
  file_import = FileImport()
119
- file_import.add_from_import("typing", "IO", ImportType.STDLIB, TypingSection.CONDITIONAL)
119
+ file_import.add_submodule_import("typing", "IO", ImportType.STDLIB, TypingSection.CONDITIONAL)
120
120
  return file_import
121
121
 
122
122
  class AnySchema(PrimitiveSchema):
@@ -138,7 +138,7 @@ class AnySchema(PrimitiveSchema):
138
138
 
139
139
  def imports(self) -> FileImport:
140
140
  file_import = FileImport()
141
- file_import.add_from_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
141
+ file_import.add_submodule_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
142
142
  return file_import
143
143
 
144
144
  class JSONSchema(AnySchema):
@@ -170,5 +170,5 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
170
170
  def model_file_imports(self) -> FileImport:
171
171
  file_import = self.schema.model_file_imports()
172
172
  if not self.required:
173
- file_import.add_from_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
173
+ file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
174
174
  return file_import
@@ -68,7 +68,7 @@ class RequestBuilder(BaseBuilder):
68
68
  for parameter in self.parameters:
69
69
  file_import.merge(parameter.imports())
70
70
 
71
- file_import.add_from_import(
71
+ file_import.add_submodule_import(
72
72
  "azure.core.rest",
73
73
  "HttpRequest",
74
74
  ImportType.AZURECORE,
@@ -77,17 +77,17 @@ class RequestBuilder(BaseBuilder):
77
77
  relative_path = ".."
78
78
  if not self.code_model.options["builders_visibility"] == "embedded" and self.operation_group_name:
79
79
  relative_path = "..." if self.operation_group_name else ".."
80
- file_import.add_from_import(
80
+ file_import.add_submodule_import(
81
81
  f"{relative_path}_vendor", "_format_url_section", ImportType.LOCAL
82
82
  )
83
83
  if self.parameters.headers or self.parameters.query:
84
- file_import.add_from_import(
84
+ file_import.add_submodule_import(
85
85
  "typing", "Dict", ImportType.STDLIB, typing_section=TypingSection.CONDITIONAL
86
86
  )
87
- file_import.add_from_import(
87
+ file_import.add_submodule_import(
88
88
  "typing", "Any", ImportType.STDLIB, typing_section=TypingSection.CONDITIONAL
89
89
  )
90
- file_import.add_from_import("msrest", "Serializer", ImportType.AZURECORE)
90
+ file_import.add_submodule_import("msrest", "Serializer", ImportType.AZURECORE)
91
91
  if self.parameters.has_body and (
92
92
  self.code_model.options["builders_visibility"] != "embedded" or
93
93
  self.code_model.options["add_python3_operation_files"]
@@ -18,8 +18,6 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
18
18
  return not(
19
19
  # don't put accept in method signature
20
20
  self.rest_api_name == "Accept"
21
- # if i'm multiapi, don't add constants
22
- or (self.code_model.options["multiapi"] and self.constant)
23
21
  # If i'm not in the method code, no point in being in signature
24
22
  or not self.in_method_code
25
23
  # If I'm a flattened property of a body, don't want me, want the body param
@@ -99,7 +99,7 @@ class SchemaResponse(BaseModel):
99
99
  def imports(self, code_model) -> FileImport:
100
100
  file_import = FileImport()
101
101
  if not code_model.options["models_mode"] and self.is_xml:
102
- file_import.add_from_import("xml.etree", "ElementTree", ImportType.STDLIB, alias="ET")
102
+ file_import.add_submodule_import("xml.etree", "ElementTree", ImportType.STDLIB, alias="ET")
103
103
  return file_import
104
104
 
105
105
  @classmethod
@@ -10,17 +10,17 @@ from .client_serializer import ClientSerializer, ConfigSerializer
10
10
 
11
11
  def config_imports(code_model, global_parameters: ParameterList, async_mode: bool) -> FileImport:
12
12
  file_import = FileImport()
13
- file_import.add_from_import("azure.core.configuration", "Configuration", ImportType.AZURECORE)
14
- file_import.add_from_import("azure.core.pipeline", "policies", ImportType.AZURECORE)
15
- file_import.add_from_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
13
+ file_import.add_submodule_import("azure.core.configuration", "Configuration", ImportType.AZURECORE)
14
+ file_import.add_submodule_import("azure.core.pipeline", "policies", ImportType.AZURECORE)
15
+ file_import.add_submodule_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
16
16
  if code_model.options["package_version"]:
17
- file_import.add_from_import(".._version" if async_mode else "._version", "VERSION", ImportType.LOCAL)
17
+ file_import.add_submodule_import(".._version" if async_mode else "._version", "VERSION", ImportType.LOCAL)
18
18
  for gp in global_parameters:
19
19
  file_import.merge(gp.imports())
20
20
  if code_model.options["azure_arm"]:
21
21
  policy = "AsyncARMChallengeAuthenticationPolicy" if async_mode else "ARMChallengeAuthenticationPolicy"
22
- file_import.add_from_import("azure.mgmt.core.policies", "ARMHttpLoggingPolicy", ImportType.AZURECORE)
23
- file_import.add_from_import("azure.mgmt.core.policies", policy, ImportType.AZURECORE)
22
+ file_import.add_submodule_import("azure.mgmt.core.policies", "ARMHttpLoggingPolicy", ImportType.AZURECORE)
23
+ file_import.add_submodule_import("azure.mgmt.core.policies", policy, ImportType.AZURECORE)
24
24
  return file_import
25
25
 
26
26
 
@@ -71,7 +71,7 @@ class GeneralSerializer:
71
71
  # configure imports
72
72
  file_import = FileImport()
73
73
  if self.code_model.need_request_converter:
74
- file_import.add_from_import(
74
+ file_import.add_submodule_import(
75
75
  "azure.core.pipeline.transport",
76
76
  "HttpRequest",
77
77
  ImportType.AZURECORE,
@@ -4,75 +4,73 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  from copy import deepcopy
7
- from typing import Dict, Set, Optional, List, Tuple, Union
8
- from ..models.imports import ImportType, FileImport, TypingSection
7
+ from typing import List
8
+ from ..models.imports import ImportType, FileImport, ImportModel, TypingSection
9
9
 
10
10
  def _serialize_package(
11
- package_name: str, module_list: Set[Optional[Union[str, Tuple[str, str]]]], delimiter: str
11
+ imports: List[ImportModel], delimiter: str
12
12
  ) -> str:
13
13
  buffer = []
14
- if None in module_list:
15
- buffer.append(f"import {package_name}")
16
- if module_list != {None}:
17
- buffer.append(
18
- "from {} import {}".format(
19
- package_name, ", ".join(sorted([
20
- mod if isinstance(mod, str) else f"{mod[0]} as {mod[1]}" for mod in module_list if mod is not None
21
- ]))
22
- )
23
- )
14
+ if any(i for i in imports if i.submodule_name is None):
15
+ buffer.append(f"import {imports[0].module_name}")
16
+ else:
17
+ import_str = ", ".join(sorted([
18
+ f"{i.submodule_name} as {i.alias}" if i.alias else i.submodule_name for i in imports # type: ignore
19
+ ]))
20
+ buffer.append(f"from {imports[0].module_name} import {import_str}")
24
21
  return delimiter.join(buffer)
25
22
 
26
- def _serialize_type(import_type_dict: Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]], delimiter: str) -> str:
23
+ def _serialize_import_type(imports: List[ImportModel], delimiter: str) -> str:
27
24
  """Serialize a given import type."""
28
25
  import_list = []
29
- for package_name in sorted(list(import_type_dict.keys())):
30
- module_list = import_type_dict[package_name]
31
- import_list.append(_serialize_package(package_name, module_list, delimiter))
26
+ for module_name in sorted(set(i.module_name for i in imports)):
27
+
28
+ import_list.append(_serialize_package([
29
+ i for i in imports if i.module_name == module_name
30
+ ], delimiter))
32
31
  return delimiter.join(import_list)
33
32
 
34
33
  def _get_import_clauses(
35
- imports: Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]], delimiter: str
34
+ imports: List[ImportModel], delimiter: str
36
35
  ) -> List[str]:
37
36
  import_clause = []
38
37
  for import_type in ImportType:
39
- if import_type in imports:
40
- import_clause.append(_serialize_type(imports[import_type], delimiter))
38
+ imports_with_import_type = [i for i in imports if i.import_type == import_type]
39
+ if imports_with_import_type:
40
+ import_clause.append(_serialize_import_type(imports_with_import_type, delimiter))
41
41
  return import_clause
42
42
 
43
43
 
44
44
  class FileImportSerializer:
45
45
  def __init__(self, file_import: FileImport, is_python3_file: bool, async_mode: bool = False) -> None:
46
- self._file_import = file_import
46
+ self.file_import = file_import
47
47
  self.is_python3_file = is_python3_file
48
48
  self.async_mode = async_mode
49
49
 
50
- def _switch_typing_section_key(self, new_key: TypingSection):
51
- switched_dictionary = {}
52
- switched_dictionary[new_key] = self._file_import.imports[TypingSection.CONDITIONAL]
53
- return switched_dictionary
54
-
55
- def _get_imports_dict(self, baseline_typing_section: TypingSection, add_conditional_typing: bool):
50
+ def _get_imports_list(self, baseline_typing_section: TypingSection, add_conditional_typing: bool):
56
51
  # If this is a python 3 file, our regular imports include the CONDITIONAL category
57
52
  # If this is not a python 3 file, our typing imports include the CONDITIONAL category
58
- file_import_copy = deepcopy(self._file_import)
59
- if add_conditional_typing and self._file_import.imports.get(TypingSection.CONDITIONAL):
53
+ file_import_copy = deepcopy(self.file_import)
54
+ if add_conditional_typing and any(
55
+ self.file_import.get_imports_from_section(TypingSection.CONDITIONAL)
56
+ ):
60
57
  # we switch the TypingSection key for the CONDITIONAL typing imports so we can merge
61
58
  # the imports together
62
- switched_imports_dictionary = self._switch_typing_section_key(baseline_typing_section)
63
- switched_imports = FileImport(switched_imports_dictionary)
64
- file_import_copy.merge(switched_imports)
65
- return file_import_copy.imports.get(baseline_typing_section, {})
59
+ for i in file_import_copy.imports:
60
+ if i.typing_section == TypingSection.CONDITIONAL:
61
+ i.typing_section = baseline_typing_section
62
+ return file_import_copy.get_imports_from_section(baseline_typing_section)
66
63
 
67
64
  def _add_type_checking_import(self):
68
- if (
69
- self._file_import.imports.get(TypingSection.TYPING) or
70
- (not self.is_python3_file and self._file_import.imports.get(TypingSection.CONDITIONAL))
71
- ):
72
- self._file_import.add_from_import("typing", "TYPE_CHECKING", ImportType.STDLIB)
65
+ any_typing = any(self.file_import.get_imports_from_section(TypingSection.TYPING))
66
+ conditional_and_not_py3 = not self.is_python3_file and any(
67
+ self.file_import.get_imports_from_section(TypingSection.CONDITIONAL)
68
+ )
69
+ if any_typing or conditional_and_not_py3:
70
+ self.file_import.add_submodule_import("typing", "TYPE_CHECKING", ImportType.STDLIB)
73
71
 
74
72
  def _get_typing_definitions(self) -> str:
75
- if not self._file_import.type_definitions:
73
+ if not self.file_import.type_definitions:
76
74
  return ""
77
75
  spacing = "" if self.is_python3_file else " "
78
76
  declarations: List[str] = [f"\n{spacing}T = TypeVar('T')"]
@@ -82,27 +80,27 @@ class FileImportSerializer:
82
80
  type_name,
83
81
  values[1] if self.async_mode else values[0]
84
82
  )
85
- for type_name, values in self._file_import.type_definitions.items()
83
+ for type_name, values in self.file_import.type_definitions.items()
86
84
  ])
87
85
  return "\n".join(declarations)
88
86
 
89
87
  def __str__(self) -> str:
90
88
  self._add_type_checking_import()
91
89
  regular_imports = ""
92
- regular_imports_dict = self._get_imports_dict(
90
+ regular_imports_list = self._get_imports_list(
93
91
  baseline_typing_section=TypingSection.REGULAR, add_conditional_typing=self.is_python3_file
94
92
  )
95
93
 
96
- if regular_imports_dict:
94
+ if regular_imports_list:
97
95
  regular_imports = "\n\n".join(
98
- _get_import_clauses(regular_imports_dict, "\n")
96
+ _get_import_clauses(regular_imports_list, "\n")
99
97
  )
100
98
 
101
99
  typing_imports = ""
102
- typing_imports_dict = self._get_imports_dict(
100
+ typing_imports_list = self._get_imports_list(
103
101
  baseline_typing_section=TypingSection.TYPING, add_conditional_typing=not self.is_python3_file
104
102
  )
105
- if typing_imports_dict:
103
+ if typing_imports_list:
106
104
  typing_imports += "\n\nif TYPE_CHECKING:\n # pylint: disable=unused-import,ungrouped-imports\n "
107
- typing_imports += "\n\n ".join(_get_import_clauses(typing_imports_dict, "\n "))
105
+ typing_imports += "\n\n ".join(_get_import_clauses(typing_imports_list, "\n "))
108
106
  return regular_imports + typing_imports + self._get_typing_definitions()
@@ -62,7 +62,7 @@ def _mixin_imports(mixin_operation_group: Optional[OperationGroup]) -> Tuple[Opt
62
62
  sync_mixin_imports = mixin_operation_group.imports_for_multiapi(async_mode=False)
63
63
  async_mixin_imports = mixin_operation_group.imports_for_multiapi(async_mode=True)
64
64
 
65
- return _json_serialize_imports(sync_mixin_imports.imports), _json_serialize_imports(async_mixin_imports.imports)
65
+ return _json_serialize_imports(sync_mixin_imports.to_dict()), _json_serialize_imports(async_mixin_imports.to_dict())
66
66
 
67
67
 
68
68
  class MetadataSerializer:
@@ -102,20 +102,22 @@ class MetadataSerializer:
102
102
  file_import = FileImport()
103
103
  for gp in global_parameters:
104
104
  file_import.merge(gp.imports())
105
- file_import.add_from_import("azure.profiles", "KnownProfiles", import_type=ImportType.AZURECORE)
106
- file_import.add_from_import("azure.profiles", "ProfileDefinition", import_type=ImportType.AZURECORE)
107
- file_import.add_from_import(
105
+ file_import.add_submodule_import("azure.profiles", "KnownProfiles", import_type=ImportType.AZURECORE)
106
+ file_import.add_submodule_import("azure.profiles", "ProfileDefinition", import_type=ImportType.AZURECORE)
107
+ file_import.add_submodule_import(
108
108
  "azure.profiles.multiapiclient", "MultiApiClientMixin", import_type=ImportType.AZURECORE
109
109
  )
110
- file_import.add_from_import("._configuration", f"{self.code_model.class_name}Configuration", ImportType.LOCAL)
110
+ file_import.add_submodule_import(
111
+ "._configuration", f"{self.code_model.class_name}Configuration", ImportType.LOCAL
112
+ )
111
113
  # api_version and potentially endpoint require Optional typing
112
- file_import.add_from_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
114
+ file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
113
115
  if mixin_operation_group:
114
- file_import.add_from_import(
116
+ file_import.add_submodule_import(
115
117
  "._operations_mixin", f"{self.code_model.class_name}OperationsMixin", ImportType.LOCAL
116
118
  )
117
119
  file_import.merge(self.code_model.service_client.imports_for_multiapi(async_mode=async_mode))
118
- return _json_serialize_imports(file_import.imports)
120
+ return _json_serialize_imports(file_import.to_dict())
119
121
 
120
122
  def serialize(self) -> str:
121
123
  def _is_lro(operation):
@@ -179,10 +181,10 @@ class MetadataSerializer:
179
181
  sync_client_imports=sync_client_imports,
180
182
  async_client_imports=async_client_imports,
181
183
  sync_config_imports=_json_serialize_imports(
182
- config_imports(self.code_model, self.code_model.global_parameters, async_mode=False).imports
184
+ config_imports(self.code_model, self.code_model.global_parameters, async_mode=False).to_dict()
183
185
  ),
184
186
  async_config_imports=_json_serialize_imports(
185
- config_imports(self.code_model, async_global_parameters, async_mode=True).imports
187
+ config_imports(self.code_model, async_global_parameters, async_mode=True).to_dict()
186
188
  ),
187
189
  get_async_operation_serializer=functools.partial(
188
190
  get_operation_serializer, code_model=self.code_model, async_mode=True, is_python3_file=True
@@ -52,12 +52,12 @@ class ModelBaseSerializer:
52
52
  @staticmethod
53
53
  def get_properties_to_initialize(model: ObjectSchema) -> List[Property]:
54
54
  if model.base_models:
55
- properties_to_initialize = []
56
- for uncast_base_model in model.base_models:
57
- base_model = cast(ObjectSchema, uncast_base_model)
58
- for prop in model.properties:
59
- if prop not in base_model.properties or prop.is_discriminator or prop.constant:
60
- properties_to_initialize.append(prop)
55
+ properties_to_initialize = list({
56
+ p.name: p
57
+ for bm in model.base_models
58
+ for p in model.properties
59
+ if p not in cast(ObjectSchema, bm).properties or p.is_discriminator or p.constant
60
+ }.values())
61
61
  else:
62
62
  properties_to_initialize = model.properties
63
63
  return properties_to_initialize
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "global_parameters": {
20
20
  "sync": {
21
- {% for gp in sync_global_parameters.config_method %}
21
+ {% for gp in sync_global_parameters.config_method | rejectattr("serialized_name", "equalto", "api_version") %}
22
22
  {{ gp.serialized_name | tojson }}: {
23
23
  "signature": {{ gp.method_signature(is_python3_file=False) | tojson }},
24
24
  "description": {{ gp.description | tojson }},
@@ -28,7 +28,7 @@
28
28
  {% endfor %}
29
29
  },
30
30
  "async": {
31
- {% for gp in async_global_parameters.config_method %}
31
+ {% for gp in async_global_parameters.config_method | rejectattr("serialized_name", "equalto", "api_version") %}
32
32
  {{ gp.serialized_name | tojson }}: {
33
33
  "signature": {{ (gp.method_signature(is_python3_file=True)) | tojson }},
34
34
  "description": {{ gp.description | tojson }},
@@ -42,7 +42,7 @@
42
42
  {{ gp.serialized_name | tojson }}: {{ gp.constant_declaration | tojson }}{{ "," if not loop.last else "" }}
43
43
  {% endfor %}
44
44
  },
45
- "call": {{ code_model.global_parameters.config_method | map(attribute="serialized_name") | join(', ') | tojson }},
45
+ "call": {{ code_model.global_parameters.config_method | rejectattr("serialized_name", "equalto", "api_version") | map(attribute="serialized_name") | join(', ') | tojson }},
46
46
  "service_client_specific": {
47
47
  "sync": {
48
48
  "api_version": {
@@ -20,4 +20,6 @@
20
20
  {{ op_tools.serialize(operation_serializer.call_request_builder(operation)) | indent }}
21
21
  pipeline_response = {{ keywords.await }}self._client._pipeline.run(request, {{ stream_request_parameter }}, **kwargs)
22
22
  {{ op_tools.serialize(operation_serializer.handle_response(operation)) | indent }}
23
+ {% if not code_model.options["version_tolerant"] %}
23
24
  {{ operation.python_name }}.metadata = {'url': {{ keywords.escape_str(request_builder.url) }}} # type: ignore
25
+ {% endif %}
@@ -17,4 +17,6 @@
17
17
  return {{ operation.get_pager(async_mode) }}(
18
18
  get_next, extract_data
19
19
  )
20
- {{ operation.python_name }}.metadata = {'url': '{{ request_builder.url|replace("'", "\\'") }}'} # type: ignore
20
+ {% if not code_model.options["metadata"] %}
21
+ {{ operation.python_name }}.metadata = {'url': '{{ request_builder.url|replace("'", "\\'") }}'} # type: ignore
22
+ {% endif %}
@@ -45,7 +45,7 @@ class FileImport:
45
45
  from_section, set()
46
46
  ).add(name_import)
47
47
 
48
- def add_from_import(
48
+ def add_submodule_import(
49
49
  self,
50
50
  from_section: str,
51
51
  name_import: str,
@@ -62,7 +62,7 @@ class FileImportSerializer:
62
62
  self._file_import.imports.get(TypingSection.TYPING) or
63
63
  (not self.is_python3_file and self._file_import.imports.get(TypingSection.CONDITIONAL))
64
64
  ):
65
- self._file_import.add_from_import("typing", "TYPE_CHECKING", ImportType.STDLIB)
65
+ self._file_import.add_submodule_import("typing", "TYPE_CHECKING", ImportType.STDLIB)
66
66
 
67
67
  def __str__(self) -> str:
68
68
  self._add_type_checking_import()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autorest/python",
3
- "version": "5.12.1",
3
+ "version": "5.12.5",
4
4
  "description": "The Python extension for generators in AutoRest.",
5
5
  "scripts": {
6
6
  "prepare": "node run-python3.js prepare.py",
@@ -37,6 +37,7 @@
37
37
  "prepare.py",
38
38
  "start.py",
39
39
  "venvtools.py",
40
- "run-python3.js"
40
+ "run-python3.js",
41
+ "requirements.txt"
41
42
  ]
42
43
  }
@@ -0,0 +1,14 @@
1
+ black==21.12b0
2
+ click==8.0.3
3
+ docutils==0.18.1
4
+ Jinja2==3.0.3
5
+ json-rpc==1.13.0
6
+ m2r==0.2.1
7
+ MarkupSafe==2.0.1
8
+ mistune==0.8.4
9
+ mypy-extensions==0.4.3
10
+ pathspec==0.9.0
11
+ platformdirs==2.4.0
12
+ PyYAML==6.0
13
+ tomli==1.2.2
14
+ typing-extensions==4.0.1