@autorest/python 5.16.0 → 5.19.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 +79 -4
- package/README.md +30 -4
- package/autorest/__init__.py +1 -1
- package/autorest/codegen/__init__.py +55 -211
- package/autorest/codegen/models/__init__.py +116 -83
- package/autorest/codegen/models/base_builder.py +49 -88
- package/autorest/codegen/models/base_model.py +1 -1
- package/autorest/codegen/models/{base_schema.py → base_type.py} +61 -39
- package/autorest/codegen/models/client.py +165 -53
- package/autorest/codegen/models/code_model.py +122 -257
- package/autorest/codegen/models/combined_type.py +107 -0
- package/autorest/codegen/models/{constant_schema.py → constant_type.py} +49 -40
- package/autorest/codegen/models/credential_types.py +224 -0
- package/autorest/codegen/models/dictionary_type.py +131 -0
- package/autorest/codegen/models/enum_type.py +195 -0
- package/autorest/codegen/models/imports.py +80 -2
- package/autorest/codegen/models/list_type.py +149 -0
- package/autorest/codegen/models/lro_operation.py +79 -156
- package/autorest/codegen/models/lro_paging_operation.py +28 -11
- package/autorest/codegen/models/model_type.py +262 -0
- package/autorest/codegen/models/operation.py +331 -298
- package/autorest/codegen/models/operation_group.py +54 -91
- package/autorest/codegen/models/paging_operation.py +82 -123
- package/autorest/codegen/models/parameter.py +289 -396
- package/autorest/codegen/models/parameter_list.py +355 -360
- package/autorest/codegen/models/primitive_types.py +544 -0
- package/autorest/codegen/models/property.py +123 -139
- package/autorest/codegen/models/request_builder.py +130 -102
- package/autorest/codegen/models/request_builder_parameter.py +112 -100
- package/autorest/codegen/models/response.py +325 -0
- package/autorest/codegen/models/utils.py +12 -19
- package/autorest/codegen/serializers/__init__.py +55 -37
- package/autorest/codegen/serializers/builder_serializer.py +695 -1144
- package/autorest/codegen/serializers/client_serializer.py +92 -89
- package/autorest/codegen/serializers/general_serializer.py +15 -69
- package/autorest/codegen/serializers/import_serializer.py +7 -4
- package/autorest/codegen/serializers/metadata_serializer.py +15 -104
- package/autorest/codegen/serializers/model_base_serializer.py +49 -36
- package/autorest/codegen/serializers/model_generic_serializer.py +8 -6
- package/autorest/codegen/serializers/model_init_serializer.py +2 -4
- package/autorest/codegen/serializers/model_python3_serializer.py +22 -16
- package/autorest/codegen/serializers/operation_groups_serializer.py +7 -13
- package/autorest/codegen/serializers/parameter_serializer.py +174 -0
- package/autorest/codegen/serializers/request_builders_serializer.py +13 -30
- package/autorest/codegen/serializers/utils.py +0 -140
- package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
- package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +10 -7
- package/autorest/codegen/templates/config.py.jinja2 +13 -13
- package/autorest/codegen/templates/enum.py.jinja2 +4 -4
- package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/init.py.jinja2 +2 -2
- package/autorest/codegen/templates/lro_operation.py.jinja2 +4 -1
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +4 -1
- package/autorest/codegen/templates/metadata.json.jinja2 +33 -33
- package/autorest/codegen/templates/model.py.jinja2 +23 -24
- package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
- package/autorest/codegen/templates/model_init.py.jinja2 +3 -5
- package/autorest/codegen/templates/operation.py.jinja2 +6 -8
- package/autorest/codegen/templates/operation_group.py.jinja2 +21 -8
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +2 -2
- package/autorest/codegen/templates/operation_tools.jinja2 +11 -3
- package/autorest/codegen/templates/paging_operation.py.jinja2 +2 -2
- package/autorest/codegen/templates/request_builder.py.jinja2 +10 -15
- package/autorest/codegen/templates/request_builders.py.jinja2 +1 -1
- package/autorest/codegen/templates/serialization.py.jinja2 +2006 -0
- package/autorest/codegen/templates/setup.py.jinja2 +13 -3
- package/autorest/codegen/templates/vendor.py.jinja2 +11 -1
- package/autorest/jsonrpc/server.py +15 -3
- package/autorest/m4reformatter/__init__.py +1126 -0
- package/autorest/multiapi/models/client.py +12 -2
- package/autorest/multiapi/models/code_model.py +1 -1
- package/autorest/multiapi/serializers/__init__.py +18 -4
- package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
- package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
- package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +4 -4
- package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
- package/autorest/postprocess/__init__.py +202 -0
- package/autorest/postprocess/get_all.py +19 -0
- package/autorest/postprocess/venvtools.py +73 -0
- package/autorest/preprocess/__init__.py +210 -0
- package/autorest/preprocess/helpers.py +54 -0
- package/autorest/{namer → preprocess}/python_mappings.py +21 -16
- package/package.json +2 -2
- package/autorest/codegen/models/credential_model.py +0 -55
- package/autorest/codegen/models/credential_schema.py +0 -95
- package/autorest/codegen/models/credential_schema_policy.py +0 -73
- package/autorest/codegen/models/dictionary_schema.py +0 -106
- package/autorest/codegen/models/enum_schema.py +0 -225
- package/autorest/codegen/models/list_schema.py +0 -135
- package/autorest/codegen/models/object_schema.py +0 -303
- package/autorest/codegen/models/primitive_schemas.py +0 -495
- package/autorest/codegen/models/request_builder_parameter_list.py +0 -249
- package/autorest/codegen/models/schema_request.py +0 -55
- package/autorest/codegen/models/schema_response.py +0 -141
- package/autorest/namer/__init__.py +0 -23
- package/autorest/namer/name_converter.py +0 -509
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
|
+
# license information.
|
|
5
|
+
# --------------------------------------------------------------------------
|
|
6
|
+
from typing import Any, Dict, List, TYPE_CHECKING, Optional
|
|
7
|
+
|
|
8
|
+
from .base_type import BaseType
|
|
9
|
+
from .imports import FileImport, ImportType, TypingSection
|
|
10
|
+
from .base_model import BaseModel
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from .code_model import CodeModel
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class EnumValue(BaseModel):
|
|
17
|
+
"""Model containing necessary information for a single value of an enum.
|
|
18
|
+
|
|
19
|
+
:param str name: The name of this enum value
|
|
20
|
+
:param str value: The value of this enum value
|
|
21
|
+
:param str description: Optional. The description for this enum value
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
|
|
25
|
+
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
26
|
+
self.name: str = self.yaml_data["name"]
|
|
27
|
+
self.value: str = self.yaml_data["value"]
|
|
28
|
+
self.description: Optional[str] = self.yaml_data.get("description")
|
|
29
|
+
|
|
30
|
+
@classmethod
|
|
31
|
+
def from_yaml(
|
|
32
|
+
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
33
|
+
) -> "EnumValue":
|
|
34
|
+
"""Constructs an EnumValue from yaml data.
|
|
35
|
+
|
|
36
|
+
:param yaml_data: the yaml data from which we will construct this object
|
|
37
|
+
:type yaml_data: dict[str, Any]
|
|
38
|
+
|
|
39
|
+
:return: A created EnumValue
|
|
40
|
+
:rtype: ~autorest.models.EnumValue
|
|
41
|
+
"""
|
|
42
|
+
return cls(
|
|
43
|
+
yaml_data=yaml_data,
|
|
44
|
+
code_model=code_model,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class EnumType(BaseType):
|
|
49
|
+
"""Schema for enums that will be serialized.
|
|
50
|
+
|
|
51
|
+
:param yaml_data: the yaml data for this schema
|
|
52
|
+
:type yaml_data: dict[str, Any]
|
|
53
|
+
:param str description: The description of this enum
|
|
54
|
+
:param str name: The name of the enum.
|
|
55
|
+
:type element_type: ~autorest.models.PrimitiveType
|
|
56
|
+
:param values: List of the values for this enum
|
|
57
|
+
:type values: list[~autorest.models.EnumValue]
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
def __init__(
|
|
61
|
+
self,
|
|
62
|
+
yaml_data: Dict[str, Any],
|
|
63
|
+
code_model: "CodeModel",
|
|
64
|
+
values: List["EnumValue"],
|
|
65
|
+
value_type: BaseType,
|
|
66
|
+
) -> None:
|
|
67
|
+
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
68
|
+
self.name: str = yaml_data["name"]
|
|
69
|
+
self.values = values
|
|
70
|
+
self.value_type = value_type
|
|
71
|
+
|
|
72
|
+
def __lt__(self, other):
|
|
73
|
+
return self.name.lower() < other.name.lower()
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def serialization_type(self) -> str:
|
|
77
|
+
"""Returns the serialization value for msrest.
|
|
78
|
+
|
|
79
|
+
:return: The serialization value for msrest
|
|
80
|
+
:rtype: str
|
|
81
|
+
"""
|
|
82
|
+
return self.value_type.serialization_type
|
|
83
|
+
|
|
84
|
+
def description(
|
|
85
|
+
self, *, is_operation_file: bool # pylint: disable=unused-argument
|
|
86
|
+
) -> str:
|
|
87
|
+
possible_values = [self.get_declaration(v.value) for v in self.values]
|
|
88
|
+
if not possible_values:
|
|
89
|
+
return ""
|
|
90
|
+
if len(possible_values) == 1:
|
|
91
|
+
return possible_values[0]
|
|
92
|
+
if len(possible_values) == 2:
|
|
93
|
+
possible_values_str = " and ".join(possible_values)
|
|
94
|
+
else:
|
|
95
|
+
possible_values_str = (
|
|
96
|
+
", ".join(possible_values[: len(possible_values) - 1])
|
|
97
|
+
+ f", and {possible_values[-1]}"
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
enum_description = f"Known values are: {possible_values_str}."
|
|
101
|
+
return enum_description
|
|
102
|
+
|
|
103
|
+
def type_annotation(self, **kwargs: Any) -> str:
|
|
104
|
+
"""The python type used for type annotation
|
|
105
|
+
|
|
106
|
+
:return: The type annotation for this schema
|
|
107
|
+
:rtype: str
|
|
108
|
+
"""
|
|
109
|
+
if self.code_model.options["models_mode"]:
|
|
110
|
+
return (
|
|
111
|
+
f"Union[{self.value_type.type_annotation(**kwargs)},"
|
|
112
|
+
f' "_models.{self.name}"]'
|
|
113
|
+
)
|
|
114
|
+
return self.value_type.type_annotation(**kwargs)
|
|
115
|
+
|
|
116
|
+
def get_declaration(self, value: Any) -> str:
|
|
117
|
+
return self.value_type.get_declaration(value)
|
|
118
|
+
|
|
119
|
+
def docstring_text(self, **kwargs: Any) -> str:
|
|
120
|
+
if self.code_model.options["models_mode"]:
|
|
121
|
+
return self.name
|
|
122
|
+
return self.value_type.type_annotation(**kwargs)
|
|
123
|
+
|
|
124
|
+
def docstring_type(self, **kwargs: Any) -> str:
|
|
125
|
+
"""The python type used for RST syntax input and type annotation."""
|
|
126
|
+
if self.code_model.options["models_mode"]:
|
|
127
|
+
return f"{self.value_type.type_annotation(**kwargs)} or ~{self.code_model.namespace}.models.{self.name}"
|
|
128
|
+
return self.value_type.type_annotation(**kwargs)
|
|
129
|
+
|
|
130
|
+
def get_json_template_representation(
|
|
131
|
+
self,
|
|
132
|
+
*,
|
|
133
|
+
optional: bool = True,
|
|
134
|
+
client_default_value_declaration: Optional[str] = None,
|
|
135
|
+
description: Optional[str] = None,
|
|
136
|
+
) -> Any:
|
|
137
|
+
# for better display effect, use the only value instead of var type
|
|
138
|
+
return self.value_type.get_json_template_representation(
|
|
139
|
+
optional=optional,
|
|
140
|
+
client_default_value_declaration=client_default_value_declaration,
|
|
141
|
+
description=description,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def instance_check_template(self) -> str:
|
|
146
|
+
return self.value_type.instance_check_template
|
|
147
|
+
|
|
148
|
+
@classmethod
|
|
149
|
+
def from_yaml(
|
|
150
|
+
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
151
|
+
) -> "EnumType":
|
|
152
|
+
"""Constructs an EnumType from yaml data.
|
|
153
|
+
|
|
154
|
+
:param yaml_data: the yaml data from which we will construct this schema
|
|
155
|
+
:type yaml_data: dict[str, Any]
|
|
156
|
+
|
|
157
|
+
:return: A created EnumType
|
|
158
|
+
:rtype: ~autorest.models.EnumType
|
|
159
|
+
"""
|
|
160
|
+
from . import build_type
|
|
161
|
+
|
|
162
|
+
return cls(
|
|
163
|
+
yaml_data=yaml_data,
|
|
164
|
+
code_model=code_model,
|
|
165
|
+
value_type=build_type(yaml_data["valueType"], code_model),
|
|
166
|
+
values=[
|
|
167
|
+
EnumValue.from_yaml(value, code_model) for value in yaml_data["values"]
|
|
168
|
+
],
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
def imports(self, **kwargs: Any) -> FileImport:
|
|
172
|
+
is_operation_file = kwargs.pop("is_operation_file", False)
|
|
173
|
+
file_import = FileImport()
|
|
174
|
+
if self.code_model.options["models_mode"]:
|
|
175
|
+
file_import.add_submodule_import(
|
|
176
|
+
"typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
177
|
+
)
|
|
178
|
+
if not is_operation_file:
|
|
179
|
+
file_import.add_submodule_import(
|
|
180
|
+
"..",
|
|
181
|
+
"models",
|
|
182
|
+
ImportType.LOCAL,
|
|
183
|
+
TypingSection.TYPING,
|
|
184
|
+
alias="_models",
|
|
185
|
+
)
|
|
186
|
+
file_import.merge(
|
|
187
|
+
self.value_type.imports(is_operation_file=is_operation_file, **kwargs)
|
|
188
|
+
)
|
|
189
|
+
relative_path = kwargs.pop("relative_path", None)
|
|
190
|
+
if self.code_model.options["models_mode"] and relative_path:
|
|
191
|
+
# add import for enums in operations file
|
|
192
|
+
file_import.add_submodule_import(
|
|
193
|
+
relative_path, "models", ImportType.LOCAL, alias="_models"
|
|
194
|
+
)
|
|
195
|
+
return file_import
|
|
@@ -3,8 +3,11 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
-
from enum import Enum
|
|
7
|
-
from typing import Dict, List, Optional, Tuple, Union, Set, Mapping
|
|
6
|
+
from enum import Enum, auto
|
|
7
|
+
from typing import Dict, List, Optional, Tuple, Union, Set, Mapping, TYPE_CHECKING
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from .code_model import CodeModel
|
|
8
11
|
|
|
9
12
|
|
|
10
13
|
class ImportType(str, Enum):
|
|
@@ -20,6 +23,16 @@ class TypingSection(str, Enum):
|
|
|
20
23
|
TYPING = "typing" # never a typing import
|
|
21
24
|
|
|
22
25
|
|
|
26
|
+
class MsrestImportType(Enum):
|
|
27
|
+
Module = auto() # import _serialization.py or msrest.serialization as Module
|
|
28
|
+
Serializer = (
|
|
29
|
+
auto()
|
|
30
|
+
) # from _serialization.py or msrest.serialization import Serializer
|
|
31
|
+
SerializerDeserializer = (
|
|
32
|
+
auto()
|
|
33
|
+
) # from _serialization.py or msrest.serialization import Serializer and Deserializer
|
|
34
|
+
|
|
35
|
+
|
|
23
36
|
class ImportModel:
|
|
24
37
|
def __init__(
|
|
25
38
|
self,
|
|
@@ -147,6 +160,29 @@ class FileImport:
|
|
|
147
160
|
self._append_import(i)
|
|
148
161
|
self.type_definitions.update(file_import.type_definitions)
|
|
149
162
|
|
|
163
|
+
def define_mutable_mapping_type(self) -> None:
|
|
164
|
+
"""Helper function for defining the mutable mapping type"""
|
|
165
|
+
self.define_mypy_type(
|
|
166
|
+
"JSON",
|
|
167
|
+
"MutableMapping[str, Any] # pylint: disable=unsubscriptable-object",
|
|
168
|
+
None,
|
|
169
|
+
{
|
|
170
|
+
(3, 9): ImportModel(
|
|
171
|
+
TypingSection.CONDITIONAL,
|
|
172
|
+
ImportType.STDLIB,
|
|
173
|
+
"collections.abc",
|
|
174
|
+
submodule_name="MutableMapping",
|
|
175
|
+
),
|
|
176
|
+
None: ImportModel(
|
|
177
|
+
TypingSection.CONDITIONAL,
|
|
178
|
+
ImportType.STDLIB,
|
|
179
|
+
"typing",
|
|
180
|
+
submodule_name="MutableMapping",
|
|
181
|
+
),
|
|
182
|
+
},
|
|
183
|
+
)
|
|
184
|
+
self.add_submodule_import("typing", "Any", ImportType.STDLIB)
|
|
185
|
+
|
|
150
186
|
def to_dict(
|
|
151
187
|
self,
|
|
152
188
|
) -> Dict[
|
|
@@ -167,3 +203,45 @@ class FileImport:
|
|
|
167
203
|
i.import_type, dict()
|
|
168
204
|
).setdefault(i.module_name, set()).add(name_import)
|
|
169
205
|
return retval
|
|
206
|
+
|
|
207
|
+
def add_msrest_import(
|
|
208
|
+
self,
|
|
209
|
+
code_model: "CodeModel",
|
|
210
|
+
relative_path: str,
|
|
211
|
+
msrest_import_type: MsrestImportType,
|
|
212
|
+
typing_section: TypingSection,
|
|
213
|
+
):
|
|
214
|
+
if code_model.options["client_side_validation"]:
|
|
215
|
+
if msrest_import_type == MsrestImportType.Module:
|
|
216
|
+
self.add_import(
|
|
217
|
+
"msrest.serialization", ImportType.AZURECORE, typing_section
|
|
218
|
+
)
|
|
219
|
+
else:
|
|
220
|
+
self.add_submodule_import(
|
|
221
|
+
"msrest", "Serializer", ImportType.THIRDPARTY, typing_section
|
|
222
|
+
)
|
|
223
|
+
if msrest_import_type == MsrestImportType.SerializerDeserializer:
|
|
224
|
+
self.add_submodule_import(
|
|
225
|
+
"msrest", "Deserializer", ImportType.THIRDPARTY, typing_section
|
|
226
|
+
)
|
|
227
|
+
else:
|
|
228
|
+
if code_model.options["multiapi"]:
|
|
229
|
+
relative_path += "."
|
|
230
|
+
if msrest_import_type == MsrestImportType.Module:
|
|
231
|
+
self.add_submodule_import(
|
|
232
|
+
relative_path, "_serialization", ImportType.LOCAL, typing_section
|
|
233
|
+
)
|
|
234
|
+
else:
|
|
235
|
+
self.add_submodule_import(
|
|
236
|
+
f"{relative_path}_serialization",
|
|
237
|
+
"Serializer",
|
|
238
|
+
ImportType.LOCAL,
|
|
239
|
+
typing_section,
|
|
240
|
+
)
|
|
241
|
+
if msrest_import_type == MsrestImportType.SerializerDeserializer:
|
|
242
|
+
self.add_submodule_import(
|
|
243
|
+
f"{relative_path}_serialization",
|
|
244
|
+
"Deserializer",
|
|
245
|
+
ImportType.LOCAL,
|
|
246
|
+
typing_section,
|
|
247
|
+
)
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
|
+
# license information.
|
|
5
|
+
# --------------------------------------------------------------------------
|
|
6
|
+
from typing import Any, Dict, Optional, Union, TYPE_CHECKING, List
|
|
7
|
+
from .base_type import BaseType
|
|
8
|
+
from .imports import FileImport, ImportType, TypingSection
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from .code_model import CodeModel
|
|
12
|
+
from .model_type import ModelType
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ListType(BaseType):
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
yaml_data: Dict[str, Any],
|
|
19
|
+
code_model: "CodeModel",
|
|
20
|
+
element_type: BaseType,
|
|
21
|
+
) -> None:
|
|
22
|
+
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
23
|
+
self.element_type = element_type
|
|
24
|
+
self.max_items: Optional[int] = yaml_data.get("maxItems")
|
|
25
|
+
self.min_items: Optional[int] = yaml_data.get("minItems")
|
|
26
|
+
self.unique_items: bool = yaml_data.get("uniqueItems", False)
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def serialization_type(self) -> str:
|
|
30
|
+
return f"[{self.element_type.serialization_type}]"
|
|
31
|
+
|
|
32
|
+
def type_annotation(self, **kwargs: Any) -> str:
|
|
33
|
+
if self.code_model.options["version_tolerant"] and self.element_type.is_xml:
|
|
34
|
+
# this means we're version tolerant XML, we just return the XML element
|
|
35
|
+
return self.element_type.type_annotation(**kwargs)
|
|
36
|
+
return f"List[{self.element_type.type_annotation(**kwargs)}]"
|
|
37
|
+
|
|
38
|
+
def description(self, *, is_operation_file: bool) -> str:
|
|
39
|
+
return "" if is_operation_file else self.yaml_data.get("description", "")
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def xml_serialization_ctxt(self) -> Optional[str]:
|
|
43
|
+
attrs_list = []
|
|
44
|
+
base_xml_map = super().xml_serialization_ctxt
|
|
45
|
+
if base_xml_map:
|
|
46
|
+
attrs_list.append(base_xml_map)
|
|
47
|
+
|
|
48
|
+
# Attribute at the list level
|
|
49
|
+
if self.xml_metadata.get("wrapped", False):
|
|
50
|
+
attrs_list.append("'wrapped': True")
|
|
51
|
+
|
|
52
|
+
# Attributes of the items
|
|
53
|
+
item_xml_metadata = self.element_type.xml_metadata
|
|
54
|
+
if item_xml_metadata.get("name"):
|
|
55
|
+
attrs_list.append(f"'itemsName': '{item_xml_metadata['name']}'")
|
|
56
|
+
if item_xml_metadata.get("prefix", False):
|
|
57
|
+
attrs_list.append(f"'itemsPrefix': '{item_xml_metadata['prefix']}'")
|
|
58
|
+
if item_xml_metadata.get("namespace", False):
|
|
59
|
+
attrs_list.append(f"'itemsNs': '{item_xml_metadata['namespace']}'")
|
|
60
|
+
|
|
61
|
+
return ", ".join(attrs_list)
|
|
62
|
+
|
|
63
|
+
def docstring_type(self, **kwargs: Any) -> str:
|
|
64
|
+
if (
|
|
65
|
+
self.code_model.options["version_tolerant"]
|
|
66
|
+
and self.element_type.xml_metadata
|
|
67
|
+
):
|
|
68
|
+
# this means we're version tolerant XML, we just return the XML element
|
|
69
|
+
return self.element_type.docstring_type(**kwargs)
|
|
70
|
+
return f"list[{self.element_type.docstring_type(**kwargs)}]"
|
|
71
|
+
|
|
72
|
+
def docstring_text(self, **kwargs: Any) -> str:
|
|
73
|
+
if (
|
|
74
|
+
self.code_model.options["version_tolerant"]
|
|
75
|
+
and self.element_type.xml_metadata
|
|
76
|
+
):
|
|
77
|
+
# this means we're version tolerant XML, we just return the XML element
|
|
78
|
+
return self.element_type.docstring_text(**kwargs)
|
|
79
|
+
return f"list of {self.element_type.docstring_text(**kwargs)}"
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def validation(self) -> Optional[Dict[str, Union[bool, int, str]]]:
|
|
83
|
+
validation: Dict[str, Union[bool, int, str]] = {}
|
|
84
|
+
if self.max_items:
|
|
85
|
+
validation["max_items"] = self.max_items
|
|
86
|
+
validation["min_items"] = self.min_items or 0
|
|
87
|
+
if self.min_items:
|
|
88
|
+
validation["min_items"] = self.min_items
|
|
89
|
+
if self.unique_items:
|
|
90
|
+
validation["unique"] = True
|
|
91
|
+
return validation or None
|
|
92
|
+
|
|
93
|
+
def get_json_template_representation(
|
|
94
|
+
self,
|
|
95
|
+
*,
|
|
96
|
+
optional: bool = True,
|
|
97
|
+
client_default_value_declaration: Optional[str] = None,
|
|
98
|
+
description: Optional[str] = None,
|
|
99
|
+
) -> Any:
|
|
100
|
+
return [
|
|
101
|
+
self.element_type.get_json_template_representation(
|
|
102
|
+
optional=optional,
|
|
103
|
+
client_default_value_declaration=client_default_value_declaration,
|
|
104
|
+
description=description,
|
|
105
|
+
)
|
|
106
|
+
]
|
|
107
|
+
|
|
108
|
+
def get_polymorphic_subtypes(self, polymorphic_subtypes: List["ModelType"]) -> None:
|
|
109
|
+
from .model_type import ModelType
|
|
110
|
+
|
|
111
|
+
if isinstance(self.element_type, ModelType):
|
|
112
|
+
is_polymorphic_subtype = (
|
|
113
|
+
self.element_type.discriminator_value
|
|
114
|
+
and not self.element_type.discriminated_subtypes
|
|
115
|
+
)
|
|
116
|
+
if (
|
|
117
|
+
self.element_type.name not in (m.name for m in polymorphic_subtypes)
|
|
118
|
+
and is_polymorphic_subtype
|
|
119
|
+
):
|
|
120
|
+
polymorphic_subtypes.append(self.element_type)
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def instance_check_template(self) -> str:
|
|
124
|
+
return "isinstance({}, list)"
|
|
125
|
+
|
|
126
|
+
@classmethod
|
|
127
|
+
def from_yaml(
|
|
128
|
+
cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
129
|
+
) -> "ListType":
|
|
130
|
+
from . import build_type
|
|
131
|
+
|
|
132
|
+
return cls(
|
|
133
|
+
yaml_data=yaml_data,
|
|
134
|
+
code_model=code_model,
|
|
135
|
+
element_type=build_type(
|
|
136
|
+
yaml_data=yaml_data["elementType"], code_model=code_model
|
|
137
|
+
),
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
def imports(self, **kwargs: Any) -> FileImport:
|
|
141
|
+
file_import = FileImport()
|
|
142
|
+
if not (
|
|
143
|
+
self.code_model.options["version_tolerant"] and self.element_type.is_xml
|
|
144
|
+
):
|
|
145
|
+
file_import.add_submodule_import(
|
|
146
|
+
"typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
147
|
+
)
|
|
148
|
+
file_import.merge(self.element_type.imports(**kwargs))
|
|
149
|
+
return file_import
|