Passed
Pull Request — master (#73)
by Ramon
01:36
created

jsons.serializers.default_dict._store_cls_info()   A

Complexity

Conditions 3

Size

Total Lines 8
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 3
nop 3
1
from typing import Optional, Callable
2
from typish import get_type
3
from jsons._common_impl import get_class_name
4
from jsons._dump_impl import dump
5
from jsons.exceptions import RecursionDetectedError, SerializationError
6
7
8
def default_dict_serializer(
9
        obj: dict,
10
        cls: Optional[type] = None,
11
        *,
12
        strict: bool = False,
13
        strip_nulls: bool = False,
14
        key_transformer: Optional[Callable[[str], str]] = None,
15
        **kwargs) -> dict:
16
    """
17
    Serialize the given ``obj`` to a dict of serialized objects.
18
    :param obj: the dict that is to be serialized.
19
    :param cls: the type of ``obj``; ``obj`` is dumped as if of that type.
20
    :param strict: if ``True`` the serialization will raise upon any the
21
    failure of any attribute. Otherwise it continues with a warning.
22
    :param strip_nulls: if ``True`` the resulting dict will not contain null
23
    values.
24
    :param key_transformer: a function that will be applied to all keys in the
25
    resulting dict.
26
    :param kwargs: any keyword arguments that may be given to the serialization
27
    process.
28
    :return: a dict of which all elements are serialized.
29
    """
30
    result = dict()
31
    fork_inst = kwargs['fork_inst']
32
    for key in obj:
33
        dumped_elem = None
34
        try:
35
            dumped_elem = dump(obj[key],
36
                               key_transformer=key_transformer,
37
                               strip_nulls=strip_nulls, **kwargs)
38
39
            if isinstance(dumped_elem, dict) and '_store_cls' in kwargs:
40
                cls_ = get_type(obj[key])
41
                _store_cls_info(dumped_elem, cls_, **kwargs)
42
43
        except RecursionDetectedError:
44
            fork_inst._warn('Recursive structure detected in attribute "{}" '
45
                            'of object of type "{}", ignoring the attribute.'
46
                            .format(key, get_class_name(cls)))
47
        except SerializationError as err:
48
            if strict:
49
                raise
50
            else:
51
                fork_inst._warn('Failed to dump attribute "{}" of object of type '
52
                                '"{}". Reason: {}. Ignoring the attribute.'
53
                                .format(key, get_class_name(cls), err.message))
54
                break
55
        if not (strip_nulls and dumped_elem is None):
56
            if key_transformer:
57
                key = key_transformer(key)
58
            result[key] = dumped_elem
59
    return result
60
61
62
def _store_cls_info(result: dict, cls: type, **kwargs):
63
    if kwargs.get('_store_cls'):
64
        if cls.__module__ == 'typing':
65
            cls_name = repr(cls)
66
        else:
67
            cls_name = get_class_name(cls, fully_qualified=True,
68
                                      fork_inst=kwargs['fork_inst'])
69
        result['-cls'] = cls_name
70