@autorest/python 5.15.0 → 5.16.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 +20 -0
- package/autorest/__init__.py +1 -2
- package/autorest/black/__init__.py +12 -5
- package/autorest/codegen/__init__.py +145 -73
- package/autorest/codegen/models/__init__.py +29 -18
- package/autorest/codegen/models/base_builder.py +48 -11
- package/autorest/codegen/models/base_model.py +6 -4
- package/autorest/codegen/models/base_schema.py +19 -18
- package/autorest/codegen/models/client.py +65 -21
- package/autorest/codegen/models/code_model.py +107 -61
- package/autorest/codegen/models/constant_schema.py +25 -13
- package/autorest/codegen/models/credential_model.py +23 -15
- package/autorest/codegen/models/credential_schema.py +18 -14
- package/autorest/codegen/models/credential_schema_policy.py +11 -15
- package/autorest/codegen/models/dictionary_schema.py +20 -17
- package/autorest/codegen/models/enum_schema.py +35 -25
- package/autorest/codegen/models/imports.py +70 -41
- package/autorest/codegen/models/list_schema.py +25 -13
- package/autorest/codegen/models/lro_operation.py +58 -22
- package/autorest/codegen/models/lro_paging_operation.py +2 -3
- package/autorest/codegen/models/object_schema.py +99 -49
- package/autorest/codegen/models/operation.py +236 -117
- package/autorest/codegen/models/operation_group.py +64 -34
- package/autorest/codegen/models/paging_operation.py +45 -18
- package/autorest/codegen/models/parameter.py +151 -83
- package/autorest/codegen/models/parameter_list.py +183 -162
- package/autorest/codegen/models/primitive_schemas.py +84 -55
- package/autorest/codegen/models/property.py +44 -26
- package/autorest/codegen/models/request_builder.py +65 -30
- package/autorest/codegen/models/request_builder_parameter.py +47 -23
- package/autorest/codegen/models/request_builder_parameter_list.py +77 -108
- package/autorest/codegen/models/schema_request.py +16 -6
- package/autorest/codegen/models/schema_response.py +18 -13
- package/autorest/codegen/models/utils.py +5 -2
- package/autorest/codegen/serializers/__init__.py +182 -91
- package/autorest/codegen/serializers/builder_serializer.py +667 -331
- package/autorest/codegen/serializers/client_serializer.py +98 -37
- package/autorest/codegen/serializers/general_serializer.py +61 -26
- package/autorest/codegen/serializers/import_serializer.py +93 -31
- package/autorest/codegen/serializers/metadata_serializer.py +73 -24
- package/autorest/codegen/serializers/model_base_serializer.py +35 -15
- package/autorest/codegen/serializers/model_generic_serializer.py +1 -4
- package/autorest/codegen/serializers/model_init_serializer.py +5 -1
- package/autorest/codegen/serializers/model_python3_serializer.py +7 -6
- package/autorest/codegen/serializers/operation_groups_serializer.py +20 -9
- package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
- package/autorest/codegen/serializers/patch_serializer.py +4 -1
- package/autorest/codegen/serializers/{rest_serializer.py → request_builders_serializer.py} +29 -12
- package/autorest/codegen/serializers/utils.py +35 -21
- package/autorest/codegen/templates/init.py.jinja2 +2 -2
- package/autorest/codegen/templates/lro_operation.py.jinja2 +5 -7
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +5 -7
- package/autorest/codegen/templates/metadata.json.jinja2 +7 -6
- package/autorest/codegen/templates/operation.py.jinja2 +7 -9
- package/autorest/codegen/templates/operation_group.py.jinja2 +2 -8
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
- package/autorest/codegen/templates/request_builder.py.jinja2 +18 -11
- package/autorest/jsonrpc/__init__.py +7 -12
- package/autorest/jsonrpc/localapi.py +4 -3
- package/autorest/jsonrpc/server.py +13 -6
- package/autorest/jsonrpc/stdstream.py +13 -6
- package/autorest/m2r/__init__.py +5 -8
- package/autorest/multiapi/__init__.py +24 -14
- package/autorest/multiapi/models/client.py +21 -11
- package/autorest/multiapi/models/code_model.py +23 -10
- package/autorest/multiapi/models/config.py +4 -1
- package/autorest/multiapi/models/constant_global_parameter.py +1 -0
- package/autorest/multiapi/models/global_parameter.py +2 -1
- package/autorest/multiapi/models/global_parameters.py +14 -8
- package/autorest/multiapi/models/imports.py +24 -17
- package/autorest/multiapi/models/mixin_operation.py +5 -5
- package/autorest/multiapi/models/operation_group.py +2 -1
- package/autorest/multiapi/models/operation_mixin_group.py +21 -10
- package/autorest/multiapi/serializers/__init__.py +18 -23
- package/autorest/multiapi/serializers/import_serializer.py +47 -17
- package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
- package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +1 -1
- package/autorest/multiapi/utils.py +3 -3
- package/autorest/namer/__init__.py +2 -4
- package/autorest/namer/name_converter.py +200 -103
- package/autorest/namer/python_mappings.py +10 -22
- package/package.json +2 -2
- package/run-python3.js +2 -3
- package/venvtools.py +1 -1
- package/autorest/codegen/models/rest.py +0 -42
|
@@ -4,19 +4,23 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
import logging
|
|
7
|
-
from typing import Dict, List, Any, Set
|
|
7
|
+
from typing import Dict, List, Any, Set, TYPE_CHECKING
|
|
8
8
|
|
|
9
9
|
from .base_model import BaseModel
|
|
10
10
|
from .operation import Operation
|
|
11
11
|
from .lro_operation import LROOperation
|
|
12
12
|
from .paging_operation import PagingOperation
|
|
13
13
|
from .lro_paging_operation import LROPagingOperation
|
|
14
|
-
from .imports import FileImport, ImportType
|
|
14
|
+
from .imports import FileImport, ImportType, TypingSection
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from .code_model import CodeModel
|
|
15
18
|
|
|
16
19
|
|
|
17
20
|
_LOGGER = logging.getLogger(__name__)
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
|
|
23
|
+
def _get_operation(yaml_data: Dict[str, Any], code_model: "CodeModel") -> Operation:
|
|
20
24
|
lro_operation = yaml_data.get("extensions", {}).get("x-ms-long-running-operation")
|
|
21
25
|
paging_operation = yaml_data.get("extensions", {}).get("x-ms-pageable")
|
|
22
26
|
operation_schema = Operation
|
|
@@ -31,106 +35,132 @@ def _get_operation(code_model, yaml_data: Dict[str, Any]) -> Operation:
|
|
|
31
35
|
|
|
32
36
|
|
|
33
37
|
class OperationGroup(BaseModel):
|
|
34
|
-
"""Represent an operation group.
|
|
38
|
+
"""Represent an operation group."""
|
|
35
39
|
|
|
36
|
-
"""
|
|
37
40
|
def __init__(
|
|
38
41
|
self,
|
|
39
|
-
code_model,
|
|
40
42
|
yaml_data: Dict[str, Any],
|
|
43
|
+
code_model: "CodeModel",
|
|
41
44
|
name: str,
|
|
42
45
|
class_name: str,
|
|
43
46
|
operations: List[Operation],
|
|
44
|
-
api_versions: Set[str]
|
|
47
|
+
api_versions: Set[str],
|
|
45
48
|
) -> None:
|
|
46
|
-
super().__init__(yaml_data)
|
|
47
|
-
self.code_model = code_model
|
|
49
|
+
super().__init__(yaml_data, code_model)
|
|
48
50
|
self.name = name
|
|
49
51
|
self.class_name = class_name
|
|
50
52
|
self.operations = operations
|
|
51
53
|
self.api_versions = api_versions
|
|
52
54
|
|
|
55
|
+
@property
|
|
56
|
+
def has_abstract_operations(self) -> bool:
|
|
57
|
+
return any(o for o in self.operations if o.abstract)
|
|
58
|
+
|
|
59
|
+
def base_class(self, async_mode: bool) -> str:
|
|
60
|
+
base_classes: List[str] = []
|
|
61
|
+
if self.is_empty_operation_group and self.code_model.need_mixin_abc:
|
|
62
|
+
base_classes.append("MixinABC")
|
|
63
|
+
if not (async_mode or self.code_model.options["python3_only"]):
|
|
64
|
+
base_classes.append("object")
|
|
65
|
+
if self.has_abstract_operations:
|
|
66
|
+
base_classes.append("abc.ABC")
|
|
67
|
+
return ", ".join(base_classes)
|
|
68
|
+
|
|
53
69
|
def imports_for_multiapi(self, async_mode: bool) -> FileImport:
|
|
54
70
|
file_import = FileImport()
|
|
55
71
|
for operation in self.operations:
|
|
56
72
|
file_import.merge(operation.imports_for_multiapi(async_mode))
|
|
57
|
-
file_import.add_submodule_import(
|
|
73
|
+
file_import.add_submodule_import(
|
|
74
|
+
".." if async_mode else ".", "models", ImportType.LOCAL, alias="_models"
|
|
75
|
+
)
|
|
58
76
|
return file_import
|
|
59
77
|
|
|
60
78
|
def imports(self, async_mode: bool, is_python3_file: bool) -> FileImport:
|
|
61
79
|
file_import = FileImport()
|
|
62
|
-
|
|
63
|
-
file_import.add_submodule_import("azure.core.exceptions", "ResourceNotFoundError", ImportType.AZURECORE)
|
|
64
|
-
file_import.add_submodule_import("azure.core.exceptions", "ResourceExistsError", ImportType.AZURECORE)
|
|
80
|
+
|
|
65
81
|
for operation in self.operations:
|
|
66
82
|
file_import.merge(operation.imports(async_mode, is_python3_file))
|
|
67
83
|
local_path = "..." if async_mode else ".."
|
|
68
84
|
if self.code_model.has_schemas and self.code_model.options["models_mode"]:
|
|
69
|
-
file_import.add_submodule_import(
|
|
85
|
+
file_import.add_submodule_import(
|
|
86
|
+
local_path, "models", ImportType.LOCAL, alias="_models"
|
|
87
|
+
)
|
|
70
88
|
if self.code_model.options["builders_visibility"] == "embedded" and async_mode:
|
|
71
89
|
if not self.code_model.options["combine_operation_files"]:
|
|
72
|
-
operation_group_name =
|
|
90
|
+
operation_group_name = (
|
|
91
|
+
"" if self.is_empty_operation_group else self.name
|
|
92
|
+
)
|
|
73
93
|
operation_group_builders = [
|
|
74
|
-
r
|
|
94
|
+
r
|
|
95
|
+
for r in self.code_model.request_builders
|
|
75
96
|
if r.operation_group_name == operation_group_name
|
|
76
97
|
]
|
|
77
98
|
else:
|
|
78
|
-
operation_group_builders = self.code_model.
|
|
99
|
+
operation_group_builders = self.code_model.request_builders
|
|
79
100
|
for request_builder in operation_group_builders:
|
|
101
|
+
if request_builder.abstract:
|
|
102
|
+
continue
|
|
80
103
|
python3_only = self.code_model.options["python3_only"]
|
|
81
|
-
typed_sync_operation_file = self.code_model.options[
|
|
82
|
-
|
|
104
|
+
typed_sync_operation_file = self.code_model.options[
|
|
105
|
+
"add_python3_operation_files"
|
|
106
|
+
]
|
|
107
|
+
suffix = (
|
|
108
|
+
"_py3" if typed_sync_operation_file and not python3_only else ""
|
|
109
|
+
)
|
|
83
110
|
file_import.add_submodule_import(
|
|
84
111
|
f"...{self.code_model.operations_folder_name}.{self.filename}{suffix}",
|
|
85
112
|
request_builder.name,
|
|
86
|
-
import_type=ImportType.LOCAL
|
|
113
|
+
import_type=ImportType.LOCAL,
|
|
87
114
|
)
|
|
88
115
|
if self.code_model.need_mixin_abc:
|
|
89
|
-
file_import.add_submodule_import(
|
|
90
|
-
|
|
91
|
-
|
|
116
|
+
file_import.add_submodule_import(".._vendor", "MixinABC", ImportType.LOCAL)
|
|
117
|
+
file_import.add_submodule_import(
|
|
118
|
+
"typing", "TypeVar", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
119
|
+
)
|
|
120
|
+
file_import.define_mypy_type("T", "TypeVar('T')")
|
|
92
121
|
type_value = "Optional[Callable[[PipelineResponse[HttpRequest, {}HttpResponse], T, Dict[str, Any]], Any]]"
|
|
93
122
|
file_import.define_mypy_type(
|
|
94
|
-
"ClsType",
|
|
95
|
-
type_value.format(""),
|
|
96
|
-
type_value.format("Async")
|
|
123
|
+
"ClsType", type_value.format(""), type_value.format("Async")
|
|
97
124
|
)
|
|
98
125
|
return file_import
|
|
99
126
|
|
|
100
|
-
|
|
101
127
|
@property
|
|
102
128
|
def filename(self) -> str:
|
|
103
129
|
basename = self.name
|
|
104
130
|
if self.is_empty_operation_group:
|
|
105
131
|
basename = self.code_model.module_name
|
|
106
132
|
|
|
107
|
-
if
|
|
133
|
+
if (
|
|
134
|
+
basename == "operations"
|
|
135
|
+
or self.code_model.options["combine_operation_files"]
|
|
136
|
+
):
|
|
108
137
|
return f"_operations"
|
|
109
138
|
return f"_{basename}_operations"
|
|
110
139
|
|
|
111
140
|
@property
|
|
112
141
|
def is_empty_operation_group(self) -> bool:
|
|
113
|
-
"""The operation group with no name is the direct client methods.
|
|
114
|
-
"""
|
|
142
|
+
"""The operation group with no name is the direct client methods."""
|
|
115
143
|
return not self.yaml_data["language"]["default"]["name"]
|
|
116
144
|
|
|
117
145
|
@classmethod
|
|
118
|
-
def from_yaml(
|
|
146
|
+
def from_yaml(
|
|
147
|
+
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
148
|
+
) -> "OperationGroup":
|
|
119
149
|
name = yaml_data["language"]["python"]["name"]
|
|
120
150
|
_LOGGER.debug("Parsing %s operation group", name)
|
|
121
151
|
|
|
122
152
|
operations = []
|
|
123
153
|
api_versions: Set[str] = set()
|
|
124
154
|
for operation_yaml in yaml_data["operations"]:
|
|
125
|
-
operation = _get_operation(
|
|
155
|
+
operation = _get_operation(operation_yaml, code_model)
|
|
126
156
|
operations.append(operation)
|
|
127
157
|
api_versions.update(operation.api_versions)
|
|
128
158
|
|
|
129
159
|
return cls(
|
|
130
|
-
code_model=code_model,
|
|
131
160
|
yaml_data=yaml_data,
|
|
161
|
+
code_model=code_model,
|
|
132
162
|
name=name,
|
|
133
163
|
class_name=yaml_data["language"]["python"]["className"],
|
|
134
164
|
operations=operations,
|
|
135
|
-
api_versions=api_versions
|
|
165
|
+
api_versions=api_versions,
|
|
136
166
|
)
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
import logging
|
|
7
|
-
from typing import cast, Dict, List, Any, Optional, Set
|
|
7
|
+
from typing import cast, Dict, List, Any, Optional, Set, TYPE_CHECKING
|
|
8
8
|
|
|
9
9
|
from .operation import Operation
|
|
10
10
|
from .schema_response import SchemaResponse
|
|
@@ -14,14 +14,18 @@ from .object_schema import ObjectSchema
|
|
|
14
14
|
from .schema_request import SchemaRequest
|
|
15
15
|
from .parameter_list import ParameterList
|
|
16
16
|
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from .code_model import CodeModel
|
|
19
|
+
|
|
17
20
|
_LOGGER = logging.getLogger(__name__)
|
|
18
21
|
|
|
19
22
|
|
|
20
23
|
class PagingOperation(Operation):
|
|
21
24
|
def __init__(
|
|
22
25
|
self,
|
|
23
|
-
code_model,
|
|
24
26
|
yaml_data: Dict[str, Any],
|
|
27
|
+
code_model: "CodeModel",
|
|
28
|
+
request_builder: RequestBuilder,
|
|
25
29
|
name: str,
|
|
26
30
|
description: str,
|
|
27
31
|
api_versions: Set[str],
|
|
@@ -34,11 +38,13 @@ class PagingOperation(Operation):
|
|
|
34
38
|
want_description_docstring: bool = True,
|
|
35
39
|
want_tracing: bool = True,
|
|
36
40
|
*,
|
|
37
|
-
|
|
41
|
+
abstract: bool = False,
|
|
42
|
+
override_success_response_to_200: bool = False,
|
|
38
43
|
) -> None:
|
|
39
|
-
super(
|
|
40
|
-
code_model,
|
|
44
|
+
super().__init__(
|
|
41
45
|
yaml_data,
|
|
46
|
+
code_model,
|
|
47
|
+
request_builder,
|
|
42
48
|
name,
|
|
43
49
|
description,
|
|
44
50
|
api_versions,
|
|
@@ -49,11 +55,16 @@ class PagingOperation(Operation):
|
|
|
49
55
|
responses,
|
|
50
56
|
exceptions,
|
|
51
57
|
want_description_docstring,
|
|
52
|
-
want_tracing
|
|
58
|
+
want_tracing=want_tracing,
|
|
59
|
+
abstract=abstract,
|
|
53
60
|
)
|
|
54
61
|
self._item_name: str = yaml_data["extensions"]["x-ms-pageable"].get("itemName")
|
|
55
|
-
self._next_link_name: str = yaml_data["extensions"]["x-ms-pageable"].get(
|
|
56
|
-
|
|
62
|
+
self._next_link_name: str = yaml_data["extensions"]["x-ms-pageable"].get(
|
|
63
|
+
"nextLinkName"
|
|
64
|
+
)
|
|
65
|
+
self.operation_name: str = yaml_data["extensions"]["x-ms-pageable"].get(
|
|
66
|
+
"operationName"
|
|
67
|
+
)
|
|
57
68
|
self.next_operation: Optional[Operation] = None
|
|
58
69
|
self.override_success_response_to_200 = override_success_response_to_200
|
|
59
70
|
|
|
@@ -61,7 +72,8 @@ class PagingOperation(Operation):
|
|
|
61
72
|
response = self.responses[0]
|
|
62
73
|
if not isinstance(response.schema, ObjectSchema):
|
|
63
74
|
raise ValueError(
|
|
64
|
-
"The response of a paging operation must be of type "
|
|
75
|
+
"The response of a paging operation must be of type "
|
|
76
|
+
+ f"ObjectSchema but {response.schema} is not"
|
|
65
77
|
)
|
|
66
78
|
return response
|
|
67
79
|
|
|
@@ -84,7 +96,8 @@ class PagingOperation(Operation):
|
|
|
84
96
|
item_name = self._item_name or "value"
|
|
85
97
|
try:
|
|
86
98
|
return (
|
|
87
|
-
self._find_python_name(item_name, "itemName")
|
|
99
|
+
self._find_python_name(item_name, "itemName")
|
|
100
|
+
if code_model.options["models_mode"]
|
|
88
101
|
else item_name
|
|
89
102
|
)
|
|
90
103
|
except ValueError:
|
|
@@ -125,12 +138,16 @@ class PagingOperation(Operation):
|
|
|
125
138
|
def _imports_shared(self, async_mode: bool) -> FileImport:
|
|
126
139
|
file_import = super()._imports_shared(async_mode)
|
|
127
140
|
if async_mode:
|
|
128
|
-
file_import.add_submodule_import(
|
|
141
|
+
file_import.add_submodule_import(
|
|
142
|
+
"typing", "AsyncIterable", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
143
|
+
)
|
|
129
144
|
else:
|
|
130
|
-
file_import.add_submodule_import(
|
|
145
|
+
file_import.add_submodule_import(
|
|
146
|
+
"typing", "Iterable", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
147
|
+
)
|
|
131
148
|
if (
|
|
132
|
-
self.next_request_builder
|
|
133
|
-
self.code_model.options["builders_visibility"] == "embedded"
|
|
149
|
+
self.next_request_builder
|
|
150
|
+
and self.code_model.options["builders_visibility"] == "embedded"
|
|
134
151
|
and not async_mode
|
|
135
152
|
):
|
|
136
153
|
file_import.merge(self.next_request_builder.imports())
|
|
@@ -141,14 +158,20 @@ class PagingOperation(Operation):
|
|
|
141
158
|
pager_import_path = ".".join(self.get_pager_path(async_mode).split(".")[:-1])
|
|
142
159
|
pager = self.get_pager(async_mode)
|
|
143
160
|
|
|
144
|
-
file_import.add_submodule_import(
|
|
161
|
+
file_import.add_submodule_import(
|
|
162
|
+
pager_import_path, pager, ImportType.AZURECORE, TypingSection.CONDITIONAL
|
|
163
|
+
)
|
|
145
164
|
|
|
146
165
|
return file_import
|
|
147
166
|
|
|
148
167
|
def imports(self, async_mode: bool, is_python3_file: bool) -> FileImport:
|
|
149
168
|
file_import = self._imports_base(async_mode, is_python3_file)
|
|
150
169
|
# operation adds an import for distributed_trace_async, we don't want it
|
|
151
|
-
file_import.imports = [
|
|
170
|
+
file_import.imports = [
|
|
171
|
+
i
|
|
172
|
+
for i in file_import.imports
|
|
173
|
+
if not i.submodule_name == "distributed_trace_async"
|
|
174
|
+
]
|
|
152
175
|
|
|
153
176
|
pager_import_path = ".".join(self.get_pager_path(async_mode).split(".")[:-1])
|
|
154
177
|
pager = self.get_pager(async_mode)
|
|
@@ -156,11 +179,15 @@ class PagingOperation(Operation):
|
|
|
156
179
|
file_import.add_submodule_import(pager_import_path, pager, ImportType.AZURECORE)
|
|
157
180
|
|
|
158
181
|
if async_mode:
|
|
159
|
-
file_import.add_submodule_import(
|
|
182
|
+
file_import.add_submodule_import(
|
|
183
|
+
"azure.core.async_paging", "AsyncList", ImportType.AZURECORE
|
|
184
|
+
)
|
|
160
185
|
|
|
161
186
|
if self.code_model.options["tracing"] and self.want_tracing:
|
|
162
187
|
file_import.add_submodule_import(
|
|
163
|
-
"azure.core.tracing.decorator",
|
|
188
|
+
"azure.core.tracing.decorator",
|
|
189
|
+
"distributed_trace",
|
|
190
|
+
ImportType.AZURECORE,
|
|
164
191
|
)
|
|
165
192
|
|
|
166
193
|
return file_import
|