@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,8 +4,10 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from typing import List
|
|
7
|
+
|
|
7
8
|
from . import utils
|
|
8
9
|
from ..models import CodeModel
|
|
10
|
+
from ..models.parameter import ParameterMethodLocation
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
class ClientSerializer:
|
|
@@ -43,7 +45,9 @@ class ClientSerializer:
|
|
|
43
45
|
|
|
44
46
|
def class_definition(self, async_mode) -> str:
|
|
45
47
|
class_name = self.code_model.class_name
|
|
46
|
-
has_mixin_og = any(
|
|
48
|
+
has_mixin_og = any(
|
|
49
|
+
og for og in self.code_model.operation_groups if og.is_empty_operation_group
|
|
50
|
+
)
|
|
47
51
|
base_class = ""
|
|
48
52
|
if has_mixin_og:
|
|
49
53
|
base_class = f"{class_name}OperationsMixin"
|
|
@@ -59,12 +63,22 @@ class ClientSerializer:
|
|
|
59
63
|
def property_descriptions(self, async_mode: bool) -> List[str]:
|
|
60
64
|
retval: List[str] = []
|
|
61
65
|
operations_folder = ".aio.operations." if async_mode else ".operations."
|
|
62
|
-
for og in [
|
|
66
|
+
for og in [
|
|
67
|
+
og
|
|
68
|
+
for og in self.code_model.operation_groups
|
|
69
|
+
if not og.is_empty_operation_group
|
|
70
|
+
]:
|
|
63
71
|
retval.append(f":ivar {og.name}: {og.class_name} operations")
|
|
64
|
-
retval.append(
|
|
72
|
+
retval.append(
|
|
73
|
+
f":vartype {og.name}: {self.code_model.namespace}{operations_folder}{og.class_name}"
|
|
74
|
+
)
|
|
65
75
|
for param in self.code_model.service_client.parameters.client_method:
|
|
66
|
-
retval.append(
|
|
67
|
-
|
|
76
|
+
retval.append(
|
|
77
|
+
f":{param.description_keyword} {param.serialized_name}: {param.description}"
|
|
78
|
+
)
|
|
79
|
+
retval.append(
|
|
80
|
+
f":{param.docstring_type_keyword} {param.serialized_name}: {param.docstring_type}"
|
|
81
|
+
)
|
|
68
82
|
if self.code_model.has_lro_operations:
|
|
69
83
|
retval.append(
|
|
70
84
|
":keyword int polling_interval: Default waiting time between two polls for LRO operations "
|
|
@@ -79,38 +93,57 @@ class ClientSerializer:
|
|
|
79
93
|
[
|
|
80
94
|
f"{p.serialized_name}={p.serialized_name}"
|
|
81
95
|
for p in self.code_model.service_client.parameters.config_method
|
|
82
|
-
if not p.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
]
|
|
96
|
+
if not p.method_location
|
|
97
|
+
in (ParameterMethodLocation.KWARG, ParameterMethodLocation.HIDDEN_KWARG)
|
|
98
|
+
]
|
|
99
|
+
+ ["**kwargs"]
|
|
100
|
+
)
|
|
86
101
|
return f"self._config = {config_name}({config_call})"
|
|
87
102
|
|
|
88
103
|
def initialize_pipeline_client(self, async_mode: bool) -> str:
|
|
89
|
-
host_variable_name =
|
|
104
|
+
host_variable_name = (
|
|
105
|
+
self.code_model.service_client.parameters.host_variable_name
|
|
106
|
+
)
|
|
90
107
|
if self.code_model.service_client.has_parameterized_host:
|
|
91
|
-
host_variable_name =
|
|
108
|
+
host_variable_name = (
|
|
109
|
+
"_" + host_variable_name
|
|
110
|
+
) # we don't want potential conflicts with input params
|
|
92
111
|
pipeline_client_name = self.code_model.service_client.pipeline_class(async_mode)
|
|
93
112
|
return f"self._client = {pipeline_client_name}(base_url={host_variable_name}, config=self._config, **kwargs)"
|
|
94
113
|
|
|
95
114
|
def serializers_and_operation_groups_properties(self) -> List[str]:
|
|
96
115
|
retval = []
|
|
97
116
|
if self.code_model.sorted_schemas:
|
|
98
|
-
client_models_value =
|
|
117
|
+
client_models_value = (
|
|
118
|
+
"{k: v for k, v in models.__dict__.items() if isinstance(v, type)}"
|
|
119
|
+
)
|
|
99
120
|
else:
|
|
100
121
|
client_models_value = "{} # type: Dict[str, Any]"
|
|
101
122
|
if self.code_model.options["models_mode"]:
|
|
102
123
|
retval.append(f"client_models = {client_models_value}")
|
|
103
|
-
client_models_str =
|
|
124
|
+
client_models_str = (
|
|
125
|
+
"client_models" if self.code_model.options["models_mode"] else ""
|
|
126
|
+
)
|
|
104
127
|
retval.append(f"self._serialize = Serializer({client_models_str})")
|
|
105
128
|
retval.append(f"self._deserialize = Deserializer({client_models_str})")
|
|
106
129
|
if not self.code_model.options["client_side_validation"]:
|
|
107
130
|
retval.append("self._serialize.client_side_validation = False")
|
|
108
|
-
operation_groups = [
|
|
109
|
-
|
|
131
|
+
operation_groups = [
|
|
132
|
+
og
|
|
133
|
+
for og in self.code_model.operation_groups
|
|
134
|
+
if not og.is_empty_operation_group
|
|
135
|
+
]
|
|
136
|
+
for og in operation_groups:
|
|
137
|
+
disable_check = (
|
|
138
|
+
" # type: ignore # pylint: disable=abstract-class-instantiated"
|
|
139
|
+
if og.has_abstract_operations
|
|
140
|
+
else ""
|
|
141
|
+
)
|
|
110
142
|
retval.extend(
|
|
111
143
|
[
|
|
112
|
-
f"self.{og.name} = {og.class_name}(
|
|
113
|
-
|
|
144
|
+
f"self.{og.name} = {og.class_name}({disable_check}",
|
|
145
|
+
" self._client, self._config, self._serialize, self._deserialize",
|
|
146
|
+
")",
|
|
114
147
|
]
|
|
115
148
|
)
|
|
116
149
|
return retval
|
|
@@ -125,12 +158,16 @@ class ClientSerializer:
|
|
|
125
158
|
),
|
|
126
159
|
)
|
|
127
160
|
|
|
128
|
-
def send_request_signature_and_response_type_annotation(
|
|
161
|
+
def send_request_signature_and_response_type_annotation(
|
|
162
|
+
self, async_mode: bool
|
|
163
|
+
) -> str:
|
|
129
164
|
send_request_signature = self._send_request_signature(async_mode)
|
|
130
165
|
return utils.method_signature_and_response_type_annotation_template(
|
|
131
166
|
is_python3_file=async_mode or self.is_python3_file,
|
|
132
167
|
method_signature=send_request_signature,
|
|
133
|
-
response_type_annotation="Awaitable[AsyncHttpResponse]"
|
|
168
|
+
response_type_annotation="Awaitable[AsyncHttpResponse]"
|
|
169
|
+
if async_mode
|
|
170
|
+
else "HttpResponse",
|
|
134
171
|
)
|
|
135
172
|
|
|
136
173
|
def _example_make_call(self, async_mode: bool) -> List[str]:
|
|
@@ -143,23 +180,35 @@ class ClientSerializer:
|
|
|
143
180
|
|
|
144
181
|
def _request_builder_example(self, async_mode: bool) -> List[str]:
|
|
145
182
|
retval = [
|
|
146
|
-
"We have helper methods to create requests specific to this service in "
|
|
147
|
-
f"`{self.code_model.namespace}.{self.code_model.rest_layer_name}`."
|
|
183
|
+
"We have helper methods to create requests specific to this service in "
|
|
184
|
+
+ f"`{self.code_model.namespace}.{self.code_model.rest_layer_name}`."
|
|
148
185
|
]
|
|
149
|
-
retval.append(
|
|
186
|
+
retval.append(
|
|
187
|
+
"Use these helper methods to create the request you pass to this method."
|
|
188
|
+
)
|
|
150
189
|
retval.append("")
|
|
151
190
|
|
|
152
|
-
request_builder = self.code_model.
|
|
153
|
-
request_builder_signature = ", ".join(
|
|
191
|
+
request_builder = self.code_model.request_builders[0]
|
|
192
|
+
request_builder_signature = ", ".join(
|
|
193
|
+
request_builder.parameters.call(async_mode)
|
|
194
|
+
)
|
|
154
195
|
if request_builder.builder_group_name:
|
|
155
196
|
rest_imported = request_builder.builder_group_name
|
|
156
|
-
request_builder_name =
|
|
197
|
+
request_builder_name = (
|
|
198
|
+
f"{request_builder.builder_group_name}.{request_builder.name}"
|
|
199
|
+
)
|
|
157
200
|
else:
|
|
158
201
|
rest_imported = request_builder.name
|
|
159
202
|
request_builder_name = request_builder.name
|
|
160
|
-
retval.append(
|
|
161
|
-
|
|
162
|
-
|
|
203
|
+
retval.append(
|
|
204
|
+
f">>> from {self.code_model.namespace}.{self.code_model.rest_layer_name} import {rest_imported}"
|
|
205
|
+
)
|
|
206
|
+
retval.append(
|
|
207
|
+
f">>> request = {request_builder_name}({request_builder_signature})"
|
|
208
|
+
)
|
|
209
|
+
retval.append(
|
|
210
|
+
f"<HttpRequest [{request_builder.method}], url: '{request_builder.url}'>"
|
|
211
|
+
)
|
|
163
212
|
retval.extend(self._example_make_call(async_mode))
|
|
164
213
|
return retval
|
|
165
214
|
|
|
@@ -178,22 +227,30 @@ class ClientSerializer:
|
|
|
178
227
|
else:
|
|
179
228
|
retval.extend(self._rest_request_example(async_mode))
|
|
180
229
|
retval.append("")
|
|
181
|
-
retval.append(
|
|
230
|
+
retval.append(
|
|
231
|
+
"For more information on this code flow, see https://aka.ms/azsdk/python/protocol/quickstart"
|
|
232
|
+
)
|
|
182
233
|
retval.append(f"")
|
|
183
234
|
retval.append(":param request: The network request you want to make. Required.")
|
|
184
235
|
retval.append(f":type request: ~azure.core.rest.HttpRequest")
|
|
185
|
-
retval.append(
|
|
186
|
-
|
|
236
|
+
retval.append(
|
|
237
|
+
":keyword bool stream: Whether the response payload will be streamed. Defaults to False."
|
|
238
|
+
)
|
|
239
|
+
retval.append(
|
|
240
|
+
":return: The response of your network call. Does not do error handling on your response."
|
|
241
|
+
)
|
|
187
242
|
http_response = "AsyncHttpResponse" if async_mode else "HttpResponse"
|
|
188
243
|
retval.append(f":rtype: ~azure.core.rest.{http_response}")
|
|
189
244
|
retval.append('"""')
|
|
190
245
|
return retval
|
|
191
246
|
|
|
192
247
|
def serialize_path(self) -> List[str]:
|
|
193
|
-
return utils.serialize_path(
|
|
248
|
+
return utils.serialize_path(
|
|
249
|
+
self.code_model.global_parameters.path, "self._serialize"
|
|
250
|
+
)
|
|
194
251
|
|
|
195
|
-
class ConfigSerializer:
|
|
196
252
|
|
|
253
|
+
class ConfigSerializer:
|
|
197
254
|
def __init__(self, code_model: CodeModel, is_python3_file: bool) -> None:
|
|
198
255
|
self.code_model = code_model
|
|
199
256
|
self.is_python3_file = is_python3_file
|
|
@@ -235,8 +292,8 @@ class ConfigSerializer:
|
|
|
235
292
|
|
|
236
293
|
def check_required_parameters(self) -> List[str]:
|
|
237
294
|
return [
|
|
238
|
-
f
|
|
239
|
-
f
|
|
295
|
+
f"if {p.serialized_name} is None:\n"
|
|
296
|
+
f" raise ValueError(\"Parameter '{p.serialized_name}' must not be None.\")"
|
|
240
297
|
for p in self.code_model.global_parameters.config_method
|
|
241
298
|
if p.required and not p.constant
|
|
242
299
|
]
|
|
@@ -244,7 +301,11 @@ class ConfigSerializer:
|
|
|
244
301
|
def property_descriptions(self) -> List[str]:
|
|
245
302
|
retval: List[str] = []
|
|
246
303
|
for p in self.code_model.global_parameters.config_method:
|
|
247
|
-
retval.append(
|
|
248
|
-
|
|
304
|
+
retval.append(
|
|
305
|
+
f":{p.description_keyword} {p.serialized_name}: {p.description}"
|
|
306
|
+
)
|
|
307
|
+
retval.append(
|
|
308
|
+
f":{p.docstring_type_keyword} {p.serialized_name}: {p.docstring_type}"
|
|
309
|
+
)
|
|
249
310
|
retval.append('"""')
|
|
250
311
|
return retval
|
|
@@ -5,27 +5,54 @@
|
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from jinja2 import Environment
|
|
7
7
|
from .import_serializer import FileImportSerializer, TypingSection
|
|
8
|
-
from ..models import
|
|
8
|
+
from ..models import (
|
|
9
|
+
FileImport,
|
|
10
|
+
ImportType,
|
|
11
|
+
CodeModel,
|
|
12
|
+
TokenCredentialSchema,
|
|
13
|
+
ParameterList,
|
|
14
|
+
)
|
|
9
15
|
from .client_serializer import ClientSerializer, ConfigSerializer
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
|
|
18
|
+
def config_imports(
|
|
19
|
+
code_model, global_parameters: ParameterList, async_mode: bool
|
|
20
|
+
) -> FileImport:
|
|
12
21
|
file_import = FileImport()
|
|
13
|
-
file_import.add_submodule_import(
|
|
14
|
-
|
|
15
|
-
|
|
22
|
+
file_import.add_submodule_import(
|
|
23
|
+
"azure.core.configuration", "Configuration", ImportType.AZURECORE
|
|
24
|
+
)
|
|
25
|
+
file_import.add_submodule_import(
|
|
26
|
+
"azure.core.pipeline", "policies", ImportType.AZURECORE
|
|
27
|
+
)
|
|
28
|
+
file_import.add_submodule_import(
|
|
29
|
+
"typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
30
|
+
)
|
|
16
31
|
if code_model.options["package_version"]:
|
|
17
|
-
file_import.add_submodule_import(
|
|
32
|
+
file_import.add_submodule_import(
|
|
33
|
+
".._version" if async_mode else "._version", "VERSION", ImportType.LOCAL
|
|
34
|
+
)
|
|
18
35
|
for gp in global_parameters:
|
|
19
36
|
file_import.merge(gp.imports())
|
|
20
37
|
if code_model.options["azure_arm"]:
|
|
21
|
-
policy =
|
|
22
|
-
|
|
23
|
-
|
|
38
|
+
policy = (
|
|
39
|
+
"AsyncARMChallengeAuthenticationPolicy"
|
|
40
|
+
if async_mode
|
|
41
|
+
else "ARMChallengeAuthenticationPolicy"
|
|
42
|
+
)
|
|
43
|
+
file_import.add_submodule_import(
|
|
44
|
+
"azure.mgmt.core.policies", "ARMHttpLoggingPolicy", ImportType.AZURECORE
|
|
45
|
+
)
|
|
46
|
+
file_import.add_submodule_import(
|
|
47
|
+
"azure.mgmt.core.policies", policy, ImportType.AZURECORE
|
|
48
|
+
)
|
|
24
49
|
return file_import
|
|
25
50
|
|
|
26
51
|
|
|
27
52
|
class GeneralSerializer:
|
|
28
|
-
def __init__(
|
|
53
|
+
def __init__(
|
|
54
|
+
self, code_model: CodeModel, env: Environment, async_mode: bool
|
|
55
|
+
) -> None:
|
|
29
56
|
self.code_model = code_model
|
|
30
57
|
self.env = env
|
|
31
58
|
self.async_mode = async_mode
|
|
@@ -40,7 +67,9 @@ class GeneralSerializer:
|
|
|
40
67
|
|
|
41
68
|
def _correct_credential_parameter(self):
|
|
42
69
|
credential_param = [
|
|
43
|
-
gp
|
|
70
|
+
gp
|
|
71
|
+
for gp in self.code_model.global_parameters.parameters
|
|
72
|
+
if isinstance(gp.schema, TokenCredentialSchema)
|
|
44
73
|
][0]
|
|
45
74
|
credential_param.schema = TokenCredentialSchema(async_mode=self.async_mode)
|
|
46
75
|
|
|
@@ -48,9 +77,9 @@ class GeneralSerializer:
|
|
|
48
77
|
|
|
49
78
|
template = self.env.get_template("service_client.py.jinja2")
|
|
50
79
|
|
|
51
|
-
if (
|
|
52
|
-
self.code_model.
|
|
53
|
-
|
|
80
|
+
if self.code_model.options["credential"] and isinstance(
|
|
81
|
+
self.code_model.credential_model.credential_schema_policy.credential,
|
|
82
|
+
TokenCredentialSchema,
|
|
54
83
|
):
|
|
55
84
|
self._correct_credential_parameter()
|
|
56
85
|
|
|
@@ -61,7 +90,7 @@ class GeneralSerializer:
|
|
|
61
90
|
serializer=ClientSerializer(self.code_model, is_python3_file=python3_only),
|
|
62
91
|
imports=FileImportSerializer(
|
|
63
92
|
self.code_model.service_client.imports(self.async_mode),
|
|
64
|
-
is_python3_file=self.async_mode or python3_only
|
|
93
|
+
is_python3_file=self.async_mode or python3_only,
|
|
65
94
|
),
|
|
66
95
|
)
|
|
67
96
|
|
|
@@ -92,10 +121,14 @@ class GeneralSerializer:
|
|
|
92
121
|
file_import.add_submodule_import(
|
|
93
122
|
"._configuration",
|
|
94
123
|
f"{self.code_model.class_name}Configuration",
|
|
95
|
-
ImportType.LOCAL
|
|
124
|
+
ImportType.LOCAL,
|
|
125
|
+
)
|
|
126
|
+
file_import.add_submodule_import(
|
|
127
|
+
"msrest", "Serializer", ImportType.THIRDPARTY, TypingSection.TYPING
|
|
128
|
+
)
|
|
129
|
+
file_import.add_submodule_import(
|
|
130
|
+
"msrest", "Deserializer", ImportType.THIRDPARTY, TypingSection.TYPING
|
|
96
131
|
)
|
|
97
|
-
file_import.add_submodule_import("msrest", "Serializer", ImportType.THIRDPARTY, TypingSection.TYPING)
|
|
98
|
-
file_import.add_submodule_import("msrest", "Deserializer", ImportType.THIRDPARTY, TypingSection.TYPING)
|
|
99
132
|
|
|
100
133
|
return template.render(
|
|
101
134
|
code_model=self.code_model,
|
|
@@ -106,17 +139,18 @@ class GeneralSerializer:
|
|
|
106
139
|
async_mode=self.async_mode,
|
|
107
140
|
)
|
|
108
141
|
|
|
109
|
-
|
|
110
142
|
def serialize_config_file(self) -> str:
|
|
111
143
|
|
|
112
|
-
package_name = self.code_model.options[
|
|
144
|
+
package_name = self.code_model.options["package_name"]
|
|
113
145
|
if package_name and package_name.startswith("azure-"):
|
|
114
|
-
package_name = package_name[len("azure-"):]
|
|
115
|
-
sdk_moniker =
|
|
146
|
+
package_name = package_name[len("azure-") :]
|
|
147
|
+
sdk_moniker = (
|
|
148
|
+
package_name if package_name else self.code_model.class_name.lower()
|
|
149
|
+
)
|
|
116
150
|
|
|
117
|
-
if (
|
|
118
|
-
self.code_model.
|
|
119
|
-
|
|
151
|
+
if self.code_model.options["credential"] and isinstance(
|
|
152
|
+
self.code_model.credential_model.credential_schema_policy.credential,
|
|
153
|
+
TokenCredentialSchema,
|
|
120
154
|
):
|
|
121
155
|
self._correct_credential_parameter()
|
|
122
156
|
|
|
@@ -128,7 +162,8 @@ class GeneralSerializer:
|
|
|
128
162
|
imports=FileImportSerializer(
|
|
129
163
|
config_imports(
|
|
130
164
|
self.code_model, self.code_model.global_parameters, self.async_mode
|
|
131
|
-
),
|
|
165
|
+
),
|
|
166
|
+
is_python3_file=self.async_mode or python3_only,
|
|
132
167
|
),
|
|
133
168
|
serializer=ConfigSerializer(self.code_model, is_python3_file=python3_only),
|
|
134
169
|
sdk_moniker=sdk_moniker,
|
|
@@ -5,49 +5,68 @@
|
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from copy import deepcopy
|
|
7
7
|
from typing import List
|
|
8
|
-
from ..models.imports import
|
|
8
|
+
from ..models.imports import (
|
|
9
|
+
ImportType,
|
|
10
|
+
FileImport,
|
|
11
|
+
ImportModel,
|
|
12
|
+
TypingSection,
|
|
13
|
+
TypeDefinition,
|
|
14
|
+
)
|
|
9
15
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
) -> str:
|
|
16
|
+
|
|
17
|
+
def _serialize_package(imports: List[ImportModel], delimiter: str) -> str:
|
|
13
18
|
buffer = []
|
|
14
19
|
if any(i for i in imports if i.submodule_name is None):
|
|
15
|
-
buffer.append(
|
|
20
|
+
buffer.append(
|
|
21
|
+
f"import {imports[0].module_name}{f' as {imports[0].alias}' if imports[0].alias else ''}"
|
|
22
|
+
)
|
|
16
23
|
else:
|
|
17
|
-
import_str = ", ".join(
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
import_str = ", ".join(
|
|
25
|
+
sorted(
|
|
26
|
+
[
|
|
27
|
+
f"{i.submodule_name} as {i.alias}" if i.alias else i.submodule_name for i in imports # type: ignore
|
|
28
|
+
]
|
|
29
|
+
)
|
|
30
|
+
)
|
|
20
31
|
buffer.append(f"from {imports[0].module_name} import {import_str}")
|
|
21
32
|
return delimiter.join(buffer)
|
|
22
33
|
|
|
34
|
+
|
|
23
35
|
def _serialize_import_type(imports: List[ImportModel], delimiter: str) -> str:
|
|
24
36
|
"""Serialize a given import type."""
|
|
25
37
|
import_list = []
|
|
26
38
|
for module_name in sorted(set(i.module_name for i in imports)):
|
|
27
39
|
|
|
28
|
-
import_list.append(
|
|
29
|
-
|
|
30
|
-
|
|
40
|
+
import_list.append(
|
|
41
|
+
_serialize_package(
|
|
42
|
+
[i for i in imports if i.module_name == module_name], delimiter
|
|
43
|
+
)
|
|
44
|
+
)
|
|
31
45
|
return delimiter.join(import_list)
|
|
32
46
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
) -> List[str]:
|
|
47
|
+
|
|
48
|
+
def _get_import_clauses(imports: List[ImportModel], delimiter: str) -> List[str]:
|
|
36
49
|
import_clause = []
|
|
37
50
|
for import_type in ImportType:
|
|
38
51
|
imports_with_import_type = [i for i in imports if i.import_type == import_type]
|
|
39
52
|
if imports_with_import_type:
|
|
40
|
-
import_clause.append(
|
|
53
|
+
import_clause.append(
|
|
54
|
+
_serialize_import_type(imports_with_import_type, delimiter)
|
|
55
|
+
)
|
|
41
56
|
return import_clause
|
|
42
57
|
|
|
43
58
|
|
|
44
59
|
class FileImportSerializer:
|
|
45
|
-
def __init__(
|
|
60
|
+
def __init__(
|
|
61
|
+
self, file_import: FileImport, is_python3_file: bool, async_mode: bool = False
|
|
62
|
+
) -> None:
|
|
46
63
|
self.file_import = file_import
|
|
47
64
|
self.is_python3_file = is_python3_file
|
|
48
65
|
self.async_mode = async_mode
|
|
49
66
|
|
|
50
|
-
def _get_imports_list(
|
|
67
|
+
def _get_imports_list(
|
|
68
|
+
self, baseline_typing_section: TypingSection, add_conditional_typing: bool
|
|
69
|
+
):
|
|
51
70
|
# If this is a python 3 file, our regular imports include the CONDITIONAL category
|
|
52
71
|
# If this is not a python 3 file, our typing imports include the CONDITIONAL category
|
|
53
72
|
file_import_copy = deepcopy(self.file_import)
|
|
@@ -62,33 +81,73 @@ class FileImportSerializer:
|
|
|
62
81
|
return file_import_copy.get_imports_from_section(baseline_typing_section)
|
|
63
82
|
|
|
64
83
|
def _add_type_checking_import(self):
|
|
65
|
-
any_typing = any(
|
|
84
|
+
any_typing = any(
|
|
85
|
+
self.file_import.get_imports_from_section(TypingSection.TYPING)
|
|
86
|
+
)
|
|
66
87
|
conditional_and_not_py3 = not self.is_python3_file and any(
|
|
67
88
|
self.file_import.get_imports_from_section(TypingSection.CONDITIONAL)
|
|
68
89
|
)
|
|
69
90
|
if any_typing or conditional_and_not_py3:
|
|
70
|
-
self.file_import.add_submodule_import(
|
|
91
|
+
self.file_import.add_submodule_import(
|
|
92
|
+
"typing", "TYPE_CHECKING", ImportType.STDLIB
|
|
93
|
+
)
|
|
71
94
|
|
|
72
95
|
def _get_typing_definitions(self) -> str:
|
|
96
|
+
def declare_defintion(
|
|
97
|
+
spacing: str, type_name: str, type_definition: TypeDefinition
|
|
98
|
+
) -> List[str]:
|
|
99
|
+
ret: List[str] = []
|
|
100
|
+
definition_value = (
|
|
101
|
+
type_definition.async_definition
|
|
102
|
+
if self.async_mode
|
|
103
|
+
else type_definition.sync_definition
|
|
104
|
+
)
|
|
105
|
+
if type_definition.version_imports is not None:
|
|
106
|
+
versions = type_definition.version_imports.keys()
|
|
107
|
+
for i, version in enumerate(
|
|
108
|
+
sorted(
|
|
109
|
+
versions, key=lambda x: x if x is not None else (), reverse=True
|
|
110
|
+
)
|
|
111
|
+
):
|
|
112
|
+
if version is not None:
|
|
113
|
+
ret.append(
|
|
114
|
+
"{}{} sys.version_info >= {}:".format(
|
|
115
|
+
spacing, "if" if i == 0 else "elif", version
|
|
116
|
+
)
|
|
117
|
+
)
|
|
118
|
+
elif i > 0:
|
|
119
|
+
ret.append("{}else:".format(spacing))
|
|
120
|
+
for import_clause in _get_import_clauses(
|
|
121
|
+
[type_definition.version_imports[version]], "\n"
|
|
122
|
+
):
|
|
123
|
+
ret.append(
|
|
124
|
+
"{}{}{}".format(
|
|
125
|
+
" "
|
|
126
|
+
if len(versions) > 1 or version is not None
|
|
127
|
+
else "",
|
|
128
|
+
spacing,
|
|
129
|
+
import_clause,
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
if i > 0:
|
|
133
|
+
ret[-1] += " # type: ignore"
|
|
134
|
+
ret.append("{}{} = {}".format(spacing, type_name, definition_value))
|
|
135
|
+
return ret
|
|
136
|
+
|
|
73
137
|
if not self.file_import.type_definitions:
|
|
74
138
|
return ""
|
|
75
139
|
spacing = "" if self.is_python3_file else " "
|
|
76
|
-
declarations: List[str] = [
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
spacing,
|
|
80
|
-
type_name,
|
|
81
|
-
values[1] if self.async_mode else values[0]
|
|
82
|
-
)
|
|
83
|
-
for type_name, values in self.file_import.type_definitions.items()
|
|
84
|
-
])
|
|
140
|
+
declarations: List[str] = [""]
|
|
141
|
+
for type_name, value in self.file_import.type_definitions.items():
|
|
142
|
+
declarations.extend(declare_defintion(spacing, type_name, value))
|
|
85
143
|
return "\n".join(declarations)
|
|
86
144
|
|
|
87
145
|
def __str__(self) -> str:
|
|
88
146
|
self._add_type_checking_import()
|
|
89
147
|
regular_imports = ""
|
|
90
148
|
regular_imports_list = self._get_imports_list(
|
|
91
|
-
baseline_typing_section=TypingSection.REGULAR,
|
|
149
|
+
baseline_typing_section=TypingSection.REGULAR,
|
|
150
|
+
add_conditional_typing=self.is_python3_file,
|
|
92
151
|
)
|
|
93
152
|
|
|
94
153
|
if regular_imports_list:
|
|
@@ -98,9 +157,12 @@ class FileImportSerializer:
|
|
|
98
157
|
|
|
99
158
|
typing_imports = ""
|
|
100
159
|
typing_imports_list = self._get_imports_list(
|
|
101
|
-
baseline_typing_section=TypingSection.TYPING,
|
|
160
|
+
baseline_typing_section=TypingSection.TYPING,
|
|
161
|
+
add_conditional_typing=not self.is_python3_file,
|
|
102
162
|
)
|
|
103
163
|
if typing_imports_list:
|
|
104
164
|
typing_imports += "\n\nif TYPE_CHECKING:\n # pylint: disable=unused-import,ungrouped-imports\n "
|
|
105
|
-
typing_imports += "\n\n ".join(
|
|
165
|
+
typing_imports += "\n\n ".join(
|
|
166
|
+
_get_import_clauses(typing_imports_list, "\n ")
|
|
167
|
+
)
|
|
106
168
|
return regular_imports + typing_imports + self._get_typing_definitions()
|