@autorest/python 6.10.2 → 6.11.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/autorest/codegen/models/client.py +14 -7
- package/autorest/codegen/models/combined_type.py +1 -2
- package/autorest/codegen/models/operation_group.py +59 -2
- package/autorest/codegen/models/parameter.py +1 -1
- package/autorest/codegen/models/response.py +2 -1
- package/autorest/codegen/serializers/__init__.py +10 -8
- package/autorest/codegen/serializers/client_serializer.py +1 -2
- package/autorest/codegen/serializers/operation_groups_serializer.py +7 -6
- package/autorest/codegen/serializers/utils.py +15 -1
- package/autorest/codegen/templates/model_base.py.jinja2 +5 -1
- package/autorest/codegen/templates/operation_group.py.jinja2 +7 -0
- package/autorest/preprocess/__init__.py +13 -6
- package/autorest/preprocess/python_mappings.py +1 -0
- package/package.json +1 -1
|
@@ -83,8 +83,9 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
83
83
|
self,
|
|
84
84
|
) -> List[Union[RequestBuilder, OverloadedRequestBuilder]]:
|
|
85
85
|
request_builders: List[Union[RequestBuilder, OverloadedRequestBuilder]] = []
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
|
|
87
|
+
def add_og_request_builder(og: Dict[str, Any]):
|
|
88
|
+
for operation_yaml in og["operations"]:
|
|
88
89
|
request_builder = get_request_builder(
|
|
89
90
|
operation_yaml,
|
|
90
91
|
code_model=self.code_model,
|
|
@@ -111,6 +112,14 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
111
112
|
client=self,
|
|
112
113
|
)
|
|
113
114
|
)
|
|
115
|
+
|
|
116
|
+
queue = self.yaml_data["operationGroups"].copy()
|
|
117
|
+
while queue:
|
|
118
|
+
now = queue.pop(0)
|
|
119
|
+
add_og_request_builder(now)
|
|
120
|
+
if now.get("operationGroups"):
|
|
121
|
+
queue.extend(now["operationGroups"])
|
|
122
|
+
|
|
114
123
|
return request_builders
|
|
115
124
|
|
|
116
125
|
def pipeline_class(self, async_mode: bool) -> str:
|
|
@@ -247,7 +256,7 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
247
256
|
@property
|
|
248
257
|
def has_mixin(self) -> bool:
|
|
249
258
|
"""Do we want a mixin ABC class for typing purposes?"""
|
|
250
|
-
return any(
|
|
259
|
+
return any(og for og in self.operation_groups if og.is_mixin)
|
|
251
260
|
|
|
252
261
|
@property
|
|
253
262
|
def lro_operations(self) -> List["OperationType"]:
|
|
@@ -255,8 +264,7 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
255
264
|
return [
|
|
256
265
|
operation
|
|
257
266
|
for operation_group in self.operation_groups
|
|
258
|
-
for operation in operation_group.
|
|
259
|
-
if operation.operation_type in ("lro", "lropaging")
|
|
267
|
+
for operation in operation_group.lro_operations
|
|
260
268
|
]
|
|
261
269
|
|
|
262
270
|
@property
|
|
@@ -267,8 +275,7 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
|
|
|
267
275
|
@property
|
|
268
276
|
def has_operations(self) -> bool:
|
|
269
277
|
return any(
|
|
270
|
-
|
|
271
|
-
for operation_group in self.operation_groups
|
|
278
|
+
operation_group.has_operations for operation_group in self.operation_groups
|
|
272
279
|
)
|
|
273
280
|
|
|
274
281
|
def link_lro_initial_operations(self) -> None:
|
|
@@ -65,8 +65,7 @@ class CombinedType(BaseType):
|
|
|
65
65
|
|
|
66
66
|
def type_annotation(self, **kwargs: Any) -> str:
|
|
67
67
|
if self.name:
|
|
68
|
-
|
|
69
|
-
return ret if kwargs.get("is_operation_file") else f'"{ret}"'
|
|
68
|
+
return f'"_types.{self.name}"'
|
|
70
69
|
return self.type_definition(**kwargs)
|
|
71
70
|
|
|
72
71
|
def type_definition(self, **kwargs: Any) -> str:
|
|
@@ -11,6 +11,8 @@ from .base import BaseModel
|
|
|
11
11
|
from .operation import get_operation
|
|
12
12
|
from .imports import FileImport, ImportType, TypingSection
|
|
13
13
|
from .utils import add_to_pylint_disable, NAME_LENGTH_LIMIT
|
|
14
|
+
from .lro_operation import LROOperation
|
|
15
|
+
from .lro_paging_operation import LROPagingOperation
|
|
14
16
|
|
|
15
17
|
if TYPE_CHECKING:
|
|
16
18
|
from .code_model import CodeModel
|
|
@@ -32,9 +34,17 @@ class OperationGroup(BaseModel):
|
|
|
32
34
|
super().__init__(yaml_data, code_model)
|
|
33
35
|
self.client = client
|
|
34
36
|
self.class_name: str = yaml_data["className"]
|
|
37
|
+
self.identify_name: str = yaml_data["identifyName"]
|
|
35
38
|
self.property_name: str = yaml_data["propertyName"]
|
|
36
39
|
self.operations = operations
|
|
37
40
|
self.api_versions = api_versions
|
|
41
|
+
self.operation_groups: List[OperationGroup] = []
|
|
42
|
+
if self.code_model.options["show_operations"]:
|
|
43
|
+
self.operation_groups = [
|
|
44
|
+
OperationGroup.from_yaml(op_group, code_model, client)
|
|
45
|
+
for op_group in self.yaml_data.get("operationGroups", [])
|
|
46
|
+
]
|
|
47
|
+
self.link_lro_initial_operations()
|
|
38
48
|
|
|
39
49
|
@property
|
|
40
50
|
def has_abstract_operations(self) -> bool:
|
|
@@ -43,7 +53,7 @@ class OperationGroup(BaseModel):
|
|
|
43
53
|
@property
|
|
44
54
|
def base_class(self) -> str:
|
|
45
55
|
base_classes: List[str] = []
|
|
46
|
-
if self.is_mixin
|
|
56
|
+
if self.is_mixin:
|
|
47
57
|
base_classes.append(f"{self.client.name}MixinABC")
|
|
48
58
|
return ", ".join(base_classes)
|
|
49
59
|
|
|
@@ -71,6 +81,8 @@ class OperationGroup(BaseModel):
|
|
|
71
81
|
retval = add_to_pylint_disable(retval, "too-many-public-methods")
|
|
72
82
|
if len(self.class_name) > NAME_LENGTH_LIMIT:
|
|
73
83
|
retval = add_to_pylint_disable(retval, "name-too-long")
|
|
84
|
+
if len(self.operation_groups) > 6:
|
|
85
|
+
retval = add_to_pylint_disable(retval, "too-many-instance-attributes")
|
|
74
86
|
return retval
|
|
75
87
|
|
|
76
88
|
@property
|
|
@@ -88,6 +100,13 @@ class OperationGroup(BaseModel):
|
|
|
88
100
|
file_import.merge(
|
|
89
101
|
operation.imports(async_mode, relative_path=relative_path)
|
|
90
102
|
)
|
|
103
|
+
if not self.code_model.options["combine_operation_files"]:
|
|
104
|
+
for og in self.operation_groups:
|
|
105
|
+
file_import.add_submodule_import(
|
|
106
|
+
".",
|
|
107
|
+
og.class_name,
|
|
108
|
+
ImportType.LOCAL,
|
|
109
|
+
)
|
|
91
110
|
# for multiapi
|
|
92
111
|
if (
|
|
93
112
|
(self.code_model.public_model_types)
|
|
@@ -124,7 +143,45 @@ class OperationGroup(BaseModel):
|
|
|
124
143
|
@property
|
|
125
144
|
def is_mixin(self) -> bool:
|
|
126
145
|
"""The operation group with no name is the direct client methods."""
|
|
127
|
-
return self.
|
|
146
|
+
return self.identify_name == ""
|
|
147
|
+
|
|
148
|
+
def link_lro_initial_operations(self) -> None:
|
|
149
|
+
"""Link each LRO operation to its initial operation"""
|
|
150
|
+
for operation_group in self.operation_groups:
|
|
151
|
+
for operation in operation_group.operations:
|
|
152
|
+
if isinstance(operation, (LROOperation, LROPagingOperation)):
|
|
153
|
+
operation.initial_operation = self.lookup_operation(
|
|
154
|
+
id(operation.yaml_data["initialOperation"])
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
def lookup_operation(self, operation_id: int) -> "OperationType":
|
|
158
|
+
try:
|
|
159
|
+
return next(
|
|
160
|
+
o
|
|
161
|
+
for og in self.operation_groups
|
|
162
|
+
for o in og.operations
|
|
163
|
+
if id(o.yaml_data) == operation_id
|
|
164
|
+
)
|
|
165
|
+
except StopIteration as exc:
|
|
166
|
+
raise KeyError(f"No operation with id {operation_id} found.") from exc
|
|
167
|
+
|
|
168
|
+
@property
|
|
169
|
+
def lro_operations(self) -> List["OperationType"]:
|
|
170
|
+
return [
|
|
171
|
+
operation
|
|
172
|
+
for operation in self.operations
|
|
173
|
+
if operation.operation_type in ("lro", "lropaging")
|
|
174
|
+
] + [
|
|
175
|
+
operation
|
|
176
|
+
for operation_group in self.operation_groups
|
|
177
|
+
for operation in operation_group.lro_operations
|
|
178
|
+
]
|
|
179
|
+
|
|
180
|
+
@property
|
|
181
|
+
def has_operations(self) -> bool:
|
|
182
|
+
return any(
|
|
183
|
+
operation_group.has_operations for operation_group in self.operation_groups
|
|
184
|
+
) or bool(self.operations)
|
|
128
185
|
|
|
129
186
|
@classmethod
|
|
130
187
|
def from_yaml(
|
|
@@ -120,8 +120,9 @@ class Response(BaseModel):
|
|
|
120
120
|
if self.nullable:
|
|
121
121
|
file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB)
|
|
122
122
|
if isinstance(self.type, CombinedType) and self.type.name:
|
|
123
|
+
async_mode = kwargs.get("async_mode", False)
|
|
123
124
|
file_import.add_submodule_import(
|
|
124
|
-
"..",
|
|
125
|
+
"..." if async_mode else "..",
|
|
125
126
|
"_types",
|
|
126
127
|
ImportType.LOCAL,
|
|
127
128
|
TypingSection.TYPING,
|
|
@@ -34,6 +34,7 @@ from .utils import (
|
|
|
34
34
|
extract_sample_name,
|
|
35
35
|
get_namespace_from_package_name,
|
|
36
36
|
get_namespace_config,
|
|
37
|
+
get_all_operation_groups_recursively,
|
|
37
38
|
)
|
|
38
39
|
|
|
39
40
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -415,14 +416,15 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
415
416
|
clients=clients,
|
|
416
417
|
)
|
|
417
418
|
else:
|
|
418
|
-
for
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
419
|
+
for operation_group in get_all_operation_groups_recursively(
|
|
420
|
+
self.code_model.clients
|
|
421
|
+
):
|
|
422
|
+
self._serialize_and_write_operations_file(
|
|
423
|
+
env=env,
|
|
424
|
+
namespace_path=namespace_path,
|
|
425
|
+
operation_group=operation_group,
|
|
426
|
+
clients=clients,
|
|
427
|
+
)
|
|
426
428
|
|
|
427
429
|
def _serialize_and_write_version_file(
|
|
428
430
|
self,
|
|
@@ -48,9 +48,8 @@ class ClientSerializer:
|
|
|
48
48
|
@property
|
|
49
49
|
def class_definition(self) -> str:
|
|
50
50
|
class_name = self.client.name
|
|
51
|
-
has_mixin_og = any(og for og in self.client.operation_groups if og.is_mixin)
|
|
52
51
|
base_class = ""
|
|
53
|
-
if
|
|
52
|
+
if self.client.has_mixin:
|
|
54
53
|
base_class = f"{class_name}OperationsMixin"
|
|
55
54
|
pylint_disable = self.client.pylint_disable
|
|
56
55
|
if base_class:
|
|
@@ -7,6 +7,7 @@ from typing import Optional, List, Union
|
|
|
7
7
|
import functools
|
|
8
8
|
from jinja2 import Environment
|
|
9
9
|
|
|
10
|
+
from .utils import get_all_operation_groups_recursively
|
|
10
11
|
from ..models import (
|
|
11
12
|
CodeModel,
|
|
12
13
|
OperationGroup,
|
|
@@ -45,18 +46,18 @@ class OperationGroupsSerializer(BaseSerializer):
|
|
|
45
46
|
for client in self.clients
|
|
46
47
|
for r in client.request_builders
|
|
47
48
|
if r.client.name == operation_group.client.name
|
|
48
|
-
and r.group_name == operation_group.
|
|
49
|
+
and r.group_name == operation_group.identify_name
|
|
49
50
|
and not r.is_overload
|
|
50
51
|
and not r.abstract
|
|
51
52
|
and not r.is_lro # lro has already initial builder
|
|
52
53
|
]
|
|
53
54
|
|
|
54
55
|
def serialize(self) -> str:
|
|
55
|
-
|
|
56
|
-
[self.operation_group]
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
if self.operation_group:
|
|
57
|
+
operation_groups = [self.operation_group]
|
|
58
|
+
else:
|
|
59
|
+
operation_groups = get_all_operation_groups_recursively(self.clients)
|
|
60
|
+
|
|
60
61
|
imports = FileImport(self.code_model)
|
|
61
62
|
for operation_group in operation_groups:
|
|
62
63
|
imports.merge(
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
-
from typing import Optional
|
|
6
|
+
from typing import Optional, List
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
|
|
9
|
+
from ..models import Client, OperationGroup
|
|
10
|
+
|
|
9
11
|
|
|
10
12
|
def method_signature_and_response_type_annotation_template(
|
|
11
13
|
*,
|
|
@@ -30,3 +32,15 @@ def get_namespace_config(namespace: str, multiapi: bool) -> str:
|
|
|
30
32
|
|
|
31
33
|
def get_namespace_from_package_name(package_name: Optional[str]) -> str:
|
|
32
34
|
return (package_name or "").replace("-", ".")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def get_all_operation_groups_recursively(clients: List[Client]) -> List[OperationGroup]:
|
|
38
|
+
operation_groups = []
|
|
39
|
+
queue = []
|
|
40
|
+
for client in clients:
|
|
41
|
+
queue.extend(client.operation_groups)
|
|
42
|
+
while queue:
|
|
43
|
+
operation_groups.append(queue.pop(0))
|
|
44
|
+
if operation_groups[-1].operation_groups:
|
|
45
|
+
queue.extend(operation_groups[-1].operation_groups)
|
|
46
|
+
return operation_groups
|
|
@@ -726,7 +726,11 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915,
|
|
|
726
726
|
):
|
|
727
727
|
if obj is None:
|
|
728
728
|
return obj
|
|
729
|
-
|
|
729
|
+
try:
|
|
730
|
+
return _deserialize_with_callable(deserializer, obj)
|
|
731
|
+
except Exception:
|
|
732
|
+
pass
|
|
733
|
+
return obj
|
|
730
734
|
|
|
731
735
|
if get_deserializer(annotation, rf):
|
|
732
736
|
return functools.partial(_deserialize_default, get_deserializer(annotation, rf))
|
|
@@ -38,6 +38,13 @@ class {{ operation_group.class_name }}: {{ operation_group.pylint_disable }}
|
|
|
38
38
|
{% if code_model.options["multiapi"] %}
|
|
39
39
|
self._api_version = input_args.pop(0) if input_args else kwargs.pop("api_version")
|
|
40
40
|
{% endif %}
|
|
41
|
+
|
|
42
|
+
{% for og in operation_group.operation_groups %}
|
|
43
|
+
self.{{ og.property_name }} = {{ og.class_name }}(
|
|
44
|
+
self._client, self._config, self._serialize, self._deserialize{{ ", self._api_version" if code_model.options["multiapi"] else "" }}
|
|
45
|
+
)
|
|
46
|
+
{% endfor %}
|
|
47
|
+
|
|
41
48
|
{{ check_abstract_methods() }}
|
|
42
49
|
{% elif operation_group.has_abstract_operations %}
|
|
43
50
|
|
|
@@ -124,11 +124,9 @@ def update_description(
|
|
|
124
124
|
return description
|
|
125
125
|
|
|
126
126
|
|
|
127
|
-
def update_operation_group_class_name(
|
|
128
|
-
yaml_data: Dict[str, Any], class_name: str
|
|
129
|
-
) -> str:
|
|
127
|
+
def update_operation_group_class_name(prefix: str, class_name: str) -> str:
|
|
130
128
|
if class_name == "":
|
|
131
|
-
return
|
|
129
|
+
return prefix + "OperationsMixin"
|
|
132
130
|
if class_name == "Operations":
|
|
133
131
|
return "Operations"
|
|
134
132
|
return class_name + "Operations"
|
|
@@ -511,7 +509,13 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
511
509
|
) -> None:
|
|
512
510
|
operation_groups_yaml_data = client["operationGroups"]
|
|
513
511
|
for operation_group in operation_groups_yaml_data:
|
|
514
|
-
operation_group["
|
|
512
|
+
operation_group["identifyName"] = self.pad_reserved_words(
|
|
513
|
+
operation_group.get("name", operation_group["propertyName"]),
|
|
514
|
+
PadType.OPERATION_GROUP,
|
|
515
|
+
)
|
|
516
|
+
operation_group["identifyName"] = to_snake_case(
|
|
517
|
+
operation_group["identifyName"]
|
|
518
|
+
)
|
|
515
519
|
operation_group["propertyName"] = self.pad_reserved_words(
|
|
516
520
|
operation_group["propertyName"], PadType.OPERATION_GROUP
|
|
517
521
|
)
|
|
@@ -519,11 +523,14 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
519
523
|
operation_group["propertyName"]
|
|
520
524
|
)
|
|
521
525
|
operation_group["className"] = update_operation_group_class_name(
|
|
522
|
-
client, operation_group["className"]
|
|
526
|
+
client["name"], operation_group["className"]
|
|
523
527
|
)
|
|
524
528
|
for operation in operation_group["operations"]:
|
|
525
529
|
self.get_operation_updater(operation)(code_model, operation)
|
|
526
530
|
|
|
531
|
+
if operation_group.get("operationGroups"):
|
|
532
|
+
self.update_operation_groups(code_model, operation_group)
|
|
533
|
+
|
|
527
534
|
def update_yaml(self, yaml_data: Dict[str, Any]) -> None:
|
|
528
535
|
"""Convert in place the YAML str."""
|
|
529
536
|
self.update_types(yaml_data["types"])
|