@autorest/python 5.12.4 → 5.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ChangeLog.md +173 -109
- package/autorest/black/__init__.py +7 -1
- package/autorest/codegen/__init__.py +12 -2
- package/autorest/codegen/models/__init__.py +2 -1
- package/autorest/codegen/models/client.py +22 -19
- package/autorest/codegen/models/constant_schema.py +0 -4
- package/autorest/codegen/models/credential_schema.py +3 -3
- package/autorest/codegen/models/dictionary_schema.py +1 -1
- package/autorest/codegen/models/enum_schema.py +2 -2
- package/autorest/codegen/models/imports.py +90 -50
- package/autorest/codegen/models/list_schema.py +1 -1
- package/autorest/codegen/models/lro_operation.py +15 -9
- package/autorest/codegen/models/object_schema.py +2 -2
- package/autorest/codegen/models/operation.py +39 -30
- package/autorest/codegen/models/operation_group.py +5 -14
- package/autorest/codegen/models/paging_operation.py +9 -9
- package/autorest/codegen/models/parameter.py +37 -11
- package/autorest/codegen/models/parameter_list.py +11 -4
- package/autorest/codegen/models/primitive_schemas.py +2 -2
- package/autorest/codegen/models/property.py +1 -1
- package/autorest/codegen/models/request_builder.py +7 -6
- package/autorest/codegen/models/request_builder_parameter.py +5 -0
- package/autorest/codegen/models/request_builder_parameter_list.py +1 -0
- package/autorest/codegen/models/schema_response.py +1 -1
- package/autorest/codegen/serializers/__init__.py +75 -71
- package/autorest/codegen/serializers/builder_serializer.py +68 -37
- package/autorest/codegen/serializers/client_serializer.py +14 -3
- package/autorest/codegen/serializers/general_serializer.py +7 -7
- package/autorest/codegen/serializers/import_serializer.py +44 -46
- package/autorest/codegen/serializers/metadata_serializer.py +12 -10
- package/autorest/codegen/serializers/utils.py +5 -1
- package/autorest/codegen/templates/config.py.jinja2 +2 -7
- package/autorest/codegen/templates/lro_operation.py.jinja2 +3 -1
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +2 -0
- package/autorest/codegen/templates/operation.py.jinja2 +8 -2
- package/autorest/codegen/templates/operation_group.py.jinja2 +2 -1
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -0
- package/autorest/codegen/templates/operation_tools.jinja2 +3 -2
- package/autorest/codegen/templates/paging_operation.py.jinja2 +3 -1
- package/autorest/codegen/templates/request_builder.py.jinja2 +2 -7
- package/autorest/codegen/templates/service_client.py.jinja2 +1 -1
- package/autorest/multiapi/models/imports.py +1 -1
- package/autorest/multiapi/serializers/import_serializer.py +1 -1
- package/autorest/namer/name_converter.py +1 -1
- package/package.json +2 -2
- package/run-python3.js +1 -7
- package/venvtools.py +2 -2
|
@@ -178,7 +178,7 @@ class EnumSchema(BaseSchema):
|
|
|
178
178
|
|
|
179
179
|
def imports(self) -> FileImport:
|
|
180
180
|
file_import = FileImport()
|
|
181
|
-
file_import.
|
|
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.
|
|
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,
|
|
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:
|
|
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
|
-
|
|
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
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
|
78
|
+
def add_submodule_import(
|
|
58
79
|
self,
|
|
59
|
-
|
|
60
|
-
|
|
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.
|
|
68
|
-
|
|
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
|
-
|
|
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.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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.
|
|
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
|
|
94
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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,14 @@ 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.
|
|
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.
|
|
176
|
-
if self.
|
|
177
|
-
file_import.
|
|
177
|
+
file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
178
|
+
if self.code_model.options["tracing"] and self.want_tracing:
|
|
179
|
+
file_import.add_submodule_import(
|
|
180
|
+
f"azure.core.tracing.decorator{'_async' if async_mode else ''}",
|
|
181
|
+
f"distributed_trace{'_async' if async_mode else ''}",
|
|
182
|
+
ImportType.AZURECORE,
|
|
183
|
+
)
|
|
178
184
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
|
@@ -159,11 +159,12 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
|
|
|
159
159
|
if response.has_body:
|
|
160
160
|
file_import.merge(cast(BaseSchema, response.schema).imports())
|
|
161
161
|
|
|
162
|
-
|
|
163
|
-
|
|
162
|
+
response_types = [r.operation_type_annotation for r in self.responses if r.has_body]
|
|
163
|
+
if len(set(response_types)) > 1:
|
|
164
|
+
file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
164
165
|
|
|
165
166
|
if self.is_stream_response:
|
|
166
|
-
file_import.
|
|
167
|
+
file_import.add_submodule_import("typing", "IO", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
167
168
|
return file_import
|
|
168
169
|
|
|
169
170
|
|
|
@@ -174,42 +175,37 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
|
|
|
174
175
|
file_import = self._imports_shared(async_mode)
|
|
175
176
|
|
|
176
177
|
# Exceptions
|
|
177
|
-
file_import.
|
|
178
|
+
file_import.add_submodule_import("azure.core.exceptions", "map_error", ImportType.AZURECORE)
|
|
178
179
|
if self.code_model.options["azure_arm"]:
|
|
179
|
-
file_import.
|
|
180
|
-
file_import.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
file_import.
|
|
184
|
-
file_import.
|
|
185
|
-
file_import.
|
|
186
|
-
file_import.
|
|
187
|
-
file_import.
|
|
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)
|
|
180
|
+
file_import.add_submodule_import("azure.mgmt.core.exceptions", "ARMErrorFormat", ImportType.AZURECORE)
|
|
181
|
+
file_import.add_submodule_import("azure.core.exceptions", "HttpResponseError", ImportType.AZURECORE)
|
|
182
|
+
|
|
183
|
+
file_import.add_submodule_import("typing", "Callable", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
184
|
+
file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
185
|
+
file_import.add_submodule_import("typing", "Dict", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
186
|
+
file_import.add_submodule_import("typing", "TypeVar", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
187
|
+
file_import.add_submodule_import("azure.core.pipeline", "PipelineResponse", ImportType.AZURECORE)
|
|
188
|
+
file_import.add_submodule_import("azure.core.rest", "HttpRequest", ImportType.AZURECORE)
|
|
191
189
|
if async_mode:
|
|
192
|
-
file_import.
|
|
190
|
+
file_import.add_submodule_import("azure.core.pipeline.transport", "AsyncHttpResponse", ImportType.AZURECORE)
|
|
193
191
|
else:
|
|
194
|
-
file_import.
|
|
192
|
+
file_import.add_submodule_import("azure.core.pipeline.transport", "HttpResponse", ImportType.AZURECORE)
|
|
195
193
|
|
|
196
|
-
|
|
197
|
-
# FIXME: Replace with "the YAML contains deprecated:true"
|
|
198
|
-
if True: # pylint: disable=using-constant-test
|
|
194
|
+
if self.deprecated:
|
|
199
195
|
file_import.add_import("warnings", ImportType.STDLIB)
|
|
200
196
|
|
|
201
197
|
if self.code_model.options["builders_visibility"] != "embedded":
|
|
202
198
|
builder_group_name = self.request_builder.builder_group_name
|
|
203
199
|
rest_import_path = "..." if async_mode else ".."
|
|
204
200
|
if builder_group_name:
|
|
205
|
-
file_import.
|
|
201
|
+
file_import.add_submodule_import(
|
|
206
202
|
f"{rest_import_path}{self.code_model.rest_layer_name}",
|
|
207
|
-
|
|
203
|
+
builder_group_name,
|
|
208
204
|
import_type=ImportType.LOCAL,
|
|
209
205
|
alias=f"rest_{builder_group_name}"
|
|
210
206
|
)
|
|
211
207
|
else:
|
|
212
|
-
file_import.
|
|
208
|
+
file_import.add_submodule_import(
|
|
213
209
|
rest_import_path,
|
|
214
210
|
self.code_model.rest_layer_name,
|
|
215
211
|
import_type=ImportType.LOCAL,
|
|
@@ -219,7 +215,7 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
|
|
|
219
215
|
file_import.merge(self.request_builder.imports())
|
|
220
216
|
if self.code_model.need_request_converter:
|
|
221
217
|
relative_path = "..." if async_mode else ".."
|
|
222
|
-
file_import.
|
|
218
|
+
file_import.add_submodule_import(
|
|
223
219
|
f"{relative_path}_vendor", "_convert_request", ImportType.LOCAL
|
|
224
220
|
)
|
|
225
221
|
if self.code_model.options["version_tolerant"] and (
|
|
@@ -227,6 +223,12 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
|
|
|
227
223
|
any(r for r in self.responses if r.has_body)
|
|
228
224
|
):
|
|
229
225
|
file_import.define_mypy_type("JSONType", "Any")
|
|
226
|
+
if self.code_model.options["tracing"] and self.want_tracing:
|
|
227
|
+
file_import.add_submodule_import(
|
|
228
|
+
f"azure.core.tracing.decorator{'_async' if async_mode else ''}",
|
|
229
|
+
f"distributed_trace{'_async' if async_mode else ''}",
|
|
230
|
+
ImportType.AZURECORE,
|
|
231
|
+
)
|
|
230
232
|
return file_import
|
|
231
233
|
|
|
232
234
|
def _get_body_param_from_body_kwarg(self, body_kwarg: Parameter) -> Parameter:
|
|
@@ -301,6 +303,15 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
|
|
|
301
303
|
parameters, multiple_content_type_parameters = create_parameters(
|
|
302
304
|
yaml_data, code_model, parameter_creator
|
|
303
305
|
)
|
|
306
|
+
parameter_list = parameter_list_creator(code_model, parameters, schema_requests)
|
|
307
|
+
multiple_content_type_parameter_list = parameter_list_creator(
|
|
308
|
+
code_model, multiple_content_type_parameters, schema_requests
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
if len(parameter_list.content_types) > 1:
|
|
312
|
+
for p in parameter_list.parameters:
|
|
313
|
+
if p.rest_api_name == "Content-Type":
|
|
314
|
+
p.is_keyword_only = True
|
|
304
315
|
|
|
305
316
|
return cls(
|
|
306
317
|
code_model=code_model,
|
|
@@ -308,10 +319,8 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
|
|
|
308
319
|
name=name,
|
|
309
320
|
description=yaml_data["language"]["python"]["description"],
|
|
310
321
|
api_versions=set(value_dict["version"] for value_dict in yaml_data["apiVersions"]),
|
|
311
|
-
parameters=
|
|
312
|
-
multiple_content_type_parameters=
|
|
313
|
-
code_model, multiple_content_type_parameters, schema_requests
|
|
314
|
-
),
|
|
322
|
+
parameters=parameter_list,
|
|
323
|
+
multiple_content_type_parameters=multiple_content_type_parameter_list,
|
|
315
324
|
schema_requests=schema_requests,
|
|
316
325
|
summary=yaml_data["language"]["python"].get("summary"),
|
|
317
326
|
responses=[SchemaResponse.from_yaml(yaml) for yaml in yaml_data.get("responses", [])],
|
|
@@ -58,23 +58,14 @@ class OperationGroup(BaseModel):
|
|
|
58
58
|
|
|
59
59
|
def imports(self, async_mode: bool) -> FileImport:
|
|
60
60
|
file_import = FileImport()
|
|
61
|
-
file_import.
|
|
62
|
-
file_import.
|
|
63
|
-
file_import.
|
|
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
|
-
if self.code_model.options["tracing"]:
|
|
67
|
-
if async_mode:
|
|
68
|
-
file_import.add_from_import(
|
|
69
|
-
"azure.core.tracing.decorator_async", "distributed_trace_async", ImportType.AZURECORE,
|
|
70
|
-
)
|
|
71
|
-
else:
|
|
72
|
-
file_import.add_from_import(
|
|
73
|
-
"azure.core.tracing.decorator", "distributed_trace", ImportType.AZURECORE,
|
|
74
|
-
)
|
|
75
66
|
local_path = "..." if async_mode else ".."
|
|
76
67
|
if self.code_model.has_schemas and self.code_model.options["models_mode"]:
|
|
77
|
-
file_import.
|
|
68
|
+
file_import.add_submodule_import(local_path, "models", ImportType.LOCAL, alias="_models")
|
|
78
69
|
if self.code_model.options["builders_visibility"] == "embedded" and async_mode:
|
|
79
70
|
if not self.code_model.options["combine_operation_files"]:
|
|
80
71
|
operation_group_name = "" if self.is_empty_operation_group else self.name
|
|
@@ -88,7 +79,7 @@ class OperationGroup(BaseModel):
|
|
|
88
79
|
python3_only = self.code_model.options["python3_only"]
|
|
89
80
|
typed_sync_operation_file = self.code_model.options["add_python3_operation_files"]
|
|
90
81
|
suffix = "_py3" if typed_sync_operation_file and not python3_only else ""
|
|
91
|
-
file_import.
|
|
82
|
+
file_import.add_submodule_import(
|
|
92
83
|
f"...{self.code_model.operations_folder_name}.{self.filename}{suffix}",
|
|
93
84
|
request_builder.name,
|
|
94
85
|
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.
|
|
128
|
+
file_import.add_submodule_import("typing", "AsyncIterable", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
129
129
|
else:
|
|
130
|
-
file_import.
|
|
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,26 +141,26 @@ 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.
|
|
144
|
+
file_import.add_submodule_import(pager_import_path, pager, ImportType.AZURECORE, TypingSection.CONDITIONAL)
|
|
145
145
|
|
|
146
146
|
return file_import
|
|
147
147
|
|
|
148
148
|
def imports(self, async_mode: bool) -> FileImport:
|
|
149
149
|
file_import = super(PagingOperation, self).imports(async_mode)
|
|
150
|
+
# operation adds an import for distributed_trace_async, we don't want it
|
|
151
|
+
file_import.imports = [i for i in file_import.imports if not i.submodule_name == "distributed_trace_async"]
|
|
150
152
|
|
|
151
153
|
pager_import_path = ".".join(self.get_pager_path(async_mode).split(".")[:-1])
|
|
152
154
|
pager = self.get_pager(async_mode)
|
|
153
155
|
|
|
154
|
-
file_import.
|
|
156
|
+
file_import.add_submodule_import(pager_import_path, pager, ImportType.AZURECORE)
|
|
155
157
|
|
|
156
158
|
if async_mode:
|
|
157
|
-
file_import.
|
|
159
|
+
file_import.add_submodule_import("azure.core.async_paging", "AsyncList", ImportType.AZURECORE)
|
|
158
160
|
|
|
159
|
-
if self.code_model.options["tracing"]:
|
|
160
|
-
file_import.
|
|
161
|
+
if self.code_model.options["tracing"] and self.want_tracing:
|
|
162
|
+
file_import.add_submodule_import(
|
|
161
163
|
"azure.core.tracing.decorator", "distributed_trace", ImportType.AZURECORE,
|
|
162
164
|
)
|
|
163
|
-
if not self.code_model.options["models_mode"]:
|
|
164
|
-
file_import.add_from_import("json", "loads", ImportType.STDLIB, alias="_loads")
|
|
165
165
|
|
|
166
166
|
return file_import
|
|
@@ -68,7 +68,7 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
68
68
|
grouped_by: Optional["Parameter"] = None,
|
|
69
69
|
original_parameter: Optional["Parameter"] = None,
|
|
70
70
|
client_default_value: Optional[Any] = None,
|
|
71
|
-
keyword_only: bool =
|
|
71
|
+
keyword_only: Optional[bool] = None,
|
|
72
72
|
content_types: Optional[List[str]] = None,
|
|
73
73
|
) -> None:
|
|
74
74
|
super().__init__(yaml_data)
|
|
@@ -98,6 +98,8 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
98
98
|
self.content_types = content_types or []
|
|
99
99
|
self.body_kwargs: List[Parameter] = []
|
|
100
100
|
self.is_body_kwarg = False
|
|
101
|
+
self.need_import = True
|
|
102
|
+
self.is_kwarg = (self.rest_api_name == "Content-Type" or (self.constant and self.rest_api_name != "Accept"))
|
|
101
103
|
|
|
102
104
|
def __hash__(self) -> int:
|
|
103
105
|
return hash(self.serialized_name)
|
|
@@ -110,6 +112,14 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
110
112
|
if description:
|
|
111
113
|
description += " "
|
|
112
114
|
description += f"{self.schema.extra_description_information}"
|
|
115
|
+
if isinstance(self.schema, ConstantSchema) and not self.constant:
|
|
116
|
+
if description:
|
|
117
|
+
description += " "
|
|
118
|
+
description += f"Possible values are {self.schema.get_declaration(self.schema.value)} or {None}."
|
|
119
|
+
if self.has_default_value and not any(
|
|
120
|
+
l for l in ["default value is", "default is"] if l in description.lower()
|
|
121
|
+
):
|
|
122
|
+
description += f" Default value is {self.default_value_declaration}."
|
|
113
123
|
if self.constant:
|
|
114
124
|
description += " Note that overriding this default value may result in unsupported behavior."
|
|
115
125
|
return description
|
|
@@ -231,7 +241,12 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
231
241
|
default_value_declaration = "None"
|
|
232
242
|
else:
|
|
233
243
|
if isinstance(self.schema, ConstantSchema):
|
|
234
|
-
|
|
244
|
+
if (self.required or
|
|
245
|
+
self.is_content_type or
|
|
246
|
+
not self.code_model.options["default_optional_constants_to_none"]):
|
|
247
|
+
default_value = self.schema.get_declaration(self.schema.value)
|
|
248
|
+
else:
|
|
249
|
+
default_value = None
|
|
235
250
|
default_value_declaration = default_value
|
|
236
251
|
else:
|
|
237
252
|
default_value = self.schema.default_value
|
|
@@ -297,22 +312,26 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
297
312
|
origin_name = f"self._config.{self.serialized_name}"
|
|
298
313
|
return origin_name
|
|
299
314
|
|
|
300
|
-
@property
|
|
301
|
-
def is_kwarg(self) -> bool:
|
|
302
|
-
# this means "am I in **kwargs?"
|
|
303
|
-
return self.rest_api_name == "Content-Type" or (self.constant and self.rest_api_name != "Accept")
|
|
304
|
-
|
|
305
315
|
@property
|
|
306
316
|
def is_keyword_only(self) -> bool:
|
|
307
317
|
# this means in async mode, I am documented like def hello(positional_1, *, me!)
|
|
308
|
-
return self._keyword_only
|
|
318
|
+
return self._keyword_only or False
|
|
319
|
+
|
|
320
|
+
@is_keyword_only.setter
|
|
321
|
+
def is_keyword_only(self, val: bool) -> None:
|
|
322
|
+
self._keyword_only = val
|
|
323
|
+
self.is_kwarg = False
|
|
309
324
|
|
|
310
325
|
@property
|
|
311
326
|
def is_hidden(self) -> bool:
|
|
312
|
-
return self.serialized_name in _HIDDEN_KWARGS or (
|
|
327
|
+
return self.serialized_name in _HIDDEN_KWARGS and self.is_kwarg or (
|
|
313
328
|
self.yaml_data["implementation"] == "Client" and self.constant
|
|
314
329
|
)
|
|
315
330
|
|
|
331
|
+
@property
|
|
332
|
+
def is_content_type(self) -> bool:
|
|
333
|
+
return self.rest_api_name == "Content-Type" and self.location == ParameterLocation.Header
|
|
334
|
+
|
|
316
335
|
@property
|
|
317
336
|
def is_positional(self) -> bool:
|
|
318
337
|
return self.in_method_signature and not (self.is_keyword_only or self.is_kwarg)
|
|
@@ -354,9 +373,9 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
354
373
|
def imports(self) -> FileImport:
|
|
355
374
|
file_import = self.schema.imports()
|
|
356
375
|
if not self.required:
|
|
357
|
-
file_import.
|
|
376
|
+
file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
358
377
|
if self.has_multiple_content_types or self._is_io_json:
|
|
359
|
-
file_import.
|
|
378
|
+
file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
|
|
360
379
|
|
|
361
380
|
return file_import
|
|
362
381
|
|
|
@@ -364,6 +383,8 @@ class ParameterOnlyPathAndBodyPositional(Parameter):
|
|
|
364
383
|
|
|
365
384
|
@property
|
|
366
385
|
def is_keyword_only(self) -> bool:
|
|
386
|
+
if self._keyword_only is not None:
|
|
387
|
+
return self._keyword_only
|
|
367
388
|
return self.in_method_signature and not (
|
|
368
389
|
self.is_hidden or
|
|
369
390
|
self.location == ParameterLocation.Path or
|
|
@@ -372,6 +393,11 @@ class ParameterOnlyPathAndBodyPositional(Parameter):
|
|
|
372
393
|
self.is_kwarg
|
|
373
394
|
)
|
|
374
395
|
|
|
396
|
+
@is_keyword_only.setter
|
|
397
|
+
def is_keyword_only(self, val: bool) -> None:
|
|
398
|
+
self._keyword_only = val
|
|
399
|
+
self.is_kwarg = False
|
|
400
|
+
|
|
375
401
|
def get_parameter(code_model):
|
|
376
402
|
if code_model.options["only_path_and_body_params_positional"]:
|
|
377
403
|
return ParameterOnlyPathAndBodyPositional
|