@autorest/python 6.2.11 → 6.2.15
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/__init__.py +7 -5
- package/autorest/_utils.py +7 -1
- package/autorest/black/__init__.py +6 -1
- package/autorest/codegen/__init__.py +1 -1
- package/autorest/codegen/models/__init__.py +8 -2
- package/autorest/codegen/models/base.py +4 -13
- package/autorest/codegen/models/client.py +9 -11
- package/autorest/codegen/models/code_model.py +3 -3
- package/autorest/codegen/models/combined_type.py +4 -3
- package/autorest/codegen/models/credential_types.py +7 -14
- package/autorest/codegen/models/dictionary_type.py +1 -1
- package/autorest/codegen/models/imports.py +3 -3
- package/autorest/codegen/models/lro_operation.py +5 -5
- package/autorest/codegen/models/model_type.py +89 -47
- package/autorest/codegen/models/operation.py +8 -8
- package/autorest/codegen/models/operation_group.py +3 -1
- package/autorest/codegen/models/paging_operation.py +2 -2
- package/autorest/codegen/models/parameter.py +27 -6
- package/autorest/codegen/models/parameter_list.py +1 -9
- package/autorest/codegen/models/primitive_types.py +1 -1
- package/autorest/codegen/models/property.py +15 -3
- package/autorest/codegen/models/response.py +2 -2
- package/autorest/codegen/serializers/__init__.py +2 -2
- package/autorest/codegen/serializers/builder_serializer.py +64 -28
- package/autorest/codegen/serializers/client_serializer.py +6 -4
- package/autorest/codegen/serializers/general_serializer.py +7 -2
- package/autorest/codegen/serializers/model_serializer.py +14 -4
- package/autorest/codegen/serializers/sample_serializer.py +2 -6
- package/autorest/codegen/templates/config.py.jinja2 +25 -6
- package/autorest/codegen/templates/enum.py.jinja2 +2 -2
- package/autorest/codegen/templates/metadata.json.jinja2 +18 -9
- package/autorest/codegen/templates/model_base.py.jinja2 +74 -63
- package/autorest/codegen/templates/model_container.py.jinja2 +2 -2
- package/autorest/codegen/templates/model_dpg.py.jinja2 +6 -4
- package/autorest/codegen/templates/model_msrest.py.jinja2 +2 -2
- package/autorest/codegen/templates/serialization.py.jinja2 +57 -29
- package/autorest/codegen/templates/vendor.py.jinja2 +3 -2
- package/autorest/jsonrpc/localapi.py +3 -3
- package/autorest/jsonrpc/server.py +3 -3
- package/autorest/m2r/__init__.py +1 -1
- package/autorest/m4reformatter/__init__.py +13 -2
- package/autorest/multiapi/models/__init__.py +2 -0
- package/autorest/multiapi/models/code_model.py +13 -0
- package/autorest/multiapi/models/global_parameter.py +1 -0
- package/autorest/multiapi/models/imports.py +3 -3
- package/autorest/multiapi/serializers/__init__.py +30 -3
- package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +8 -12
- package/autorest/postprocess/get_all.py +3 -1
- package/autorest/postprocess/venvtools.py +5 -4
- package/autorest/preprocess/__init__.py +19 -7
- package/autorest/preprocess/python_mappings.py +1 -0
- package/index.js +0 -0
- package/package.json +2 -1
- package/requirements.txt +6 -6
- package/setup.py +0 -1
- package/venvtools.py +2 -3
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
{% import 'operation_tools.jinja2' as op_tools %}
|
|
2
2
|
{% import 'keywords.jinja2' as keywords %}
|
|
3
|
+
{% set only_path = client.code_model.options["only_path_and_body_params_positional"] %}
|
|
4
|
+
{% set method_location = "keywordOnly" if only_path else "positional" %}
|
|
3
5
|
{
|
|
4
6
|
"chosen_version": {{ chosen_version | tojson }},
|
|
5
7
|
"total_api_version_list": {{ total_api_version_list | tojson }},
|
|
@@ -22,7 +24,8 @@
|
|
|
22
24
|
"signature": {{ gp.method_signature(async_mode=False) | tojson }},
|
|
23
25
|
"description": {{ gp.description | tojson }},
|
|
24
26
|
"docstring_type": {{ gp.docstring_type(async_mode=False) | tojson }},
|
|
25
|
-
"required": {{ (not gp.optional) | tojson }}
|
|
27
|
+
"required": {{ (not gp.optional) | tojson }},
|
|
28
|
+
"method_location": {{ gp.method_location | tojson }}
|
|
26
29
|
}{{ "," if not loop.last else "" }}
|
|
27
30
|
{% endfor %}
|
|
28
31
|
},
|
|
@@ -48,21 +51,24 @@
|
|
|
48
51
|
"signature": "api_version: Optional[str]=None,",
|
|
49
52
|
"description": "API version to use if no profile is provided, or if missing in profile.",
|
|
50
53
|
"docstring_type": "str",
|
|
51
|
-
"required": false
|
|
54
|
+
"required": false,
|
|
55
|
+
"method_location": {{ method_location | tojson }}
|
|
52
56
|
},
|
|
53
57
|
{% if not client.has_parameterized_host %}
|
|
54
|
-
"base_url": {
|
|
58
|
+
"{{ "endpoint" if only_path else "base_url" }}": {
|
|
55
59
|
"signature": {{ client.parameters.host.method_signature(async_mode=False) | tojson }},
|
|
56
60
|
"description": "Service URL",
|
|
57
61
|
"docstring_type": "str",
|
|
58
|
-
"required": false
|
|
62
|
+
"required": false,
|
|
63
|
+
"method_location": {{ method_location | tojson }}
|
|
59
64
|
},
|
|
60
65
|
{% endif %}
|
|
61
66
|
"profile": {
|
|
62
67
|
"signature": "profile: KnownProfiles=KnownProfiles.default,",
|
|
63
68
|
"description": "A profile definition, from KnownProfiles to dict.",
|
|
64
69
|
"docstring_type": "azure.profiles.KnownProfiles",
|
|
65
|
-
"required": false
|
|
70
|
+
"required": false,
|
|
71
|
+
"method_location": {{ method_location | tojson }}
|
|
66
72
|
}
|
|
67
73
|
},
|
|
68
74
|
"async": {
|
|
@@ -70,21 +76,24 @@
|
|
|
70
76
|
"signature": "api_version: Optional[str] = None,",
|
|
71
77
|
"description": "API version to use if no profile is provided, or if missing in profile.",
|
|
72
78
|
"docstring_type": "str",
|
|
73
|
-
"required": false
|
|
79
|
+
"required": false,
|
|
80
|
+
"method_location": {{ method_location | tojson }}
|
|
74
81
|
},
|
|
75
82
|
{% if not client.has_parameterized_host %}
|
|
76
|
-
"base_url": {
|
|
83
|
+
"{{ "endpoint" if only_path else "base_url" }}": {
|
|
77
84
|
"signature": {{ client.parameters.host.method_signature(async_mode=True) | tojson }},
|
|
78
85
|
"description": "Service URL",
|
|
79
86
|
"docstring_type": "str",
|
|
80
|
-
"required": false
|
|
87
|
+
"required": false,
|
|
88
|
+
"method_location": {{ method_location | tojson }}
|
|
81
89
|
},
|
|
82
90
|
{% endif %}
|
|
83
91
|
"profile": {
|
|
84
92
|
"signature": "profile: KnownProfiles = KnownProfiles.default,",
|
|
85
93
|
"description": "A profile definition, from KnownProfiles to dict.",
|
|
86
94
|
"docstring_type": "azure.profiles.KnownProfiles",
|
|
87
|
-
"required": false
|
|
95
|
+
"required": false,
|
|
96
|
+
"method_location": {{ method_location | tojson }}
|
|
88
97
|
}
|
|
89
98
|
}
|
|
90
99
|
}
|
|
@@ -4,22 +4,23 @@
|
|
|
4
4
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
5
5
|
# license information.
|
|
6
6
|
# --------------------------------------------------------------------------
|
|
7
|
+
# pylint: disable=protected-access, arguments-differ, signature-differs, broad-except
|
|
8
|
+
# pyright: reportGeneralTypeIssues=false
|
|
7
9
|
|
|
8
10
|
import functools
|
|
9
11
|
import sys
|
|
10
12
|
import logging
|
|
11
13
|
import base64
|
|
12
14
|
import re
|
|
13
|
-
import
|
|
14
|
-
from json import JSONEncoder
|
|
15
|
+
import copy
|
|
15
16
|
import typing
|
|
16
|
-
from datetime import datetime, date, time, timedelta
|
|
17
|
-
from azure.core.utils._utils import _FixedOffset
|
|
18
17
|
from collections.abc import MutableMapping
|
|
18
|
+
from datetime import datetime, date, time, timedelta, timezone
|
|
19
|
+
from json import JSONEncoder
|
|
20
|
+
import isodate
|
|
19
21
|
from azure.core.exceptions import DeserializationError
|
|
20
22
|
from azure.core import CaseInsensitiveEnumMeta
|
|
21
23
|
from azure.core.pipeline import PipelineResponse
|
|
22
|
-
import copy
|
|
23
24
|
|
|
24
25
|
_LOGGER = logging.getLogger(__name__)
|
|
25
26
|
|
|
@@ -41,11 +42,16 @@ A falsy sentinel object which is supposed to be used to specify attributes
|
|
|
41
42
|
with no data. This gets serialized to `null` on the wire.
|
|
42
43
|
"""
|
|
43
44
|
|
|
45
|
+
TZ_UTC = timezone.utc
|
|
44
46
|
|
|
45
47
|
def _timedelta_as_isostr(td: timedelta) -> str:
|
|
46
48
|
"""Converts a datetime.timedelta object into an ISO 8601 formatted string, e.g. 'P4DT12H30M05S'
|
|
47
49
|
|
|
48
50
|
Function adapted from the Tin Can Python project: https://github.com/RusticiSoftware/TinCanPython
|
|
51
|
+
|
|
52
|
+
:param timedelta td: The timedelta to convert
|
|
53
|
+
:rtype: str
|
|
54
|
+
:return: ISO8601 version of this timedelta
|
|
49
55
|
"""
|
|
50
56
|
|
|
51
57
|
# Split seconds to larger units
|
|
@@ -93,7 +99,12 @@ def _timedelta_as_isostr(td: timedelta) -> str:
|
|
|
93
99
|
|
|
94
100
|
|
|
95
101
|
def _datetime_as_isostr(dt: typing.Union[datetime, date, time, timedelta]) -> str:
|
|
96
|
-
"""Converts a datetime.(datetime|date|time|timedelta) object into an ISO 8601 formatted string
|
|
102
|
+
"""Converts a datetime.(datetime|date|time|timedelta) object into an ISO 8601 formatted string
|
|
103
|
+
|
|
104
|
+
:param timedelta dt: The date object to convert
|
|
105
|
+
:rtype: str
|
|
106
|
+
:return: ISO8601 version of this datetime
|
|
107
|
+
"""
|
|
97
108
|
# First try datetime.datetime
|
|
98
109
|
if hasattr(dt, "year") and hasattr(dt, "hour"):
|
|
99
110
|
dt = typing.cast(datetime, dt)
|
|
@@ -113,15 +124,6 @@ def _datetime_as_isostr(dt: typing.Union[datetime, date, time, timedelta]) -> st
|
|
|
113
124
|
dt = typing.cast(timedelta, dt)
|
|
114
125
|
return _timedelta_as_isostr(dt)
|
|
115
126
|
|
|
116
|
-
|
|
117
|
-
try:
|
|
118
|
-
from datetime import timezone
|
|
119
|
-
|
|
120
|
-
TZ_UTC = timezone.utc # type: ignore
|
|
121
|
-
except ImportError:
|
|
122
|
-
TZ_UTC = _FixedOffset(0) # type: ignore
|
|
123
|
-
|
|
124
|
-
|
|
125
127
|
def _serialize_bytes(o) -> str:
|
|
126
128
|
return base64.b64encode(o).decode()
|
|
127
129
|
|
|
@@ -141,7 +143,7 @@ def _serialize_datetime(o):
|
|
|
141
143
|
|
|
142
144
|
def _is_readonly(p):
|
|
143
145
|
try:
|
|
144
|
-
return p._readonly
|
|
146
|
+
return p._readonly # pylint: disable=protected-access
|
|
145
147
|
except AttributeError:
|
|
146
148
|
return False
|
|
147
149
|
|
|
@@ -151,7 +153,7 @@ class AzureJSONEncoder(JSONEncoder):
|
|
|
151
153
|
|
|
152
154
|
def default(self, o): # pylint: disable=too-many-return-statements
|
|
153
155
|
if _is_model(o):
|
|
154
|
-
readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)]
|
|
156
|
+
readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] # pylint: disable=protected-access
|
|
155
157
|
return {k: v for k, v in o.items() if k not in readonly_props}
|
|
156
158
|
if isinstance(o, (bytes, bytearray)):
|
|
157
159
|
return base64.b64encode(o).decode()
|
|
@@ -174,7 +176,7 @@ class AzureJSONEncoder(JSONEncoder):
|
|
|
174
176
|
return super(AzureJSONEncoder, self).default(o)
|
|
175
177
|
|
|
176
178
|
|
|
177
|
-
_VALID_DATE = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?")
|
|
179
|
+
_VALID_DATE = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" + r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?")
|
|
178
180
|
|
|
179
181
|
|
|
180
182
|
def _deserialize_datetime(attr: typing.Union[str, datetime]) -> datetime:
|
|
@@ -182,6 +184,7 @@ def _deserialize_datetime(attr: typing.Union[str, datetime]) -> datetime:
|
|
|
182
184
|
|
|
183
185
|
:param str attr: response string to be deserialized.
|
|
184
186
|
:rtype: ~datetime.datetime
|
|
187
|
+
:returns: The datetime object from that input
|
|
185
188
|
"""
|
|
186
189
|
if isinstance(attr, datetime):
|
|
187
190
|
# i'm already deserialized
|
|
@@ -212,7 +215,8 @@ def _deserialize_datetime(attr: typing.Union[str, datetime]) -> datetime:
|
|
|
212
215
|
def _deserialize_date(attr: typing.Union[str, date]) -> date:
|
|
213
216
|
"""Deserialize ISO-8601 formatted string into Date object.
|
|
214
217
|
:param str attr: response string to be deserialized.
|
|
215
|
-
:rtype:
|
|
218
|
+
:rtype: date
|
|
219
|
+
:returns: The date object from that input
|
|
216
220
|
"""
|
|
217
221
|
# This must NOT use defaultmonth/defaultday. Using None ensure this raises an exception.
|
|
218
222
|
if isinstance(attr, date):
|
|
@@ -225,6 +229,7 @@ def _deserialize_time(attr: typing.Union[str, time]) -> time:
|
|
|
225
229
|
|
|
226
230
|
:param str attr: response string to be deserialized.
|
|
227
231
|
:rtype: datetime.time
|
|
232
|
+
:returns: The time object from that input
|
|
228
233
|
"""
|
|
229
234
|
if isinstance(attr, time):
|
|
230
235
|
return attr
|
|
@@ -271,7 +276,7 @@ class _MyMutableMapping(MutableMapping):
|
|
|
271
276
|
def __init__(self, data: typing.Dict[str, typing.Any]) -> None:
|
|
272
277
|
self._data = copy.deepcopy(data)
|
|
273
278
|
|
|
274
|
-
def __contains__(self, key:
|
|
279
|
+
def __contains__(self, key: typing.Any) -> bool:
|
|
275
280
|
return key in self._data
|
|
276
281
|
|
|
277
282
|
def __getitem__(self, key: str) -> typing.Any:
|
|
@@ -307,15 +312,15 @@ class _MyMutableMapping(MutableMapping):
|
|
|
307
312
|
except KeyError:
|
|
308
313
|
return default
|
|
309
314
|
|
|
310
|
-
@typing.overload
|
|
311
|
-
def pop(self, key: str) -> typing.Any:
|
|
315
|
+
@typing.overload # type: ignore
|
|
316
|
+
def pop(self, key: str) -> typing.Any: # pylint: disable=no-member
|
|
312
317
|
...
|
|
313
318
|
|
|
314
319
|
@typing.overload
|
|
315
320
|
def pop(self, key: str, default: typing.Any) -> typing.Any:
|
|
316
321
|
...
|
|
317
322
|
|
|
318
|
-
def pop(self, key:
|
|
323
|
+
def pop(self, key: str, default: typing.Any = _UNSET) -> typing.Any:
|
|
319
324
|
if default is _UNSET:
|
|
320
325
|
return self._data.pop(key)
|
|
321
326
|
return self._data.pop(key, default)
|
|
@@ -329,7 +334,7 @@ class _MyMutableMapping(MutableMapping):
|
|
|
329
334
|
def update(self, *args: typing.Any, **kwargs: typing.Any) -> None:
|
|
330
335
|
self._data.update(*args, **kwargs)
|
|
331
336
|
|
|
332
|
-
@typing.overload
|
|
337
|
+
@typing.overload # type: ignore
|
|
333
338
|
def setdefault(self, key: str) -> typing.Any:
|
|
334
339
|
...
|
|
335
340
|
|
|
@@ -337,7 +342,7 @@ class _MyMutableMapping(MutableMapping):
|
|
|
337
342
|
def setdefault(self, key: str, default: typing.Any) -> typing.Any:
|
|
338
343
|
...
|
|
339
344
|
|
|
340
|
-
def setdefault(self, key:
|
|
345
|
+
def setdefault(self, key: str, default: typing.Any = _UNSET) -> typing.Any:
|
|
341
346
|
if default is _UNSET:
|
|
342
347
|
return self._data.setdefault(key)
|
|
343
348
|
return self._data.setdefault(key, default)
|
|
@@ -383,8 +388,8 @@ def _get_rest_field(
|
|
|
383
388
|
return None
|
|
384
389
|
|
|
385
390
|
|
|
386
|
-
def _create_value(
|
|
387
|
-
return _deserialize(
|
|
391
|
+
def _create_value(rf: typing.Optional["_RestField"], value: typing.Any) -> typing.Any:
|
|
392
|
+
return _deserialize(rf._type, value) if (rf and rf._is_model) else _serialize(value)
|
|
388
393
|
|
|
389
394
|
|
|
390
395
|
class Model(_MyMutableMapping):
|
|
@@ -414,7 +419,7 @@ class Model(_MyMutableMapping):
|
|
|
414
419
|
def copy(self):
|
|
415
420
|
return Model(self.__dict__)
|
|
416
421
|
|
|
417
|
-
def __new__(cls, *args: typing.Any, **kwargs: typing.Any):
|
|
422
|
+
def __new__(cls, *args: typing.Any, **kwargs: typing.Any): # pylint: disable=unused-argument
|
|
418
423
|
# we know the last three classes in mro are going to be 'Model', 'dict', and 'object'
|
|
419
424
|
mros = cls.__mro__[:-3][::-1] # ignore model, dict, and object parents, and reverse the mro order
|
|
420
425
|
attr_to_rest_field: typing.Dict[str, _RestField] = { # map attribute name to rest_field property
|
|
@@ -423,50 +428,50 @@ class Model(_MyMutableMapping):
|
|
|
423
428
|
annotations = {
|
|
424
429
|
k: v
|
|
425
430
|
for mro_class in mros
|
|
426
|
-
if hasattr(mro_class, "__annotations__")
|
|
427
|
-
for k, v in mro_class.__annotations__.items()
|
|
431
|
+
if hasattr(mro_class, "__annotations__") # pylint: disable=no-member
|
|
432
|
+
for k, v in mro_class.__annotations__.items() # pylint: disable=no-member
|
|
428
433
|
}
|
|
429
|
-
for attr,
|
|
430
|
-
|
|
431
|
-
if not
|
|
432
|
-
|
|
433
|
-
if not
|
|
434
|
-
|
|
435
|
-
cls._attr_to_rest_field: typing.Dict[str, _RestField] =
|
|
434
|
+
for attr, rf in attr_to_rest_field.items():
|
|
435
|
+
rf._module = cls.__module__
|
|
436
|
+
if not rf._type:
|
|
437
|
+
rf._type = rf._get_deserialize_callable_from_annotation(annotations.get(attr, None))
|
|
438
|
+
if not rf._rest_name_input:
|
|
439
|
+
rf._rest_name_input = attr
|
|
440
|
+
cls._attr_to_rest_field: typing.Dict[str, _RestField] = dict(attr_to_rest_field.items())
|
|
436
441
|
|
|
437
442
|
return super().__new__(cls)
|
|
438
443
|
|
|
439
444
|
def __init_subclass__(cls, discriminator=None):
|
|
440
445
|
for base in cls.__bases__:
|
|
441
|
-
if hasattr(base, "__mapping__"):
|
|
442
|
-
base.__mapping__[discriminator or cls.__name__] = cls
|
|
446
|
+
if hasattr(base, "__mapping__"): # pylint: disable=no-member
|
|
447
|
+
base.__mapping__[discriminator or cls.__name__] = cls # pylint: disable=no-member
|
|
443
448
|
|
|
444
449
|
@classmethod
|
|
445
450
|
def _get_discriminator(cls) -> typing.Optional[str]:
|
|
446
451
|
for v in cls.__dict__.values():
|
|
447
|
-
if isinstance(v, _RestField) and v._is_discriminator:
|
|
448
|
-
return v._rest_name
|
|
452
|
+
if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access
|
|
453
|
+
return v._rest_name # pylint: disable=protected-access
|
|
449
454
|
return None
|
|
450
455
|
|
|
451
456
|
@classmethod
|
|
452
457
|
def _deserialize(cls, data):
|
|
453
|
-
if not hasattr(cls, "__mapping__"):
|
|
458
|
+
if not hasattr(cls, "__mapping__"): # pylint: disable=no-member
|
|
454
459
|
return cls(data)
|
|
455
460
|
discriminator = cls._get_discriminator()
|
|
456
|
-
mapped_cls = cls.__mapping__.get(data.get(discriminator), cls)
|
|
461
|
+
mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member
|
|
457
462
|
if mapped_cls == cls:
|
|
458
463
|
return cls(data)
|
|
459
|
-
return mapped_cls._deserialize(data)
|
|
464
|
+
return mapped_cls._deserialize(data) # pylint: disable=protected-access
|
|
460
465
|
|
|
461
466
|
|
|
462
|
-
def _get_deserialize_callable_from_annotation(
|
|
463
|
-
annotation: typing.Any, module: str,
|
|
467
|
+
def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements
|
|
468
|
+
annotation: typing.Any, module: typing.Optional[str],
|
|
464
469
|
) -> typing.Optional[typing.Callable[[typing.Any], typing.Any]]:
|
|
465
470
|
if not annotation or annotation in [int, float]:
|
|
466
471
|
return None
|
|
467
472
|
|
|
468
473
|
try:
|
|
469
|
-
if _is_model(_get_model(module, annotation)):
|
|
474
|
+
if module and _is_model(_get_model(module, annotation)):
|
|
470
475
|
def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj):
|
|
471
476
|
if _is_model(obj):
|
|
472
477
|
return obj
|
|
@@ -478,21 +483,25 @@ def _get_deserialize_callable_from_annotation(
|
|
|
478
483
|
|
|
479
484
|
# is it a literal?
|
|
480
485
|
try:
|
|
481
|
-
if
|
|
486
|
+
if sys.version_info >= (3, 8):
|
|
487
|
+
from typing import Literal # pylint: disable=no-name-in-module, ungrouped-imports
|
|
488
|
+
else:
|
|
489
|
+
from typing_extensions import Literal # type: ignore # pylint: disable=ungrouped-imports
|
|
490
|
+
|
|
491
|
+
if annotation.__origin__ == Literal:
|
|
482
492
|
return None
|
|
483
493
|
except AttributeError:
|
|
484
494
|
pass
|
|
485
495
|
|
|
486
|
-
if
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
return functools.partial(_deserialize_with_union, annotation)
|
|
496
|
+
if getattr(annotation, "__origin__", None) is typing.Union:
|
|
497
|
+
def _deserialize_with_union(union_annotation, obj):
|
|
498
|
+
for t in union_annotation.__args__:
|
|
499
|
+
try:
|
|
500
|
+
return _deserialize(t, obj, module)
|
|
501
|
+
except DeserializationError:
|
|
502
|
+
pass
|
|
503
|
+
raise DeserializationError()
|
|
504
|
+
return functools.partial(_deserialize_with_union, annotation)
|
|
496
505
|
|
|
497
506
|
# is it optional?
|
|
498
507
|
try:
|
|
@@ -510,11 +519,11 @@ def _get_deserialize_callable_from_annotation(
|
|
|
510
519
|
return _deserialize_with_callable(if_obj_deserializer, obj)
|
|
511
520
|
|
|
512
521
|
return functools.partial(_deserialize_with_optional, if_obj_deserializer)
|
|
513
|
-
except
|
|
522
|
+
except AttributeError:
|
|
514
523
|
pass
|
|
515
524
|
|
|
516
525
|
# is it a forward ref / in quotes?
|
|
517
|
-
if isinstance(annotation, str
|
|
526
|
+
if isinstance(annotation, (str, typing.ForwardRef)):
|
|
518
527
|
try:
|
|
519
528
|
model_name = annotation.__forward_arg__ # type: ignore
|
|
520
529
|
except AttributeError:
|
|
@@ -596,6 +605,8 @@ def _deserialize_with_callable(deserializer: typing.Optional[typing.Callable[[ty
|
|
|
596
605
|
try:
|
|
597
606
|
if value is None:
|
|
598
607
|
return None
|
|
608
|
+
if deserializer is None:
|
|
609
|
+
return value
|
|
599
610
|
if isinstance(deserializer, CaseInsensitiveEnumMeta):
|
|
600
611
|
try:
|
|
601
612
|
return deserializer(value)
|
|
@@ -603,13 +614,13 @@ def _deserialize_with_callable(deserializer: typing.Optional[typing.Callable[[ty
|
|
|
603
614
|
# for unknown value, return raw value
|
|
604
615
|
return value
|
|
605
616
|
if isinstance(deserializer, type) and issubclass(deserializer, Model):
|
|
606
|
-
return deserializer._deserialize(value)
|
|
607
|
-
return deserializer(value)
|
|
617
|
+
return deserializer._deserialize(value) # type: ignore
|
|
618
|
+
return deserializer(value)
|
|
608
619
|
except Exception as e:
|
|
609
620
|
raise DeserializationError() from e
|
|
610
621
|
|
|
611
622
|
|
|
612
|
-
def _deserialize(deserializer: typing.
|
|
623
|
+
def _deserialize(deserializer: typing.Any, value: typing.Any, module: typing.Optional[str] = None) -> typing.Any:
|
|
613
624
|
if isinstance(value, PipelineResponse):
|
|
614
625
|
value = value.http_response.json()
|
|
615
626
|
deserializer = _get_deserialize_callable_from_annotation(deserializer, module)
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
{{ imports }}
|
|
6
6
|
{% for model in code_model.model_types %}
|
|
7
|
-
{% if
|
|
7
|
+
{% if model.base == "dpg" %}
|
|
8
8
|
{% include "model_dpg.py.jinja2" %}
|
|
9
|
-
{%
|
|
9
|
+
{% elif model.base == "msrest" %}
|
|
10
10
|
{% include "model_msrest.py.jinja2" %}
|
|
11
11
|
{% endif %}
|
|
12
12
|
{% endfor %}
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
30
|
{% if model.is_polymorphic %}
|
|
31
|
-
__mapping__ = {}
|
|
31
|
+
__mapping__: Dict[str, _model_base.Model] = {}
|
|
32
32
|
{% endif %}
|
|
33
33
|
{% for p in serializer.get_properties_to_declare(model)%}
|
|
34
34
|
{% for line in serializer.declare_property(p) %}
|
|
@@ -52,11 +52,13 @@
|
|
|
52
52
|
:param mapping: raw JSON to initialize the model.
|
|
53
53
|
:type mapping: Mapping[str, Any]
|
|
54
54
|
"""
|
|
55
|
-
...
|
|
56
55
|
|
|
57
56
|
{% endif %}
|
|
58
|
-
|
|
57
|
+
{% set initialize_properties = serializer.initialize_properties(model) %}
|
|
58
|
+
{% if model.is_public and serializer.init_line(model) or initialize_properties %}
|
|
59
|
+
def __init__(self, *args, **kwargs):{{ '# pylint: disable=useless-super-delegation' if not initialize_properties else '' }}
|
|
59
60
|
super().__init__(*args, **kwargs)
|
|
60
|
-
{% for initialize_property in
|
|
61
|
+
{% for initialize_property in initialize_properties %}
|
|
61
62
|
{{ initialize_property }}
|
|
62
63
|
{% endfor %}
|
|
64
|
+
{% endif %}
|