1
|
|
|
from typing import Union |
2
|
|
|
|
3
|
|
|
from jsons._common_impl import get_class_name, NoneType |
4
|
|
|
from jsons._compatibility_impl import get_union_params |
5
|
|
|
from jsons._dump_impl import dump |
6
|
|
|
from jsons.exceptions import JsonsError, SerializationError |
7
|
|
|
|
8
|
|
|
|
9
|
|
|
def default_union_serializer(obj: object, cls: Union, **kwargs) -> object: |
10
|
|
|
""" |
11
|
|
|
Serialize an object to any matching type of the given union. The first |
12
|
|
|
successful serialization is returned. |
13
|
|
|
:param obj: The object that is to be serialized. |
14
|
|
|
:param cls: The Union type with a generic (e.g. Union[str, int]). |
15
|
|
|
:param kwargs: Any keyword arguments that are passed through the |
16
|
|
|
serialization process. |
17
|
|
|
:return: An object of the first type of the Union that could be |
18
|
|
|
serialized successfully. |
19
|
|
|
""" |
20
|
|
|
sub_types = get_union_params(cls) |
21
|
|
|
|
22
|
|
|
# Cater for Optional[...]/Union[None, ...] first to avoid blindly |
23
|
|
|
# string-ifying None in later serializers. |
24
|
|
|
if obj is None and NoneType in sub_types: |
25
|
|
|
return obj |
26
|
|
|
|
27
|
|
|
for sub_type in sub_types: |
28
|
|
|
try: |
29
|
|
|
return dump(obj, sub_type, **kwargs) |
30
|
|
|
except JsonsError: |
31
|
|
|
pass # Try the next one. |
32
|
|
|
else: |
33
|
|
|
args_msg = ', '.join([get_class_name(cls_) |
34
|
|
|
for cls_ in get_union_params(cls)]) |
35
|
|
|
err_msg = ('Could not match the object of type "{}" to any type of ' |
36
|
|
|
'the Union: {}'.format(type(obj), args_msg)) |
37
|
|
|
raise SerializationError(err_msg) |
38
|
|
|
|