Completed
Push — master ( db4c81...c9ecbe )
by Ramon
25s queued 11s
created

default_union_serializer()   B

Complexity

Conditions 6

Size

Total Lines 29
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 14
dl 0
loc 29
rs 8.6666
c 0
b 0
f 0
cc 6
nop 3
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