Passed
Pull Request — master (#17)
by Ramon
50s
created

default_tuple_deserializer()   A

Complexity

Conditions 4

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 19
rs 9.85
c 0
b 0
f 0
cc 4
nop 3
1
from jsons.exceptions import UnfulfilledArgumentError
2
from jsons._main_impl import load
3
4
5
def default_tuple_deserializer(obj: list,
6
                               cls: type = None,
7
                               **kwargs) -> object:
8
    """
9
    Deserialize a (JSON) list into a tuple by deserializing all items of that
10
    list.
11
    :param obj: the tuple that needs deserializing.
12
    :param cls: the type optionally with a generic (e.g. Tuple[str, int]).
13
    :param kwargs: any keyword arguments.
14
    :return: a deserialized tuple instance.
15
    """
16
    if hasattr(cls, '_fields'):
17
        return default_namedtuple_deserializer(obj, cls, **kwargs)
18
    tuple_types = getattr(cls, '__tuple_params__', cls.__args__)
19
    if len(tuple_types) > 1 and tuple_types[1] is ...:
20
        tuple_types = [tuple_types[0]] * len(obj)
21
    list_ = [load(value, tuple_types[i], **kwargs)
22
             for i, value in enumerate(obj)]
23
    return tuple(list_)
24
25
26
def default_namedtuple_deserializer(obj: list, cls: type, **kwargs) -> object:
27
    """
28
    Deserialize a (JSON) list into a named tuple by deserializing all items of
29
    that list.
30
    :param obj: the tuple that needs deserializing.
31
    :param cls: the NamedTuple.
32
    :param kwargs: any keyword arguments.
33
    :return: a deserialized named tuple (i.e. an instance of a class).
34
    """
35
    args = []
36
    for index, field_name in enumerate(cls._fields):
37
        if index < len(obj):
38
            field = obj[index]
39
        else:
40
            field = cls._field_defaults.get(field_name, None)
41
        if not field:
42
            msg = ('No value present in {} for argument "{}"'
43
                   .format(obj, field_name))
44
            raise UnfulfilledArgumentError(msg, field_name, obj, cls)
45
        cls_ = cls._field_types.get(field_name, None)
46
        loaded_field = load(field, cls_, **kwargs)
47
        args.append(loaded_field)
48
    inst = cls(*args)
49
    return inst
50