@autorest/python 6.1.11 → 6.2.1
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/_utils.py +2 -1
- package/autorest/codegen/__init__.py +23 -81
- package/autorest/codegen/models/__init__.py +5 -3
- package/autorest/codegen/models/{base_type.py → base.py} +24 -3
- package/autorest/codegen/models/base_builder.py +9 -5
- package/autorest/codegen/models/client.py +183 -13
- package/autorest/codegen/models/code_model.py +154 -141
- package/autorest/codegen/models/combined_type.py +5 -2
- package/autorest/codegen/models/constant_type.py +38 -4
- package/autorest/codegen/models/credential_types.py +1 -1
- package/autorest/codegen/models/dictionary_type.py +1 -1
- package/autorest/codegen/models/enum_type.py +5 -3
- package/autorest/codegen/models/imports.py +78 -29
- package/autorest/codegen/models/list_type.py +1 -1
- package/autorest/codegen/models/lro_operation.py +5 -1
- package/autorest/codegen/models/model_type.py +1 -2
- package/autorest/codegen/models/operation.py +34 -10
- package/autorest/codegen/models/operation_group.py +16 -5
- package/autorest/codegen/models/paging_operation.py +5 -4
- package/autorest/codegen/models/parameter.py +19 -6
- package/autorest/codegen/models/primitive_types.py +1 -2
- package/autorest/codegen/models/property.py +4 -4
- package/autorest/codegen/models/request_builder.py +17 -6
- package/autorest/codegen/models/request_builder_parameter.py +5 -2
- package/autorest/codegen/models/response.py +6 -3
- package/autorest/codegen/serializers/__init__.py +207 -135
- package/autorest/codegen/serializers/builder_serializer.py +2 -4
- package/autorest/codegen/serializers/client_serializer.py +41 -45
- package/autorest/codegen/serializers/general_serializer.py +80 -37
- package/autorest/codegen/serializers/import_serializer.py +30 -36
- package/autorest/codegen/serializers/metadata_serializer.py +36 -14
- package/autorest/codegen/serializers/model_serializer.py +34 -19
- package/autorest/codegen/serializers/operation_groups_serializer.py +22 -6
- package/autorest/codegen/serializers/operations_init_serializer.py +10 -4
- package/autorest/codegen/serializers/sample_serializer.py +144 -0
- package/autorest/codegen/templates/client.py.jinja2 +7 -15
- package/autorest/codegen/templates/client_container.py.jinja2 +12 -0
- package/autorest/codegen/templates/config.py.jinja2 +13 -26
- package/autorest/codegen/templates/config_container.py.jinja2 +16 -0
- package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/init.py.jinja2 +9 -3
- package/autorest/codegen/templates/lro_operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/metadata.json.jinja2 +13 -14
- package/autorest/codegen/templates/model_dpg.py.jinja2 +4 -4
- package/autorest/codegen/templates/model_init.py.jinja2 +1 -1
- package/autorest/codegen/templates/operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/operation_group.py.jinja2 +2 -2
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +5 -5
- package/autorest/codegen/templates/operation_tools.jinja2 +2 -2
- package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -4
- package/autorest/codegen/templates/{CHANGELOG.md.jinja2 → packaging_templates/CHANGELOG.md.jinja2} +0 -0
- package/autorest/codegen/templates/{LICENSE.jinja2 → packaging_templates/LICENSE.jinja2} +0 -0
- package/autorest/codegen/templates/{MANIFEST.in.jinja2 → packaging_templates/MANIFEST.in.jinja2} +0 -0
- package/autorest/codegen/templates/{README.md.jinja2 → packaging_templates/README.md.jinja2} +0 -0
- package/autorest/codegen/templates/{dev_requirements.txt.jinja2 → packaging_templates/dev_requirements.txt.jinja2} +0 -0
- package/autorest/codegen/templates/{setup.py.jinja2 → packaging_templates/setup.py.jinja2} +12 -9
- package/autorest/codegen/templates/request_builders.py.jinja2 +2 -2
- package/autorest/codegen/templates/sample.py.jinja2 +44 -0
- package/autorest/codegen/templates/vendor.py.jinja2 +4 -2
- package/autorest/m4reformatter/__init__.py +18 -4
- package/autorest/multiapi/models/imports.py +89 -18
- package/autorest/multiapi/serializers/import_serializer.py +88 -7
- package/autorest/multiapi/utils.py +6 -0
- package/autorest/preprocess/__init__.py +20 -8
- package/package.json +1 -1
- package/run_cadl.py +0 -1
- package/autorest/cadlflags/__init__.py +0 -130
- package/autorest/codegen/models/base_model.py +0 -28
|
@@ -3,20 +3,22 @@
|
|
|
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 List, Dict,
|
|
6
|
+
from typing import List, Dict, Any, Set, Union
|
|
7
7
|
|
|
8
|
-
from .
|
|
8
|
+
from .base import BaseType
|
|
9
9
|
from .enum_type import EnumType
|
|
10
10
|
from .model_type import ModelType
|
|
11
|
-
from .
|
|
12
|
-
from .
|
|
13
|
-
from .
|
|
14
|
-
from .parameter import Parameter
|
|
11
|
+
from .client import Client
|
|
12
|
+
from .request_builder import RequestBuilder, OverloadedRequestBuilder
|
|
13
|
+
from .constant_type import ConstantType
|
|
15
14
|
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
""
|
|
19
|
-
|
|
16
|
+
def _is_legacy(options) -> bool:
|
|
17
|
+
return not (options["version_tolerant"] or options["low_level_client"])
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class CodeModel: # pylint: disable=too-many-public-methods
|
|
21
|
+
"""Top level code model
|
|
20
22
|
|
|
21
23
|
:param options: Options of the code model. I.e., whether this is for management generation
|
|
22
24
|
:type options: dict[str, bool]
|
|
@@ -34,8 +36,6 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
34
36
|
:param primitives: List of schemas we've created that are not EnumSchemas or ObjectSchemas. Maps their
|
|
35
37
|
yaml id to our created schemas.
|
|
36
38
|
:type primitives: Dict[int, ~autorest.models.BaseType]
|
|
37
|
-
:param operation_groups: The operation groups we are going to serialize
|
|
38
|
-
:type operation_groups: list[~autorest.models.OperationGroup]
|
|
39
39
|
:param package_dependency: All the dependencies needed in setup.py
|
|
40
40
|
:type package_dependency: Dict[str, str]
|
|
41
41
|
"""
|
|
@@ -44,71 +44,136 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
44
44
|
self,
|
|
45
45
|
yaml_data: Dict[str, Any],
|
|
46
46
|
options: Dict[str, Any],
|
|
47
|
+
*,
|
|
48
|
+
is_subnamespace: bool = False,
|
|
47
49
|
) -> None:
|
|
48
50
|
self.yaml_data = yaml_data
|
|
49
51
|
self.options = options
|
|
52
|
+
self.namespace = self.yaml_data["namespace"]
|
|
50
53
|
self.types_map: Dict[int, BaseType] = {} # map yaml id to schema
|
|
51
|
-
self.operation_groups: List[OperationGroup] = []
|
|
52
54
|
self._model_types: List[ModelType] = []
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
] = [
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
from . import build_type
|
|
56
|
+
|
|
57
|
+
for type_yaml in yaml_data.get("types", []):
|
|
58
|
+
build_type(yaml_data=type_yaml, code_model=self)
|
|
59
|
+
self.clients: List[Client] = [
|
|
60
|
+
Client.from_yaml(client_yaml_data, self)
|
|
61
|
+
for client_yaml_data in yaml_data["clients"]
|
|
62
|
+
]
|
|
63
|
+
self.subnamespace_to_clients: Dict[str, List[Client]] = {
|
|
64
|
+
subnamespace: [
|
|
65
|
+
Client.from_yaml(client_yaml, self, is_subclient=True)
|
|
66
|
+
for client_yaml in client_yamls
|
|
67
|
+
]
|
|
68
|
+
for subnamespace, client_yamls in yaml_data.get(
|
|
69
|
+
"subnamespaceToClients", {}
|
|
70
|
+
).items()
|
|
71
|
+
}
|
|
72
|
+
if self.options["models_mode"] and self.model_types:
|
|
73
|
+
self.sort_model_types()
|
|
74
|
+
self.is_subnamespace = is_subnamespace
|
|
61
75
|
|
|
62
|
-
|
|
63
|
-
|
|
76
|
+
@property
|
|
77
|
+
def has_operations(self) -> bool:
|
|
78
|
+
if any(c for c in self.clients if c.has_operations):
|
|
79
|
+
return True
|
|
80
|
+
return any(
|
|
81
|
+
c
|
|
82
|
+
for clients in self.subnamespace_to_clients.values()
|
|
83
|
+
for c in clients
|
|
84
|
+
if c.has_operations
|
|
85
|
+
)
|
|
64
86
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
87
|
+
@property
|
|
88
|
+
def has_non_abstract_operations(self) -> bool:
|
|
89
|
+
for client in self.clients:
|
|
90
|
+
for operation_group in client.operation_groups:
|
|
91
|
+
for operation in operation_group.operations:
|
|
92
|
+
if not operation.abstract:
|
|
93
|
+
return True
|
|
94
|
+
for clients in self.subnamespace_to_clients.values():
|
|
95
|
+
for client in clients:
|
|
96
|
+
for operation_group in client.operation_groups:
|
|
97
|
+
for operation in operation_group.operations:
|
|
98
|
+
if not operation.abstract:
|
|
99
|
+
return True
|
|
100
|
+
return False
|
|
101
|
+
|
|
102
|
+
def lookup_request_builder(
|
|
103
|
+
self, request_builder_id: int
|
|
104
|
+
) -> Union[RequestBuilder, OverloadedRequestBuilder]:
|
|
105
|
+
"""Find the request builder based off of id"""
|
|
106
|
+
for client in self.clients:
|
|
107
|
+
try:
|
|
108
|
+
return client.lookup_request_builder(request_builder_id)
|
|
109
|
+
except KeyError:
|
|
110
|
+
pass
|
|
111
|
+
raise KeyError(f"No request builder with id {request_builder_id} found.")
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def rest_layer_name(self) -> str:
|
|
115
|
+
"""If we have a separate rest layer, what is its name?"""
|
|
116
|
+
return "rest" if self.options["builders_visibility"] == "public" else "_rest"
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def client_filename(self) -> str:
|
|
120
|
+
return self.clients[0].filename
|
|
121
|
+
|
|
122
|
+
def need_vendored_code(self, async_mode: bool) -> bool:
|
|
123
|
+
"""Whether we need to vendor code in the _vendor.py file for this SDK"""
|
|
124
|
+
if self.has_abstract_operations:
|
|
125
|
+
return True
|
|
126
|
+
if async_mode:
|
|
127
|
+
return self.need_mixin_abc
|
|
128
|
+
return (
|
|
129
|
+
self.need_request_converter or self.need_format_url or self.need_mixin_abc
|
|
130
|
+
)
|
|
74
131
|
|
|
75
132
|
@property
|
|
76
|
-
def
|
|
77
|
-
|
|
78
|
-
return self.client.parameters.credential
|
|
133
|
+
def need_request_converter(self) -> bool:
|
|
134
|
+
return any(c for c in self.clients if c.need_request_converter)
|
|
79
135
|
|
|
80
136
|
@property
|
|
81
|
-
def
|
|
82
|
-
|
|
83
|
-
raise ValueError("You haven't linked the client yet")
|
|
84
|
-
return self._client
|
|
137
|
+
def need_format_url(self) -> bool:
|
|
138
|
+
return any(c for c in self.clients if c.need_format_url)
|
|
85
139
|
|
|
86
|
-
@
|
|
87
|
-
def
|
|
88
|
-
self.
|
|
140
|
+
@property
|
|
141
|
+
def need_mixin_abc(self) -> bool:
|
|
142
|
+
return any(c for c in self.clients if c.has_mixin)
|
|
89
143
|
|
|
90
144
|
@property
|
|
91
|
-
def
|
|
92
|
-
|
|
93
|
-
raise ValueError("You haven't linked the config yet")
|
|
94
|
-
return self._config
|
|
145
|
+
def has_abstract_operations(self) -> bool:
|
|
146
|
+
return any(c for c in self.clients if c.has_abstract_operations)
|
|
95
147
|
|
|
96
|
-
@
|
|
97
|
-
def
|
|
98
|
-
|
|
148
|
+
@property
|
|
149
|
+
def operations_folder_name(self) -> str:
|
|
150
|
+
"""Get the name of the operations folder that holds operations."""
|
|
151
|
+
name = "operations"
|
|
152
|
+
if self.options["version_tolerant"] and not any(
|
|
153
|
+
og
|
|
154
|
+
for client in self.clients
|
|
155
|
+
for og in client.operation_groups
|
|
156
|
+
if not og.is_mixin
|
|
157
|
+
):
|
|
158
|
+
name = f"_{name}"
|
|
159
|
+
return name
|
|
99
160
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
161
|
+
@property
|
|
162
|
+
def description(self) -> str:
|
|
163
|
+
return self.clients[0].description
|
|
164
|
+
|
|
165
|
+
def lookup_type(self, schema_id: int) -> BaseType:
|
|
166
|
+
"""Looks to see if the schema has already been created.
|
|
167
|
+
|
|
168
|
+
:param int schema_id: The yaml id of the schema
|
|
169
|
+
:return: If created, we return the created schema, otherwise, we throw.
|
|
170
|
+
:rtype: ~autorest.models.BaseType
|
|
171
|
+
:raises: KeyError if schema is not found
|
|
172
|
+
"""
|
|
104
173
|
try:
|
|
105
|
-
return next(
|
|
106
|
-
rb
|
|
107
|
-
for rb in self.request_builders
|
|
108
|
-
if id(rb.yaml_data) == request_builder_id
|
|
109
|
-
)
|
|
174
|
+
return next(type for id, type in self.types_map.items() if id == schema_id)
|
|
110
175
|
except StopIteration:
|
|
111
|
-
raise KeyError(f"
|
|
176
|
+
raise KeyError(f"Couldn't find schema with id {schema_id}")
|
|
112
177
|
|
|
113
178
|
@property
|
|
114
179
|
def model_types(self) -> List[ModelType]:
|
|
@@ -132,9 +197,11 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
132
197
|
"""All of the enums"""
|
|
133
198
|
return [t for t in self.types_map.values() if isinstance(t, EnumType)]
|
|
134
199
|
|
|
135
|
-
@staticmethod
|
|
136
200
|
def _sort_model_types_helper(
|
|
137
|
-
|
|
201
|
+
self,
|
|
202
|
+
current: ModelType,
|
|
203
|
+
seen_schema_names: Set[str],
|
|
204
|
+
seen_schema_yaml_ids: Set[int],
|
|
138
205
|
):
|
|
139
206
|
if current.id in seen_schema_yaml_ids:
|
|
140
207
|
return []
|
|
@@ -150,7 +217,7 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
150
217
|
seen_schema_names.add(current.name)
|
|
151
218
|
seen_schema_yaml_ids.add(current.id)
|
|
152
219
|
ancestors = (
|
|
153
|
-
|
|
220
|
+
self._sort_model_types_helper(
|
|
154
221
|
parent, seen_schema_names, seen_schema_yaml_ids
|
|
155
222
|
)
|
|
156
223
|
+ ancestors
|
|
@@ -170,84 +237,12 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
170
237
|
sorted_object_schemas: List[ModelType] = []
|
|
171
238
|
for schema in sorted(self.model_types, key=lambda x: x.name.lower()):
|
|
172
239
|
sorted_object_schemas.extend(
|
|
173
|
-
|
|
240
|
+
self._sort_model_types_helper(
|
|
174
241
|
schema, seen_schema_names, seen_schema_yaml_ids
|
|
175
242
|
)
|
|
176
243
|
)
|
|
177
244
|
self.model_types = sorted_object_schemas
|
|
178
245
|
|
|
179
|
-
def format_lro_operations(self) -> None:
|
|
180
|
-
"""Adds operations and attributes needed for LROs.
|
|
181
|
-
If there are LRO functions in here, will add initial LRO function. Will also set the return
|
|
182
|
-
type of the LRO operation
|
|
183
|
-
"""
|
|
184
|
-
for operation_group in self.operation_groups:
|
|
185
|
-
i = 0
|
|
186
|
-
while i < len(operation_group.operations):
|
|
187
|
-
operation = operation_group.operations[i]
|
|
188
|
-
if operation.operation_type in ("lro", "lropaging"):
|
|
189
|
-
operation_group.operations.insert(i, operation.initial_operation) # type: ignore
|
|
190
|
-
i += 1
|
|
191
|
-
i += 1
|
|
192
|
-
|
|
193
|
-
@property
|
|
194
|
-
def operations_folder_name(self) -> str:
|
|
195
|
-
"""Get the name of the operations folder that holds operations."""
|
|
196
|
-
name = "operations"
|
|
197
|
-
if self.options["version_tolerant"] and not any(
|
|
198
|
-
og for og in self.operation_groups if not og.is_mixin
|
|
199
|
-
):
|
|
200
|
-
name = f"_{name}"
|
|
201
|
-
return name
|
|
202
|
-
|
|
203
|
-
@property
|
|
204
|
-
def has_abstract_operations(self) -> bool:
|
|
205
|
-
"""Whether there is abstract operation in any operation group."""
|
|
206
|
-
return any(og.has_abstract_operations for og in self.operation_groups)
|
|
207
|
-
|
|
208
|
-
def need_vendored_code(self, async_mode: bool) -> bool:
|
|
209
|
-
"""Whether we need to vendor code in the _vendor.py file for this SDK"""
|
|
210
|
-
if self.has_abstract_operations:
|
|
211
|
-
return True
|
|
212
|
-
if async_mode:
|
|
213
|
-
return self.need_mixin_abc
|
|
214
|
-
return (
|
|
215
|
-
self.need_request_converter or self.need_format_url or self.need_mixin_abc
|
|
216
|
-
)
|
|
217
|
-
|
|
218
|
-
@property
|
|
219
|
-
def need_request_converter(self) -> bool:
|
|
220
|
-
"""
|
|
221
|
-
Whether we need to convert our created azure.core.rest.HttpRequests to
|
|
222
|
-
azure.core.pipeline.transport.HttpRequests
|
|
223
|
-
"""
|
|
224
|
-
return (
|
|
225
|
-
self.options["show_operations"]
|
|
226
|
-
and bool(self.request_builders)
|
|
227
|
-
and not self.options["version_tolerant"]
|
|
228
|
-
)
|
|
229
|
-
|
|
230
|
-
@property
|
|
231
|
-
def need_format_url(self) -> bool:
|
|
232
|
-
"""Whether we need to format urls. If so, we need to vendor core."""
|
|
233
|
-
return any(rq for rq in self.request_builders if rq.parameters.path)
|
|
234
|
-
|
|
235
|
-
@property
|
|
236
|
-
def need_mixin_abc(self) -> bool:
|
|
237
|
-
"""Do we want a mixin ABC class for typing purposes?"""
|
|
238
|
-
return any(o for o in self.operation_groups if o.is_mixin)
|
|
239
|
-
|
|
240
|
-
@property
|
|
241
|
-
def has_lro_operations(self) -> bool:
|
|
242
|
-
"""Are there any LRO operations in this SDK?"""
|
|
243
|
-
return any(
|
|
244
|
-
[
|
|
245
|
-
operation.operation_type in ("lro", "lropaging")
|
|
246
|
-
for operation_group in self.operation_groups
|
|
247
|
-
for operation in operation_group.operations
|
|
248
|
-
]
|
|
249
|
-
)
|
|
250
|
-
|
|
251
246
|
@property
|
|
252
247
|
def models_filename(self) -> str:
|
|
253
248
|
"""Get the names of the model file(s)"""
|
|
@@ -259,16 +254,34 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
|
|
|
259
254
|
def enums_filename(self) -> str:
|
|
260
255
|
"""The name of the enums file"""
|
|
261
256
|
if self.is_legacy:
|
|
262
|
-
return f"_{self.
|
|
257
|
+
return f"_{self.clients[0].legacy_filename}_enums"
|
|
263
258
|
return "_enums"
|
|
264
259
|
|
|
265
260
|
@property
|
|
266
261
|
def is_legacy(self) -> bool:
|
|
267
|
-
return
|
|
268
|
-
self.options["version_tolerant"] or self.options["low_level_client"]
|
|
269
|
-
)
|
|
262
|
+
return _is_legacy(self.options)
|
|
270
263
|
|
|
271
264
|
@property
|
|
272
|
-
def
|
|
273
|
-
""
|
|
274
|
-
|
|
265
|
+
def need_typing_extensions(self) -> bool:
|
|
266
|
+
if self.options["models_mode"] and any(
|
|
267
|
+
isinstance(p.type, ConstantType)
|
|
268
|
+
and (p.optional or self.options["models_mode"] == "dpg")
|
|
269
|
+
for model in self.model_types
|
|
270
|
+
for p in model.properties
|
|
271
|
+
):
|
|
272
|
+
return True
|
|
273
|
+
if any(
|
|
274
|
+
isinstance(parameter.type, ConstantType)
|
|
275
|
+
for client in self.clients
|
|
276
|
+
for og in client.operation_groups
|
|
277
|
+
for op in og.operations
|
|
278
|
+
for parameter in op.parameters.method
|
|
279
|
+
):
|
|
280
|
+
return True
|
|
281
|
+
if any(
|
|
282
|
+
isinstance(parameter.type, ConstantType)
|
|
283
|
+
for client in self.clients
|
|
284
|
+
for parameter in client.config.parameters.kwargs_to_pop
|
|
285
|
+
):
|
|
286
|
+
return True
|
|
287
|
+
return False
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
from typing import Any, Dict, List, Optional, TYPE_CHECKING
|
|
7
7
|
import re
|
|
8
8
|
from autorest.codegen.models.imports import FileImport, ImportType
|
|
9
|
-
from .
|
|
9
|
+
from .base import BaseType
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
12
|
from .code_model import CodeModel
|
|
@@ -21,7 +21,10 @@ class CombinedType(BaseType):
|
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
23
|
def __init__(
|
|
24
|
-
self,
|
|
24
|
+
self,
|
|
25
|
+
yaml_data: Dict[str, Any],
|
|
26
|
+
code_model: "CodeModel",
|
|
27
|
+
types: List[BaseType],
|
|
25
28
|
) -> None:
|
|
26
29
|
super().__init__(yaml_data, code_model)
|
|
27
30
|
self.types = types # the types that this type is combining
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
import logging
|
|
7
7
|
from typing import Dict, Any, Optional, TYPE_CHECKING
|
|
8
|
-
from .
|
|
9
|
-
from .imports import FileImport
|
|
8
|
+
from .base import BaseType
|
|
9
|
+
from .imports import FileImport, ImportType, TypingSection
|
|
10
|
+
from .primitive_types import IntegerType, BinaryType, StringType, BooleanType
|
|
10
11
|
from .utils import add_to_description
|
|
11
12
|
|
|
12
13
|
if TYPE_CHECKING:
|
|
@@ -75,7 +76,17 @@ class ConstantType(BaseType):
|
|
|
75
76
|
return self.value_type.docstring_type(**kwargs)
|
|
76
77
|
|
|
77
78
|
def type_annotation(self, **kwargs: Any) -> str:
|
|
78
|
-
return
|
|
79
|
+
return (
|
|
80
|
+
f"Literal[{self.get_declaration()}]"
|
|
81
|
+
if self._is_literal
|
|
82
|
+
else self.value_type.type_annotation(**kwargs)
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def _is_literal(self) -> bool:
|
|
87
|
+
return isinstance(
|
|
88
|
+
self.value_type, (IntegerType, BinaryType, StringType, BooleanType)
|
|
89
|
+
)
|
|
79
90
|
|
|
80
91
|
@classmethod
|
|
81
92
|
def from_yaml(
|
|
@@ -112,11 +123,34 @@ class ConstantType(BaseType):
|
|
|
112
123
|
description=description,
|
|
113
124
|
)
|
|
114
125
|
|
|
115
|
-
def
|
|
126
|
+
def _imports_shared(self, **kwargs: Any):
|
|
116
127
|
file_import = FileImport()
|
|
117
128
|
file_import.merge(self.value_type.imports(**kwargs))
|
|
118
129
|
return file_import
|
|
119
130
|
|
|
131
|
+
def imports_for_multiapi(self, **kwargs: Any) -> FileImport:
|
|
132
|
+
return self._imports_shared(**kwargs)
|
|
133
|
+
|
|
134
|
+
def imports(self, **kwargs: Any) -> FileImport:
|
|
135
|
+
file_import = self._imports_shared(**kwargs)
|
|
136
|
+
if self._is_literal:
|
|
137
|
+
file_import.add_import("sys", ImportType.STDLIB)
|
|
138
|
+
file_import.add_submodule_import(
|
|
139
|
+
"typing_extensions",
|
|
140
|
+
"Literal",
|
|
141
|
+
ImportType.BYVERSION,
|
|
142
|
+
TypingSection.REGULAR,
|
|
143
|
+
None,
|
|
144
|
+
(
|
|
145
|
+
(
|
|
146
|
+
(3, 8),
|
|
147
|
+
"typing",
|
|
148
|
+
"pylint: disable=no-name-in-module, ungrouped-imports",
|
|
149
|
+
),
|
|
150
|
+
),
|
|
151
|
+
)
|
|
152
|
+
return file_import
|
|
153
|
+
|
|
120
154
|
@property
|
|
121
155
|
def instance_check_template(self) -> str:
|
|
122
156
|
return self.value_type.instance_check_template
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from typing import Any, Dict, Optional, TYPE_CHECKING, List
|
|
7
|
-
from .
|
|
7
|
+
from .base import BaseType
|
|
8
8
|
from .imports import FileImport, ImportType, TypingSection
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from typing import Any, Dict, List, TYPE_CHECKING, Optional
|
|
7
7
|
|
|
8
|
-
from .
|
|
8
|
+
from .base import BaseType
|
|
9
9
|
from .imports import FileImport, ImportType, TypingSection
|
|
10
|
-
from .
|
|
10
|
+
from .base import BaseModel
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
13
|
from .code_model import CodeModel
|
|
@@ -126,7 +126,9 @@ class EnumType(BaseType):
|
|
|
126
126
|
def docstring_type(self, **kwargs: Any) -> str:
|
|
127
127
|
"""The python type used for RST syntax input and type annotation."""
|
|
128
128
|
if self.code_model.options["models_mode"]:
|
|
129
|
-
|
|
129
|
+
type_annotation = self.value_type.type_annotation(**kwargs)
|
|
130
|
+
enum_type_annotation = f"{self.code_model.namespace}.models.{self.name}"
|
|
131
|
+
return f"{type_annotation} or ~{enum_type_annotation}"
|
|
130
132
|
return self.value_type.type_annotation(**kwargs)
|
|
131
133
|
|
|
132
134
|
def get_json_template_representation(
|