@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
|
@@ -6,21 +6,24 @@
|
|
|
6
6
|
import logging
|
|
7
7
|
import datetime
|
|
8
8
|
from enum import Enum
|
|
9
|
-
from typing import cast, Any, Dict, List, Optional, Union
|
|
9
|
+
from typing import cast, Any, Dict, List, Optional, Union, TYPE_CHECKING
|
|
10
10
|
|
|
11
11
|
from .base_schema import BaseSchema
|
|
12
12
|
from .imports import FileImport, ImportType, TypingSection
|
|
13
13
|
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from .code_model import CodeModel
|
|
16
|
+
|
|
14
17
|
|
|
15
18
|
_LOGGER = logging.getLogger(__name__)
|
|
16
19
|
|
|
20
|
+
|
|
17
21
|
class RawString(object):
|
|
18
22
|
def __init__(self, string: str) -> None:
|
|
19
23
|
self.string = string
|
|
20
24
|
|
|
21
25
|
def __repr__(self) -> str:
|
|
22
|
-
return "r'{}'".format(self.string.replace('
|
|
23
|
-
|
|
26
|
+
return "r'{}'".format(self.string.replace("'", "\\'"))
|
|
24
27
|
|
|
25
28
|
|
|
26
29
|
class PrimitiveSchema(BaseSchema):
|
|
@@ -39,8 +42,9 @@ class PrimitiveSchema(BaseSchema):
|
|
|
39
42
|
def docstring_type(self) -> str:
|
|
40
43
|
return self._to_python_type()
|
|
41
44
|
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
def type_annotation(
|
|
46
|
+
self, *, is_operation_file: bool = False # pylint: disable=unused-argument
|
|
47
|
+
) -> str:
|
|
44
48
|
return self.docstring_type
|
|
45
49
|
|
|
46
50
|
@property
|
|
@@ -70,28 +74,18 @@ class PrimitiveSchema(BaseSchema):
|
|
|
70
74
|
def get_json_template_representation(self, **kwargs: Any) -> Any:
|
|
71
75
|
if self.default_value:
|
|
72
76
|
kwargs["default_value_declaration"] = kwargs.get(
|
|
73
|
-
"default_value_declaration",
|
|
74
|
-
self.get_declaration(self.default_value)
|
|
77
|
+
"default_value_declaration", self.get_declaration(self.default_value)
|
|
75
78
|
)
|
|
76
|
-
return self._add_optional_and_default_value_template_representation(
|
|
77
|
-
**kwargs
|
|
78
|
-
)
|
|
79
|
+
return self._add_optional_and_default_value_template_representation(**kwargs)
|
|
79
80
|
|
|
80
81
|
@property
|
|
81
82
|
def default_template_representation_declaration(self) -> str:
|
|
82
83
|
return self.get_declaration(self.docstring_type)
|
|
83
84
|
|
|
84
|
-
def get_files_and_data_template_representation(self, **kwargs: Any) -> Any:
|
|
85
|
-
"""Template of what the files input should look like
|
|
86
|
-
"""
|
|
87
|
-
return self._add_optional_and_default_value_template_representation(
|
|
88
|
-
**kwargs
|
|
89
|
-
)
|
|
90
85
|
|
|
91
86
|
class IOSchema(PrimitiveSchema):
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
super(IOSchema, self).__init__(namespace=namespace, yaml_data=yaml_data)
|
|
87
|
+
def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
|
|
88
|
+
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
95
89
|
self.type = "IO"
|
|
96
90
|
|
|
97
91
|
@property
|
|
@@ -102,8 +96,9 @@ class IOSchema(PrimitiveSchema):
|
|
|
102
96
|
def docstring_type(self) -> str:
|
|
103
97
|
return self.type
|
|
104
98
|
|
|
105
|
-
|
|
106
|
-
|
|
99
|
+
def type_annotation(
|
|
100
|
+
self, *, is_operation_file: bool = False # pylint: disable=unused-argument
|
|
101
|
+
) -> str:
|
|
107
102
|
return self.docstring_type
|
|
108
103
|
|
|
109
104
|
@property
|
|
@@ -116,9 +111,12 @@ class IOSchema(PrimitiveSchema):
|
|
|
116
111
|
|
|
117
112
|
def imports(self) -> FileImport:
|
|
118
113
|
file_import = FileImport()
|
|
119
|
-
file_import.add_submodule_import(
|
|
114
|
+
file_import.add_submodule_import(
|
|
115
|
+
"typing", "IO", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
116
|
+
)
|
|
120
117
|
return file_import
|
|
121
118
|
|
|
119
|
+
|
|
122
120
|
class AnySchema(PrimitiveSchema):
|
|
123
121
|
@property
|
|
124
122
|
def serialization_type(self) -> str:
|
|
@@ -128,8 +126,9 @@ class AnySchema(PrimitiveSchema):
|
|
|
128
126
|
def docstring_type(self) -> str:
|
|
129
127
|
return "any"
|
|
130
128
|
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
def type_annotation(
|
|
130
|
+
self, *, is_operation_file: bool = False # pylint: disable=unused-argument
|
|
131
|
+
) -> str:
|
|
133
132
|
return "Any"
|
|
134
133
|
|
|
135
134
|
@property
|
|
@@ -138,23 +137,15 @@ class AnySchema(PrimitiveSchema):
|
|
|
138
137
|
|
|
139
138
|
def imports(self) -> FileImport:
|
|
140
139
|
file_import = FileImport()
|
|
141
|
-
file_import.add_submodule_import(
|
|
140
|
+
file_import.add_submodule_import(
|
|
141
|
+
"typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
142
|
+
)
|
|
142
143
|
return file_import
|
|
143
144
|
|
|
144
|
-
class JSONSchema(AnySchema):
|
|
145
|
-
|
|
146
|
-
@property
|
|
147
|
-
def docstring_type(self) -> str:
|
|
148
|
-
return "JSONType"
|
|
149
|
-
|
|
150
|
-
@property
|
|
151
|
-
def type_annotation(self) -> str:
|
|
152
|
-
return "JSONType"
|
|
153
|
-
|
|
154
145
|
|
|
155
146
|
class NumberSchema(PrimitiveSchema):
|
|
156
|
-
def __init__(self,
|
|
157
|
-
super(
|
|
147
|
+
def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
|
|
148
|
+
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
158
149
|
self.precision = cast(int, yaml_data["precision"])
|
|
159
150
|
self.multiple = cast(int, yaml_data.get("multipleOf"))
|
|
160
151
|
self.maximum = cast(int, yaml_data.get("maximum"))
|
|
@@ -165,10 +156,18 @@ class NumberSchema(PrimitiveSchema):
|
|
|
165
156
|
@property
|
|
166
157
|
def serialization_constraints(self) -> List[str]:
|
|
167
158
|
validation_constraints = [
|
|
168
|
-
f"maximum_ex={self.maximum}"
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
f"
|
|
159
|
+
f"maximum_ex={self.maximum}"
|
|
160
|
+
if self.maximum is not None and self.exclusive_maximum
|
|
161
|
+
else None,
|
|
162
|
+
f"maximum={self.maximum}"
|
|
163
|
+
if self.maximum is not None and not self.exclusive_maximum
|
|
164
|
+
else None,
|
|
165
|
+
f"minimum_ex={self.minimum}"
|
|
166
|
+
if self.minimum is not None and self.exclusive_minimum
|
|
167
|
+
else None,
|
|
168
|
+
f"minimum={self.minimum}"
|
|
169
|
+
if self.minimum is not None and not self.exclusive_minimum
|
|
170
|
+
else None,
|
|
172
171
|
f"multiple={self.multiple}" if self.multiple else None,
|
|
173
172
|
]
|
|
174
173
|
return [x for x in validation_constraints if x is not None]
|
|
@@ -206,8 +205,9 @@ class NumberSchema(PrimitiveSchema):
|
|
|
206
205
|
return "int"
|
|
207
206
|
return "float"
|
|
208
207
|
|
|
209
|
-
|
|
210
|
-
|
|
208
|
+
def type_annotation(
|
|
209
|
+
self, *, is_operation_file: bool = False # pylint: disable=unused-argument
|
|
210
|
+
) -> str:
|
|
211
211
|
python_type = self.docstring_type
|
|
212
212
|
if python_type == "long":
|
|
213
213
|
return "int"
|
|
@@ -218,13 +218,18 @@ class NumberSchema(PrimitiveSchema):
|
|
|
218
218
|
default_value = 0 if self.docstring_type == "int" else 0.0
|
|
219
219
|
return self.get_declaration(default_value)
|
|
220
220
|
|
|
221
|
-
class StringSchema(PrimitiveSchema):
|
|
222
221
|
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
class StringSchema(PrimitiveSchema):
|
|
223
|
+
def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
|
|
224
|
+
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
225
225
|
self.max_length = cast(int, yaml_data.get("maxLength"))
|
|
226
226
|
self.min_length = cast(
|
|
227
|
-
int,
|
|
227
|
+
int,
|
|
228
|
+
(
|
|
229
|
+
yaml_data.get("minLength", 0)
|
|
230
|
+
if yaml_data.get("maxLength")
|
|
231
|
+
else yaml_data.get("minLength")
|
|
232
|
+
),
|
|
228
233
|
)
|
|
229
234
|
self.pattern = cast(str, yaml_data.get("pattern"))
|
|
230
235
|
|
|
@@ -254,8 +259,8 @@ class StringSchema(PrimitiveSchema):
|
|
|
254
259
|
|
|
255
260
|
|
|
256
261
|
class DatetimeSchema(PrimitiveSchema):
|
|
257
|
-
def __init__(self,
|
|
258
|
-
super(
|
|
262
|
+
def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
|
|
263
|
+
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
259
264
|
self.format = self.Formats(yaml_data["format"])
|
|
260
265
|
|
|
261
266
|
class Formats(str, Enum):
|
|
@@ -264,15 +269,19 @@ class DatetimeSchema(PrimitiveSchema):
|
|
|
264
269
|
|
|
265
270
|
@property
|
|
266
271
|
def serialization_type(self) -> str:
|
|
267
|
-
formats_to_attribute_type = {
|
|
272
|
+
formats_to_attribute_type = {
|
|
273
|
+
self.Formats.datetime: "iso-8601",
|
|
274
|
+
self.Formats.rfc1123: "rfc-1123",
|
|
275
|
+
}
|
|
268
276
|
return formats_to_attribute_type[self.format]
|
|
269
277
|
|
|
270
278
|
@property
|
|
271
279
|
def docstring_type(self) -> str:
|
|
272
|
-
return "~" + self.type_annotation
|
|
280
|
+
return "~" + self.type_annotation()
|
|
273
281
|
|
|
274
|
-
|
|
275
|
-
|
|
282
|
+
def type_annotation(
|
|
283
|
+
self, *, is_operation_file: bool = False # pylint: disable=unused-argument
|
|
284
|
+
) -> str:
|
|
276
285
|
return "datetime.datetime"
|
|
277
286
|
|
|
278
287
|
@property
|
|
@@ -294,6 +303,7 @@ class DatetimeSchema(PrimitiveSchema):
|
|
|
294
303
|
def default_template_representation_declaration(self):
|
|
295
304
|
return self.get_declaration(datetime.datetime(2020, 2, 20))
|
|
296
305
|
|
|
306
|
+
|
|
297
307
|
class TimeSchema(PrimitiveSchema):
|
|
298
308
|
@property
|
|
299
309
|
def serialization_type(self) -> str:
|
|
@@ -301,10 +311,11 @@ class TimeSchema(PrimitiveSchema):
|
|
|
301
311
|
|
|
302
312
|
@property
|
|
303
313
|
def docstring_type(self) -> str:
|
|
304
|
-
return "~" + self.type_annotation
|
|
314
|
+
return "~" + self.type_annotation()
|
|
305
315
|
|
|
306
|
-
|
|
307
|
-
|
|
316
|
+
def type_annotation(
|
|
317
|
+
self, *, is_operation_file: bool = False # pylint: disable=unused-argument
|
|
318
|
+
) -> str:
|
|
308
319
|
return "datetime.time"
|
|
309
320
|
|
|
310
321
|
@property
|
|
@@ -334,10 +345,11 @@ class UnixTimeSchema(PrimitiveSchema):
|
|
|
334
345
|
|
|
335
346
|
@property
|
|
336
347
|
def docstring_type(self) -> str:
|
|
337
|
-
return "~" + self.type_annotation
|
|
348
|
+
return "~" + self.type_annotation()
|
|
338
349
|
|
|
339
|
-
|
|
340
|
-
|
|
350
|
+
def type_annotation(
|
|
351
|
+
self, *, is_operation_file: bool = False # pylint: disable=unused-argument
|
|
352
|
+
) -> str:
|
|
341
353
|
return "datetime.datetime"
|
|
342
354
|
|
|
343
355
|
@property
|
|
@@ -367,10 +379,11 @@ class DateSchema(PrimitiveSchema):
|
|
|
367
379
|
|
|
368
380
|
@property
|
|
369
381
|
def docstring_type(self) -> str:
|
|
370
|
-
return "~" + self.type_annotation
|
|
382
|
+
return "~" + self.type_annotation()
|
|
371
383
|
|
|
372
|
-
|
|
373
|
-
|
|
384
|
+
def type_annotation(
|
|
385
|
+
self, *, is_operation_file: bool = False # pylint: disable=unused-argument
|
|
386
|
+
) -> str:
|
|
374
387
|
return "datetime.date"
|
|
375
388
|
|
|
376
389
|
@property
|
|
@@ -400,10 +413,11 @@ class DurationSchema(PrimitiveSchema):
|
|
|
400
413
|
|
|
401
414
|
@property
|
|
402
415
|
def docstring_type(self) -> str:
|
|
403
|
-
return "~" + self.type_annotation
|
|
416
|
+
return "~" + self.type_annotation()
|
|
404
417
|
|
|
405
|
-
|
|
406
|
-
|
|
418
|
+
def type_annotation(
|
|
419
|
+
self, *, is_operation_file: bool = False # pylint: disable=unused-argument
|
|
420
|
+
) -> str:
|
|
407
421
|
return "datetime.timedelta"
|
|
408
422
|
|
|
409
423
|
@property
|
|
@@ -427,8 +441,8 @@ class DurationSchema(PrimitiveSchema):
|
|
|
427
441
|
|
|
428
442
|
|
|
429
443
|
class ByteArraySchema(PrimitiveSchema):
|
|
430
|
-
def __init__(self,
|
|
431
|
-
super(
|
|
444
|
+
def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
|
|
445
|
+
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
432
446
|
self.format = self.Formats(yaml_data["format"])
|
|
433
447
|
|
|
434
448
|
class Formats(str, Enum):
|
|
@@ -453,7 +467,9 @@ class ByteArraySchema(PrimitiveSchema):
|
|
|
453
467
|
return f'bytearray("{value}", encoding="utf-8")'
|
|
454
468
|
|
|
455
469
|
|
|
456
|
-
def get_primitive_schema(
|
|
470
|
+
def get_primitive_schema(
|
|
471
|
+
yaml_data: Dict[str, Any], code_model: "CodeModel"
|
|
472
|
+
) -> "PrimitiveSchema":
|
|
457
473
|
mapping = {
|
|
458
474
|
"integer": NumberSchema,
|
|
459
475
|
"number": NumberSchema,
|
|
@@ -467,10 +483,13 @@ def get_primitive_schema(namespace: str, yaml_data: Dict[str, Any]) -> "Primitiv
|
|
|
467
483
|
"byte-array": ByteArraySchema,
|
|
468
484
|
"any": AnySchema,
|
|
469
485
|
"any-object": AnySchema,
|
|
470
|
-
"binary": IOSchema
|
|
486
|
+
"binary": IOSchema,
|
|
471
487
|
}
|
|
472
488
|
schema_type = yaml_data["type"]
|
|
473
489
|
primitive_schema = cast(
|
|
474
|
-
PrimitiveSchema,
|
|
490
|
+
PrimitiveSchema,
|
|
491
|
+
mapping.get(schema_type, PrimitiveSchema).from_yaml(
|
|
492
|
+
yaml_data=yaml_data, code_model=code_model
|
|
493
|
+
),
|
|
475
494
|
)
|
|
476
495
|
return primitive_schema
|
|
@@ -3,7 +3,7 @@
|
|
|
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 cast, Any, Dict, Union, List, Optional
|
|
6
|
+
from typing import cast, Any, Dict, Union, List, Optional, TYPE_CHECKING
|
|
7
7
|
|
|
8
8
|
from .base_model import BaseModel
|
|
9
9
|
from .constant_schema import ConstantSchema
|
|
@@ -11,19 +11,24 @@ from .imports import FileImport, ImportType, TypingSection
|
|
|
11
11
|
from .base_schema import BaseSchema
|
|
12
12
|
from .enum_schema import EnumSchema
|
|
13
13
|
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from .code_model import CodeModel
|
|
16
|
+
|
|
17
|
+
|
|
14
18
|
class Property(BaseModel): # pylint: disable=too-many-instance-attributes
|
|
15
19
|
def __init__(
|
|
16
20
|
self,
|
|
17
21
|
yaml_data: Dict[str, Any],
|
|
22
|
+
code_model: "CodeModel",
|
|
18
23
|
name: str,
|
|
19
24
|
schema: BaseSchema,
|
|
20
25
|
original_swagger_name: str,
|
|
21
26
|
*,
|
|
22
27
|
flattened_names: Optional[List[str]] = None,
|
|
23
28
|
description: Optional[str] = None,
|
|
24
|
-
client_default_value: Optional[Any] = None
|
|
29
|
+
client_default_value: Optional[Any] = None,
|
|
25
30
|
) -> None:
|
|
26
|
-
super().__init__(yaml_data)
|
|
31
|
+
super().__init__(yaml_data, code_model)
|
|
27
32
|
self.name = name
|
|
28
33
|
self.schema = schema
|
|
29
34
|
self.original_swagger_name = original_swagger_name
|
|
@@ -35,15 +40,18 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
|
|
|
35
40
|
self.client_default_value = client_default_value
|
|
36
41
|
self.description = self._create_description(description, yaml_data)
|
|
37
42
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
def _create_description(
|
|
44
|
+
self, description_input: Optional[str], yaml_data: Dict[str, Any]
|
|
45
|
+
) -> str:
|
|
46
|
+
description: str = (
|
|
47
|
+
description_input or yaml_data["language"]["python"]["description"]
|
|
48
|
+
)
|
|
41
49
|
if description and description[-1] != ".":
|
|
42
50
|
description += "."
|
|
43
51
|
if self.name == "tags":
|
|
44
52
|
description = "A set of tags. " + description
|
|
45
53
|
if self.constant:
|
|
46
|
-
description += f
|
|
54
|
+
description += f" Has constant value: {self.constant_declaration}."
|
|
47
55
|
elif self.required:
|
|
48
56
|
if description:
|
|
49
57
|
description = "Required. " + description
|
|
@@ -51,16 +59,19 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
|
|
|
51
59
|
description = "Required. "
|
|
52
60
|
elif isinstance(self.schema, ConstantSchema):
|
|
53
61
|
description += (
|
|
54
|
-
f" The only acceptable values to pass in are None and {self.constant_declaration}. "
|
|
55
|
-
f"The default value is {self.default_value_declaration}."
|
|
62
|
+
f" The only acceptable values to pass in are None and {self.constant_declaration}. "
|
|
63
|
+
+ f"The default value is {self.default_value_declaration}."
|
|
56
64
|
)
|
|
57
65
|
if self.is_discriminator:
|
|
58
66
|
description += "Constant filled by server. "
|
|
59
67
|
if isinstance(self.schema, EnumSchema):
|
|
60
|
-
values = [
|
|
68
|
+
values = [
|
|
69
|
+
self.schema.enum_type.get_declaration(v.value)
|
|
70
|
+
for v in self.schema.values
|
|
71
|
+
]
|
|
61
72
|
if description and description[-1] != " ":
|
|
62
73
|
description += " "
|
|
63
|
-
description += "
|
|
74
|
+
description += "Known values are: {}.".format(", ".join(values))
|
|
64
75
|
if self.schema.default_value:
|
|
65
76
|
description += f' Default value: "{self.schema.default_value}".'
|
|
66
77
|
return description
|
|
@@ -70,9 +81,9 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
|
|
|
70
81
|
# this bool doesn't consider you to be constant if you are a discriminator
|
|
71
82
|
# you also have to be required to be considered a constant
|
|
72
83
|
return (
|
|
73
|
-
isinstance(self.schema, ConstantSchema)
|
|
74
|
-
self.required
|
|
75
|
-
not self.is_discriminator
|
|
84
|
+
isinstance(self.schema, ConstantSchema)
|
|
85
|
+
and self.required
|
|
86
|
+
and not self.is_discriminator
|
|
76
87
|
)
|
|
77
88
|
|
|
78
89
|
@property
|
|
@@ -85,29 +96,36 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
|
|
|
85
96
|
if self.constant:
|
|
86
97
|
retval["constant"] = True
|
|
87
98
|
if self.schema.validation_map:
|
|
88
|
-
validation_map_from_schema = cast(
|
|
99
|
+
validation_map_from_schema = cast(
|
|
100
|
+
Dict[str, Union[bool, int, str]], self.schema.validation_map
|
|
101
|
+
)
|
|
89
102
|
retval.update(validation_map_from_schema)
|
|
90
103
|
return retval or None
|
|
91
104
|
|
|
92
105
|
@property
|
|
93
106
|
def escaped_swagger_name(self) -> str:
|
|
94
|
-
"""Return the RestAPI name correctly escaped for serialization.
|
|
95
|
-
"""
|
|
107
|
+
"""Return the RestAPI name correctly escaped for serialization."""
|
|
96
108
|
if self.flattened_names:
|
|
97
109
|
return ".".join(n.replace(".", "\\\\.") for n in self.flattened_names)
|
|
98
110
|
return self.original_swagger_name.replace(".", "\\\\.")
|
|
99
111
|
|
|
100
112
|
@classmethod
|
|
101
|
-
def from_yaml(
|
|
113
|
+
def from_yaml(
|
|
114
|
+
cls,
|
|
115
|
+
yaml_data: Dict[str, Any],
|
|
116
|
+
code_model: "CodeModel",
|
|
117
|
+
*,
|
|
118
|
+
has_additional_properties: Optional[bool] = None,
|
|
119
|
+
) -> "Property":
|
|
102
120
|
from . import build_schema # pylint: disable=import-outside-toplevel
|
|
103
121
|
|
|
104
122
|
name = yaml_data["language"]["python"]["name"]
|
|
105
|
-
has_additional_properties = kwargs.pop("has_additional_properties", None)
|
|
106
123
|
if name == "additional_properties" and has_additional_properties:
|
|
107
124
|
name = "additional_properties1"
|
|
108
|
-
schema = build_schema(yaml_data=yaml_data["schema"],
|
|
125
|
+
schema = build_schema(yaml_data=yaml_data["schema"], code_model=code_model)
|
|
109
126
|
return cls(
|
|
110
127
|
yaml_data=yaml_data,
|
|
128
|
+
code_model=code_model,
|
|
111
129
|
name=name,
|
|
112
130
|
schema=schema,
|
|
113
131
|
original_swagger_name=yaml_data["serializedName"],
|
|
@@ -126,7 +144,7 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
|
|
|
126
144
|
return self.schema.get_declaration(self.schema.value)
|
|
127
145
|
raise ValueError(
|
|
128
146
|
"Trying to get constant declaration for a schema that is not ConstantSchema"
|
|
129
|
-
|
|
147
|
+
)
|
|
130
148
|
raise ValueError("Trying to get a declaration for a schema that doesn't exist")
|
|
131
149
|
|
|
132
150
|
@property
|
|
@@ -149,26 +167,26 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
|
|
|
149
167
|
return self.schema.get_declaration(self.client_default_value)
|
|
150
168
|
return self.schema.default_value_declaration
|
|
151
169
|
|
|
152
|
-
|
|
153
|
-
def type_annotation(self) -> str:
|
|
170
|
+
def type_annotation(self, *, is_operation_file: bool = False) -> str:
|
|
154
171
|
if self.required:
|
|
155
|
-
return self.schema.type_annotation
|
|
156
|
-
return f"Optional[{self.schema.type_annotation}]"
|
|
172
|
+
return self.schema.type_annotation(is_operation_file=is_operation_file)
|
|
173
|
+
return f"Optional[{self.schema.type_annotation(is_operation_file=is_operation_file)}]"
|
|
157
174
|
|
|
158
175
|
def get_json_template_representation(self, **kwargs: Any) -> Any:
|
|
159
176
|
kwargs["optional"] = not self.required
|
|
160
177
|
if self.default_value:
|
|
161
|
-
kwargs["default_value_declaration"] = self.schema.get_declaration(
|
|
178
|
+
kwargs["default_value_declaration"] = self.schema.get_declaration(
|
|
179
|
+
self.default_value
|
|
180
|
+
)
|
|
162
181
|
if self.description:
|
|
163
182
|
kwargs["description"] = self.description
|
|
164
183
|
return self.schema.get_json_template_representation(**kwargs)
|
|
165
184
|
|
|
166
|
-
def get_files_and_data_template_representation(self, **kwargs: Any) -> Any:
|
|
167
|
-
kwargs["optional"] = not self.required
|
|
168
|
-
return self.schema.get_files_and_data_template_representation(**kwargs)
|
|
169
|
-
|
|
170
185
|
def model_file_imports(self) -> FileImport:
|
|
171
186
|
file_import = self.schema.model_file_imports()
|
|
172
187
|
if not self.required:
|
|
173
|
-
file_import.add_submodule_import(
|
|
188
|
+
file_import.add_submodule_import(
|
|
189
|
+
"typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
190
|
+
)
|
|
191
|
+
file_import.merge(self.schema.model_file_imports())
|
|
174
192
|
return file_import
|