Completed
Push — master ( 919d86...33db6d )
by Ramon
23s queued 10s
created

jsons.deserializers.default_list._do_load()   A

Complexity

Conditions 4

Size

Total Lines 20
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 18
dl 0
loc 20
rs 9.5
c 0
b 0
f 0
cc 4
nop 5
1
from multiprocessing import Process
2
from typing import Type
3
4
from typish import get_args
5
6
from jsons._common_impl import StateHolder
7
from jsons._load_impl import load
8
from jsons._multitasking import multi_task
9
from jsons.exceptions import JsonsError, DeserializationError
10
11
12
def default_list_deserializer(
13
        obj: list,
14
        cls: type = None,
15
        *,
16
        warn_on_fail: bool = False,
17
        tasks: int = 1,
18
        task_type: type = Process,
19
        fork_inst: Type[StateHolder] = StateHolder,
20
        **kwargs) -> list:
21
    """
22
    Deserialize a list by deserializing all items of that list.
23
    :param obj: the list that needs deserializing.
24
    :param cls: the type optionally with a generic (e.g. List[str]).
25
    :param warn_on_fail: if ``True``, will warn upon any failure and continue.
26
    :param tasks: the allowed number of tasks (threads or processes).
27
    :param task_type: the type that is used for multitasking.
28
    :param fork_inst: if given, it uses this fork of ``JsonSerializable``.
29
    :param kwargs: any keyword arguments.
30
    :return: a deserialized list instance.
31
    """
32
    cls_ = None
33
    kwargs_ = {**kwargs}
34
    cls_args = get_args(cls)
35
    if cls_args:
36
        cls_ = cls_args[0]
37
        # Mark the cls as 'inferred' so that later it is known where cls came
38
        # from and the precedence of classes can be determined.
39
        kwargs_['_inferred_cls'] = True
40
41
    if tasks == 1:
42
        result = _do_load(obj, cls_, warn_on_fail, fork_inst, kwargs_)
43
    elif tasks > 1:
44
        result = multi_task(load, obj, tasks, task_type, cls_, **kwargs_)
45
    else:
46
        raise JsonsError('Invalid number of tasks: {}'.format(tasks))
47
    return result
48
49
50
def _do_load(
51
        obj: list,
52
        cls: type,
53
        warn_on_fail: bool,
54
        fork_inst: Type[StateHolder],
55
        kwargs) -> list:
56
    result = []
57
    for index, elem in enumerate(obj):
58
        try:
59
            result.append(load(elem, cls=cls, tasks=1, **kwargs))
60
        except DeserializationError as err:
61
            new_msg = ('Could not deserialize element at index %s. %s' %
62
                       (index, err.message))
63
            if warn_on_fail:
64
                fork_inst._warn(new_msg)
65
            else:
66
                new_err = DeserializationError(new_msg, err.source, err.target)
67
                raise new_err from err
68
69
    return result
70