@autorest/python 5.13.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 +67 -0
- package/autorest/__init__.py +1 -2
- package/autorest/black/__init__.py +12 -5
- package/autorest/codegen/__init__.py +239 -105
- 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 +21 -24
- package/autorest/codegen/models/client.py +70 -20
- package/autorest/codegen/models/code_model.py +144 -129
- package/autorest/codegen/models/constant_schema.py +32 -16
- package/autorest/codegen/models/credential_model.py +55 -0
- package/autorest/codegen/models/credential_schema.py +21 -16
- package/autorest/codegen/models/credential_schema_policy.py +11 -15
- package/autorest/codegen/models/dictionary_schema.py +27 -24
- package/autorest/codegen/models/enum_schema.py +41 -62
- package/autorest/codegen/models/imports.py +72 -41
- package/autorest/codegen/models/list_schema.py +40 -18
- package/autorest/codegen/models/lro_operation.py +61 -25
- package/autorest/codegen/models/lro_paging_operation.py +5 -6
- package/autorest/codegen/models/object_schema.py +113 -59
- package/autorest/codegen/models/operation.py +251 -111
- package/autorest/codegen/models/operation_group.py +67 -32
- package/autorest/codegen/models/paging_operation.py +48 -21
- package/autorest/codegen/models/parameter.py +182 -90
- package/autorest/codegen/models/parameter_list.py +184 -163
- package/autorest/codegen/models/primitive_schemas.py +89 -70
- package/autorest/codegen/models/property.py +49 -31
- package/autorest/codegen/models/request_builder.py +67 -32
- package/autorest/codegen/models/request_builder_parameter.py +54 -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 +35 -17
- package/autorest/codegen/models/utils.py +24 -1
- package/autorest/codegen/serializers/__init__.py +273 -89
- package/autorest/codegen/serializers/builder_serializer.py +711 -333
- package/autorest/codegen/serializers/client_serializer.py +114 -43
- package/autorest/codegen/serializers/general_serializer.py +84 -25
- 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 +42 -14
- 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 +9 -8
- package/autorest/codegen/serializers/operation_groups_serializer.py +20 -8
- package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
- package/autorest/codegen/serializers/patch_serializer.py +14 -2
- package/autorest/codegen/serializers/{rest_serializer.py → request_builders_serializer.py} +29 -12
- package/autorest/codegen/serializers/utils.py +60 -21
- package/autorest/codegen/templates/CHANGELOG.md.jinja2 +6 -0
- package/autorest/codegen/templates/LICENSE.jinja2 +21 -0
- package/autorest/codegen/templates/MANIFEST.in.jinja2 +7 -0
- package/autorest/codegen/templates/README.md.jinja2 +105 -0
- package/autorest/codegen/templates/config.py.jinja2 +4 -4
- package/autorest/codegen/templates/dev_requirements.txt.jinja2 +10 -0
- package/autorest/codegen/templates/enum.py.jinja2 +1 -1
- package/autorest/codegen/templates/enum_container.py.jinja2 +0 -1
- package/autorest/codegen/templates/init.py.jinja2 +9 -6
- package/autorest/codegen/templates/keywords.jinja2 +14 -1
- 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 +10 -9
- package/autorest/codegen/templates/model.py.jinja2 +1 -6
- package/autorest/codegen/templates/model_init.py.jinja2 +7 -4
- package/autorest/codegen/templates/operation.py.jinja2 +8 -11
- package/autorest/codegen/templates/operation_group.py.jinja2 +15 -18
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -2
- package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -0
- package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
- package/autorest/codegen/templates/patch.py.jinja2 +18 -29
- package/autorest/codegen/templates/request_builder.py.jinja2 +19 -14
- package/autorest/codegen/templates/setup.py.jinja2 +79 -20
- package/autorest/codegen/templates/vendor.py.jinja2 +12 -2
- 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 +35 -18
- 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 -15
- 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 +3 -3
- package/run-python3.js +2 -3
- package/venvtools.py +1 -1
- package/autorest/codegen/models/rest.py +0 -42
|
@@ -3,23 +3,26 @@
|
|
|
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 Any, Dict, Optional, Union
|
|
6
|
+
from typing import Any, Dict, Optional, Union, TYPE_CHECKING
|
|
7
7
|
from .base_schema import BaseSchema
|
|
8
8
|
from .imports import FileImport, ImportType, TypingSection
|
|
9
9
|
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from .code_model import CodeModel
|
|
12
|
+
|
|
10
13
|
|
|
11
14
|
class ListSchema(BaseSchema):
|
|
12
15
|
def __init__(
|
|
13
16
|
self,
|
|
14
|
-
namespace: str,
|
|
15
17
|
yaml_data: Dict[str, Any],
|
|
18
|
+
code_model: "CodeModel",
|
|
16
19
|
element_type: BaseSchema,
|
|
17
20
|
*,
|
|
18
21
|
max_items: Optional[int] = None,
|
|
19
22
|
min_items: Optional[int] = None,
|
|
20
23
|
unique_items: Optional[int] = None,
|
|
21
24
|
) -> None:
|
|
22
|
-
super(
|
|
25
|
+
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
23
26
|
self.element_type = element_type
|
|
24
27
|
self.max_items = max_items
|
|
25
28
|
self.min_items = min_items
|
|
@@ -29,20 +32,26 @@ class ListSchema(BaseSchema):
|
|
|
29
32
|
def serialization_type(self) -> str:
|
|
30
33
|
return f"[{self.element_type.serialization_type}]"
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return f"List[{self.element_type.
|
|
35
|
+
def type_annotation(self, *, is_operation_file: bool = False) -> str:
|
|
36
|
+
if self.element_type.type_annotation() == "ET.Element":
|
|
37
|
+
# this means we're version tolerant XML, we just return the XML element
|
|
38
|
+
return self.element_type.type_annotation(
|
|
39
|
+
is_operation_file=is_operation_file
|
|
40
|
+
)
|
|
41
|
+
return f"List[{self.element_type.type_annotation(is_operation_file=is_operation_file)}]"
|
|
39
42
|
|
|
40
43
|
@property
|
|
41
44
|
def docstring_type(self) -> str:
|
|
45
|
+
if self.element_type.docstring_type == "ET.Element":
|
|
46
|
+
# this means we're version tolerant XML, we just return the XML element
|
|
47
|
+
return self.element_type.docstring_type
|
|
42
48
|
return f"list[{self.element_type.docstring_type}]"
|
|
43
49
|
|
|
44
50
|
@property
|
|
45
51
|
def docstring_text(self) -> str:
|
|
52
|
+
if self.element_type.docstring_text == "XML Element":
|
|
53
|
+
# this means we're version tolerant XML, we just return the XML element
|
|
54
|
+
return self.element_type.docstring_text
|
|
46
55
|
return f"list of {self.element_type.docstring_text}"
|
|
47
56
|
|
|
48
57
|
@property
|
|
@@ -59,14 +68,14 @@ class ListSchema(BaseSchema):
|
|
|
59
68
|
|
|
60
69
|
@property
|
|
61
70
|
def has_xml_serialization_ctxt(self) -> bool:
|
|
62
|
-
return
|
|
71
|
+
return (
|
|
72
|
+
super().has_xml_serialization_ctxt
|
|
73
|
+
or self.element_type.has_xml_serialization_ctxt
|
|
74
|
+
)
|
|
63
75
|
|
|
64
76
|
def get_json_template_representation(self, **kwargs: Any) -> Any:
|
|
65
77
|
return [self.element_type.get_json_template_representation(**kwargs)]
|
|
66
78
|
|
|
67
|
-
def get_files_and_data_template_representation(self, **kwargs: Any) -> Any:
|
|
68
|
-
return [self.element_type.get_files_and_data_template_representation(**kwargs)]
|
|
69
|
-
|
|
70
79
|
def xml_serialization_ctxt(self) -> Optional[str]:
|
|
71
80
|
attrs_list = []
|
|
72
81
|
base_xml_map = super().xml_serialization_ctxt()
|
|
@@ -89,17 +98,19 @@ class ListSchema(BaseSchema):
|
|
|
89
98
|
return ", ".join(attrs_list)
|
|
90
99
|
|
|
91
100
|
@classmethod
|
|
92
|
-
def from_yaml(
|
|
101
|
+
def from_yaml(
|
|
102
|
+
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
103
|
+
) -> "ListSchema":
|
|
93
104
|
# TODO: for items, if the type is a primitive is it listed in type instead of $ref?
|
|
94
105
|
element_schema = yaml_data["elementType"]
|
|
95
106
|
|
|
96
107
|
from . import build_schema # pylint: disable=import-outside-toplevel
|
|
97
108
|
|
|
98
|
-
element_type = build_schema(yaml_data=element_schema,
|
|
109
|
+
element_type = build_schema(yaml_data=element_schema, code_model=code_model)
|
|
99
110
|
|
|
100
111
|
return cls(
|
|
101
|
-
namespace=namespace,
|
|
102
112
|
yaml_data=yaml_data,
|
|
113
|
+
code_model=code_model,
|
|
103
114
|
element_type=element_type,
|
|
104
115
|
max_items=yaml_data.get("maxItems"),
|
|
105
116
|
min_items=yaml_data.get("minItems"),
|
|
@@ -108,6 +119,17 @@ class ListSchema(BaseSchema):
|
|
|
108
119
|
|
|
109
120
|
def imports(self) -> FileImport:
|
|
110
121
|
file_import = FileImport()
|
|
111
|
-
|
|
122
|
+
if (
|
|
123
|
+
not self.element_type.type_annotation(is_operation_file=True)
|
|
124
|
+
== "ET.Element"
|
|
125
|
+
):
|
|
126
|
+
file_import.add_submodule_import(
|
|
127
|
+
"typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
128
|
+
)
|
|
112
129
|
file_import.merge(self.element_type.imports())
|
|
113
130
|
return file_import
|
|
131
|
+
|
|
132
|
+
def model_file_imports(self) -> FileImport:
|
|
133
|
+
file_import = self.imports()
|
|
134
|
+
file_import.merge(self.element_type.model_file_imports())
|
|
135
|
+
return file_import
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
import logging
|
|
7
|
-
from typing import Dict, List, Any, Optional, Set, cast
|
|
7
|
+
from typing import Dict, List, Any, Optional, Set, cast, TYPE_CHECKING
|
|
8
8
|
from .imports import FileImport
|
|
9
9
|
from .operation import Operation
|
|
10
10
|
from .parameter_list import ParameterList
|
|
@@ -12,6 +12,10 @@ from .schema_response import SchemaResponse
|
|
|
12
12
|
from .imports import ImportType, TypingSection
|
|
13
13
|
from .base_schema import BaseSchema
|
|
14
14
|
from .schema_request import SchemaRequest
|
|
15
|
+
from .request_builder import RequestBuilder
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from .code_model import CodeModel
|
|
15
19
|
|
|
16
20
|
_LOGGER = logging.getLogger(__name__)
|
|
17
21
|
|
|
@@ -19,8 +23,9 @@ _LOGGER = logging.getLogger(__name__)
|
|
|
19
23
|
class LROOperation(Operation):
|
|
20
24
|
def __init__(
|
|
21
25
|
self,
|
|
22
|
-
code_model,
|
|
23
26
|
yaml_data: Dict[str, Any],
|
|
27
|
+
code_model: "CodeModel",
|
|
28
|
+
request_builder: RequestBuilder,
|
|
24
29
|
name: str,
|
|
25
30
|
description: str,
|
|
26
31
|
api_versions: Set[str],
|
|
@@ -31,11 +36,14 @@ class LROOperation(Operation):
|
|
|
31
36
|
responses: Optional[List[SchemaResponse]] = None,
|
|
32
37
|
exceptions: Optional[List[SchemaResponse]] = None,
|
|
33
38
|
want_description_docstring: bool = True,
|
|
34
|
-
want_tracing: bool = True
|
|
39
|
+
want_tracing: bool = True,
|
|
40
|
+
*,
|
|
41
|
+
abstract: bool = False,
|
|
35
42
|
) -> None:
|
|
36
|
-
super(
|
|
37
|
-
code_model,
|
|
43
|
+
super().__init__(
|
|
38
44
|
yaml_data,
|
|
45
|
+
code_model,
|
|
46
|
+
request_builder,
|
|
39
47
|
name,
|
|
40
48
|
description,
|
|
41
49
|
api_versions,
|
|
@@ -46,9 +54,12 @@ class LROOperation(Operation):
|
|
|
46
54
|
responses,
|
|
47
55
|
exceptions,
|
|
48
56
|
want_description_docstring,
|
|
49
|
-
want_tracing,
|
|
57
|
+
want_tracing=want_tracing,
|
|
58
|
+
abstract=abstract,
|
|
59
|
+
)
|
|
60
|
+
self.lro_options = yaml_data.get("extensions", {}).get(
|
|
61
|
+
"x-ms-long-running-operation-options", {}
|
|
50
62
|
)
|
|
51
|
-
self.lro_options = yaml_data.get("extensions", {}).get("x-ms-long-running-operation-options", {})
|
|
52
63
|
self.name = "begin_" + self.name
|
|
53
64
|
|
|
54
65
|
@property
|
|
@@ -68,12 +79,14 @@ class LROOperation(Operation):
|
|
|
68
79
|
schema_types = {r.schema for r in responses_with_bodies}
|
|
69
80
|
response_schema = cast(BaseSchema, response.schema).serialization_type
|
|
70
81
|
_LOGGER.warning(
|
|
71
|
-
"Multiple schema types in responses: %s. Choosing: %s",
|
|
82
|
+
"Multiple schema types in responses: %s. Choosing: %s",
|
|
83
|
+
schema_types,
|
|
84
|
+
response_schema,
|
|
72
85
|
)
|
|
73
86
|
except IndexError:
|
|
74
87
|
raise ValueError(
|
|
75
|
-
f"Your swagger is invalid because you have multiple response schemas for LRO"
|
|
76
|
-
f" method {self.python_name} and none of them have a 200 status code."
|
|
88
|
+
f"Your swagger is invalid because you have multiple response schemas for LRO"
|
|
89
|
+
+ f" method {self.python_name} and none of them have a 200 status code."
|
|
77
90
|
)
|
|
78
91
|
|
|
79
92
|
elif num_response_schemas:
|
|
@@ -83,8 +96,9 @@ class LROOperation(Operation):
|
|
|
83
96
|
@property
|
|
84
97
|
def initial_operation(self) -> Operation:
|
|
85
98
|
operation = Operation(
|
|
86
|
-
self.code_model,
|
|
87
99
|
yaml_data={},
|
|
100
|
+
code_model=self.code_model,
|
|
101
|
+
request_builder=self.code_model.lookup_request_builder(id(self.yaml_data)),
|
|
88
102
|
name=self.name[5:] + "_initial",
|
|
89
103
|
description="",
|
|
90
104
|
api_versions=self.api_versions,
|
|
@@ -119,10 +133,14 @@ class LROOperation(Operation):
|
|
|
119
133
|
return self.get_poller_path(async_mode).split(".")[-1]
|
|
120
134
|
|
|
121
135
|
def get_default_polling_method_path(self, async_mode: bool, azure_arm: bool) -> str:
|
|
122
|
-
return self._get_lro_extension(
|
|
136
|
+
return self._get_lro_extension(
|
|
137
|
+
"default-polling-method", async_mode, azure_arm=azure_arm
|
|
138
|
+
)
|
|
123
139
|
|
|
124
140
|
def get_default_polling_method(self, async_mode: bool, azure_arm: bool) -> str:
|
|
125
|
-
return self.get_default_polling_method_path(async_mode, azure_arm).split(".")[
|
|
141
|
+
return self.get_default_polling_method_path(async_mode, azure_arm).split(".")[
|
|
142
|
+
-1
|
|
143
|
+
]
|
|
126
144
|
|
|
127
145
|
def get_default_no_polling_method_path(self, async_mode: bool) -> str:
|
|
128
146
|
return self._get_lro_extension("default-no-polling-method", async_mode)
|
|
@@ -140,23 +158,35 @@ class LROOperation(Operation):
|
|
|
140
158
|
file_import = super().imports_for_multiapi(async_mode)
|
|
141
159
|
poller_import_path = ".".join(self.get_poller_path(async_mode).split(".")[:-1])
|
|
142
160
|
poller = self.get_poller(async_mode)
|
|
143
|
-
file_import.add_submodule_import(
|
|
161
|
+
file_import.add_submodule_import(
|
|
162
|
+
poller_import_path, poller, ImportType.AZURECORE, TypingSection.CONDITIONAL
|
|
163
|
+
)
|
|
144
164
|
return file_import
|
|
145
165
|
|
|
146
|
-
def imports(self, async_mode: bool) -> FileImport:
|
|
147
|
-
file_import =
|
|
148
|
-
file_import.add_submodule_import(
|
|
166
|
+
def imports(self, async_mode: bool, is_python3_file: bool) -> FileImport:
|
|
167
|
+
file_import = self._imports_base(async_mode, is_python3_file)
|
|
168
|
+
file_import.add_submodule_import(
|
|
169
|
+
"typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
170
|
+
)
|
|
149
171
|
|
|
150
172
|
poller_import_path = ".".join(self.get_poller_path(async_mode).split(".")[:-1])
|
|
151
173
|
poller = self.get_poller(async_mode)
|
|
152
|
-
file_import.add_submodule_import(
|
|
174
|
+
file_import.add_submodule_import(
|
|
175
|
+
poller_import_path, poller, ImportType.AZURECORE
|
|
176
|
+
)
|
|
153
177
|
|
|
154
178
|
default_polling_method_import_path = ".".join(
|
|
155
|
-
self.get_default_polling_method_path(
|
|
179
|
+
self.get_default_polling_method_path(
|
|
180
|
+
async_mode, self.code_model.options["azure_arm"]
|
|
181
|
+
).split(".")[:-1]
|
|
182
|
+
)
|
|
183
|
+
default_polling_method = self.get_default_polling_method(
|
|
184
|
+
async_mode, self.code_model.options["azure_arm"]
|
|
156
185
|
)
|
|
157
|
-
default_polling_method = self.get_default_polling_method(async_mode, self.code_model.options['azure_arm'])
|
|
158
186
|
file_import.add_submodule_import(
|
|
159
|
-
default_polling_method_import_path,
|
|
187
|
+
default_polling_method_import_path,
|
|
188
|
+
default_polling_method,
|
|
189
|
+
ImportType.AZURECORE,
|
|
160
190
|
)
|
|
161
191
|
|
|
162
192
|
default_no_polling_method_import_path = ".".join(
|
|
@@ -164,17 +194,23 @@ class LROOperation(Operation):
|
|
|
164
194
|
)
|
|
165
195
|
default_no_polling_method = self.get_default_no_polling_method(async_mode)
|
|
166
196
|
file_import.add_submodule_import(
|
|
167
|
-
default_no_polling_method_import_path,
|
|
197
|
+
default_no_polling_method_import_path,
|
|
198
|
+
default_no_polling_method,
|
|
199
|
+
ImportType.AZURECORE,
|
|
168
200
|
)
|
|
169
201
|
|
|
170
202
|
base_polling_method_import_path = ".".join(
|
|
171
203
|
self.get_base_polling_method_path(async_mode).split(".")[:-1]
|
|
172
204
|
)
|
|
173
205
|
base_polling_method = self.get_base_polling_method(async_mode)
|
|
174
|
-
file_import.add_submodule_import(
|
|
175
|
-
|
|
206
|
+
file_import.add_submodule_import(
|
|
207
|
+
base_polling_method_import_path, base_polling_method, ImportType.AZURECORE
|
|
208
|
+
)
|
|
209
|
+
file_import.add_submodule_import("typing", "cast", ImportType.STDLIB)
|
|
176
210
|
if async_mode:
|
|
177
|
-
file_import.add_submodule_import(
|
|
211
|
+
file_import.add_submodule_import(
|
|
212
|
+
"typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
213
|
+
)
|
|
178
214
|
if self.code_model.options["tracing"] and self.want_tracing:
|
|
179
215
|
file_import.add_submodule_import(
|
|
180
216
|
f"azure.core.tracing.decorator{'_async' if async_mode else ''}",
|
|
@@ -7,11 +7,11 @@ from .imports import FileImport
|
|
|
7
7
|
from .lro_operation import LROOperation
|
|
8
8
|
from .paging_operation import PagingOperation
|
|
9
9
|
|
|
10
|
-
class LROPagingOperation(PagingOperation, LROOperation):
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
class LROPagingOperation(PagingOperation, LROOperation):
|
|
12
|
+
def imports(self, async_mode: bool, is_python3_file: bool) -> FileImport:
|
|
13
|
+
lro_imports = LROOperation.imports(self, async_mode, is_python3_file)
|
|
14
|
+
paging_imports = PagingOperation.imports(self, async_mode, is_python3_file)
|
|
15
15
|
|
|
16
16
|
file_import = lro_imports
|
|
17
17
|
file_import.merge(paging_imports)
|
|
@@ -19,6 +19,5 @@ class LROPagingOperation(PagingOperation, LROOperation):
|
|
|
19
19
|
|
|
20
20
|
@property
|
|
21
21
|
def success_status_code(self):
|
|
22
|
-
"""The list of all successfull status code.
|
|
23
|
-
"""
|
|
22
|
+
"""The list of all successfull status code."""
|
|
24
23
|
return [200]
|
|
@@ -3,11 +3,14 @@
|
|
|
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 Any, Dict, List, Optional, Union, Type
|
|
6
|
+
from typing import Any, Dict, List, Optional, Union, Type, TYPE_CHECKING
|
|
7
7
|
from .base_schema import BaseSchema
|
|
8
8
|
from .dictionary_schema import DictionarySchema
|
|
9
9
|
from .property import Property
|
|
10
|
-
from .imports import FileImport, ImportType, TypingSection
|
|
10
|
+
from .imports import FileImport, ImportModel, ImportType, TypingSection
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from .code_model import CodeModel
|
|
11
14
|
|
|
12
15
|
|
|
13
16
|
class ObjectSchema(BaseSchema): # pylint: disable=too-many-instance-attributes
|
|
@@ -20,36 +23,41 @@ class ObjectSchema(BaseSchema): # pylint: disable=too-many-instance-attributes
|
|
|
20
23
|
"""
|
|
21
24
|
|
|
22
25
|
def __init__(
|
|
23
|
-
self,
|
|
26
|
+
self,
|
|
27
|
+
yaml_data: Dict[str, Any],
|
|
28
|
+
code_model: "CodeModel",
|
|
29
|
+
name: str,
|
|
30
|
+
description: str = "",
|
|
31
|
+
**kwargs,
|
|
24
32
|
) -> None:
|
|
25
|
-
super(
|
|
33
|
+
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
26
34
|
self.name = name
|
|
27
35
|
self.description = description
|
|
28
36
|
self.max_properties: Optional[int] = kwargs.pop("max_properties", None)
|
|
29
37
|
self.min_properties: Optional[int] = kwargs.pop("min_properties", None)
|
|
30
38
|
self.properties: List[Property] = kwargs.pop("properties", [])
|
|
31
39
|
self.is_exception: bool = kwargs.pop("is_exception", False)
|
|
32
|
-
self.base_models: Union[List[int], List["ObjectSchema"]] = kwargs.pop(
|
|
40
|
+
self.base_models: Union[List[int], List["ObjectSchema"]] = kwargs.pop(
|
|
41
|
+
"base_models", []
|
|
42
|
+
)
|
|
33
43
|
self.subtype_map: Optional[Dict[str, str]] = kwargs.pop("subtype_map", None)
|
|
34
44
|
self.discriminator_name: Optional[str] = kwargs.pop("discriminator_name", None)
|
|
35
|
-
self.discriminator_value: Optional[str] = kwargs.pop(
|
|
45
|
+
self.discriminator_value: Optional[str] = kwargs.pop(
|
|
46
|
+
"discriminator_value", None
|
|
47
|
+
)
|
|
36
48
|
self._created_json_template_representation = False
|
|
37
49
|
|
|
38
50
|
@property
|
|
39
51
|
def serialization_type(self) -> str:
|
|
40
52
|
return self.name
|
|
41
53
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return f'"{
|
|
45
|
-
|
|
46
|
-
@property
|
|
47
|
-
def operation_type_annotation(self) -> str:
|
|
48
|
-
return f'"_models.{self.name}"'
|
|
54
|
+
def type_annotation(self, *, is_operation_file: bool = False) -> str:
|
|
55
|
+
retval = f"_models.{self.name}"
|
|
56
|
+
return retval if is_operation_file else f'"{retval}"'
|
|
49
57
|
|
|
50
58
|
@property
|
|
51
59
|
def docstring_type(self) -> str:
|
|
52
|
-
return f"~{self.namespace}.models.{self.name}"
|
|
60
|
+
return f"~{self.code_model.namespace}.models.{self.name}"
|
|
53
61
|
|
|
54
62
|
@property
|
|
55
63
|
def docstring_text(self) -> str:
|
|
@@ -83,18 +91,21 @@ class ObjectSchema(BaseSchema): # pylint: disable=too-many-instance-attributes
|
|
|
83
91
|
# don't add additional properties, because there's not really a concept of
|
|
84
92
|
# additional properties in the template
|
|
85
93
|
representation = {
|
|
86
|
-
f'"{prop.original_swagger_name}"': prop.get_json_template_representation(
|
|
94
|
+
f'"{prop.original_swagger_name}"': prop.get_json_template_representation(
|
|
95
|
+
**kwargs
|
|
96
|
+
)
|
|
87
97
|
for prop in [
|
|
88
|
-
p
|
|
98
|
+
p
|
|
99
|
+
for p in self.properties
|
|
89
100
|
if not (p.is_discriminator or p.name == "additional_properties")
|
|
90
101
|
]
|
|
91
102
|
}
|
|
92
103
|
try:
|
|
93
104
|
# add discriminator prop if there is one
|
|
94
105
|
discriminator = next(p for p in self.properties if p.is_discriminator)
|
|
95
|
-
representation[
|
|
96
|
-
discriminator.original_swagger_name
|
|
97
|
-
|
|
106
|
+
representation[discriminator.original_swagger_name] = (
|
|
107
|
+
self.discriminator_value or discriminator.original_swagger_name
|
|
108
|
+
)
|
|
98
109
|
except StopIteration:
|
|
99
110
|
pass
|
|
100
111
|
|
|
@@ -103,20 +114,10 @@ class ObjectSchema(BaseSchema): # pylint: disable=too-many-instance-attributes
|
|
|
103
114
|
self._created_json_template_representation = False
|
|
104
115
|
return representation
|
|
105
116
|
|
|
106
|
-
def get_files_and_data_template_representation(self, **kwargs: Any) -> Any:
|
|
107
|
-
object_schema_names = kwargs.get("object_schema_names", [])
|
|
108
|
-
object_schema_names.append(self.name) # do tis to avoid circular
|
|
109
|
-
kwargs["object_schema_names"] = object_schema_names
|
|
110
|
-
return {
|
|
111
|
-
"{}".format(
|
|
112
|
-
prop.original_swagger_name
|
|
113
|
-
): prop.get_files_and_data_template_representation(**kwargs)
|
|
114
|
-
for prop in self.properties
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
117
|
@classmethod
|
|
119
|
-
def from_yaml(
|
|
118
|
+
def from_yaml(
|
|
119
|
+
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
120
|
+
) -> "ObjectSchema":
|
|
120
121
|
"""Returns a ClassType from the dict object constructed from a yaml file.
|
|
121
122
|
|
|
122
123
|
WARNING: This guy might create an infinite loop.
|
|
@@ -127,11 +128,13 @@ class ObjectSchema(BaseSchema): # pylint: disable=too-many-instance-attributes
|
|
|
127
128
|
:returns: A ClassType.
|
|
128
129
|
:rtype: ~autorest.models.schema.ClassType
|
|
129
130
|
"""
|
|
130
|
-
obj = cls(
|
|
131
|
-
obj.fill_instance_from_yaml(
|
|
131
|
+
obj = cls(yaml_data, code_model, "", description="")
|
|
132
|
+
obj.fill_instance_from_yaml(yaml_data, code_model)
|
|
132
133
|
return obj
|
|
133
134
|
|
|
134
|
-
def fill_instance_from_yaml(
|
|
135
|
+
def fill_instance_from_yaml(
|
|
136
|
+
self, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
137
|
+
) -> None:
|
|
135
138
|
properties = []
|
|
136
139
|
base_models = []
|
|
137
140
|
|
|
@@ -145,20 +148,24 @@ class ObjectSchema(BaseSchema): # pylint: disable=too-many-instance-attributes
|
|
|
145
148
|
for immediate_parent in immediate_parents:
|
|
146
149
|
if immediate_parent["type"] == "dictionary":
|
|
147
150
|
additional_properties_schema = DictionarySchema.from_yaml(
|
|
148
|
-
|
|
151
|
+
yaml_data=immediate_parent, code_model=code_model
|
|
149
152
|
)
|
|
150
153
|
properties.append(
|
|
151
154
|
Property(
|
|
155
|
+
yaml_data={},
|
|
156
|
+
code_model=code_model,
|
|
152
157
|
name="additional_properties",
|
|
153
158
|
schema=additional_properties_schema,
|
|
154
159
|
original_swagger_name="",
|
|
155
|
-
|
|
156
|
-
|
|
160
|
+
description=(
|
|
161
|
+
"Unmatched properties from the message are "
|
|
162
|
+
"deserialized to this collection."
|
|
163
|
+
),
|
|
157
164
|
)
|
|
158
165
|
)
|
|
159
166
|
elif (
|
|
160
|
-
immediate_parent["language"]["default"]["name"] != name
|
|
161
|
-
immediate_parent[
|
|
167
|
+
immediate_parent["language"]["default"]["name"] != name
|
|
168
|
+
and immediate_parent["type"] == "object"
|
|
162
169
|
):
|
|
163
170
|
base_models.append(id(immediate_parent))
|
|
164
171
|
|
|
@@ -168,21 +175,22 @@ class ObjectSchema(BaseSchema): # pylint: disable=too-many-instance-attributes
|
|
|
168
175
|
subtype_map = {}
|
|
169
176
|
# map of discriminator value to child's name
|
|
170
177
|
for children_yaml in yaml_data["discriminator"]["immediate"].values():
|
|
171
|
-
subtype_map[children_yaml["discriminatorValue"]] = children_yaml[
|
|
178
|
+
subtype_map[children_yaml["discriminatorValue"]] = children_yaml[
|
|
179
|
+
"language"
|
|
180
|
+
]["python"]["name"]
|
|
172
181
|
if yaml_data.get("properties"):
|
|
173
182
|
properties += [
|
|
174
|
-
Property.from_yaml(
|
|
183
|
+
Property.from_yaml(
|
|
184
|
+
p, code_model, has_additional_properties=len(properties) > 0
|
|
185
|
+
)
|
|
175
186
|
for p in yaml_data["properties"]
|
|
176
187
|
]
|
|
177
188
|
# this is to ensure that the attribute map type and property type are generated correctly
|
|
178
189
|
|
|
179
|
-
|
|
180
|
-
|
|
181
190
|
description = yaml_data["language"]["python"]["description"]
|
|
182
191
|
is_exception = False
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if id(yaml_data) in exceptions_set:
|
|
192
|
+
if code_model.exception_ids:
|
|
193
|
+
if id(yaml_data) in code_model.exception_ids:
|
|
186
194
|
is_exception = True
|
|
187
195
|
|
|
188
196
|
self.yaml_data = yaml_data
|
|
@@ -206,43 +214,89 @@ class ObjectSchema(BaseSchema): # pylint: disable=too-many-instance-attributes
|
|
|
206
214
|
@property
|
|
207
215
|
def property_with_discriminator(self) -> Any:
|
|
208
216
|
try:
|
|
209
|
-
return next(
|
|
217
|
+
return next(
|
|
218
|
+
p
|
|
219
|
+
for p in self.properties
|
|
220
|
+
if getattr(p.schema, "discriminator_name", None)
|
|
221
|
+
)
|
|
210
222
|
except StopIteration:
|
|
211
223
|
return None
|
|
212
224
|
|
|
213
225
|
def imports(self) -> FileImport:
|
|
214
226
|
file_import = FileImport()
|
|
215
227
|
if self.is_exception:
|
|
216
|
-
file_import.add_submodule_import(
|
|
228
|
+
file_import.add_submodule_import(
|
|
229
|
+
"azure.core.exceptions", "HttpResponseError", ImportType.AZURECORE
|
|
230
|
+
)
|
|
231
|
+
return file_import
|
|
232
|
+
|
|
233
|
+
def model_file_imports(self) -> FileImport:
|
|
234
|
+
file_import = self.imports()
|
|
235
|
+
file_import.add_import(
|
|
236
|
+
"__init__",
|
|
237
|
+
ImportType.LOCAL,
|
|
238
|
+
typing_section=TypingSection.TYPING,
|
|
239
|
+
alias="_models",
|
|
240
|
+
)
|
|
217
241
|
return file_import
|
|
218
242
|
|
|
219
|
-
class HiddenModelObjectSchema(ObjectSchema):
|
|
220
243
|
|
|
244
|
+
class HiddenModelObjectSchema(ObjectSchema):
|
|
221
245
|
@property
|
|
222
246
|
def serialization_type(self) -> str:
|
|
223
247
|
return "object"
|
|
224
248
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
return "JSONType"
|
|
249
|
+
def type_annotation(
|
|
250
|
+
self, *, is_operation_file: bool = False # pylint: disable=unused-argument
|
|
251
|
+
) -> str:
|
|
252
|
+
if self.xml_metadata:
|
|
253
|
+
return "ET.Element"
|
|
254
|
+
return "JSON"
|
|
232
255
|
|
|
233
256
|
@property
|
|
234
257
|
def docstring_type(self) -> str:
|
|
235
|
-
|
|
258
|
+
if self.xml_metadata:
|
|
259
|
+
return "ET.Element"
|
|
260
|
+
return "JSON"
|
|
236
261
|
|
|
237
262
|
@property
|
|
238
263
|
def docstring_text(self) -> str:
|
|
264
|
+
if self.xml_metadata:
|
|
265
|
+
return "XML Element"
|
|
239
266
|
return "JSON object"
|
|
240
267
|
|
|
241
268
|
def imports(self) -> FileImport:
|
|
242
269
|
file_import = FileImport()
|
|
243
|
-
file_import.add_submodule_import(
|
|
270
|
+
file_import.add_submodule_import(
|
|
271
|
+
"typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
272
|
+
)
|
|
273
|
+
if self.xml_metadata:
|
|
274
|
+
file_import.add_submodule_import(
|
|
275
|
+
"xml.etree", "ElementTree", ImportType.STDLIB, alias="ET"
|
|
276
|
+
)
|
|
277
|
+
file_import.add_import("sys", ImportType.STDLIB)
|
|
278
|
+
file_import.define_mypy_type(
|
|
279
|
+
"JSON",
|
|
280
|
+
"MutableMapping[str, Any] # pylint: disable=unsubscriptable-object",
|
|
281
|
+
None,
|
|
282
|
+
{
|
|
283
|
+
(3, 9): ImportModel(
|
|
284
|
+
TypingSection.CONDITIONAL,
|
|
285
|
+
ImportType.STDLIB,
|
|
286
|
+
"collections.abc",
|
|
287
|
+
submodule_name="MutableMapping",
|
|
288
|
+
),
|
|
289
|
+
None: ImportModel(
|
|
290
|
+
TypingSection.CONDITIONAL,
|
|
291
|
+
ImportType.STDLIB,
|
|
292
|
+
"typing",
|
|
293
|
+
submodule_name="MutableMapping",
|
|
294
|
+
),
|
|
295
|
+
},
|
|
296
|
+
)
|
|
244
297
|
return file_import
|
|
245
298
|
|
|
299
|
+
|
|
246
300
|
def get_object_schema(code_model) -> Type[ObjectSchema]:
|
|
247
301
|
if code_model.options["models_mode"]:
|
|
248
302
|
return ObjectSchema
|