Completed
Push — master ( a0c5cf...fb555e )
by Ramon
19s queued 11s
created

jsons.serializers.default_dict._store_cls_info()   A

Complexity

Conditions 4

Size

Total Lines 9
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 9
rs 10
c 0
b 0
f 0
cc 4
nop 4
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
            _store_cls_info(dumped_elem, key, obj, **kwargs)
40
41
        except RecursionDetectedError:
42
            fork_inst._warn('Recursive structure detected in attribute "{}" '
43
                            'of object of type "{}", ignoring the attribute.'
44
                            .format(key, get_class_name(cls)))
45
        except SerializationError as err:
46
            if strict:
47
                raise
48
            else:
49
                fork_inst._warn('Failed to dump attribute "{}" of object of '
50
                                'type "{}". Reason: {}. Ignoring the '
51
                                'attribute.'
52
                                .format(key, get_class_name(cls), err.message))
53
                break
54
        if not (strip_nulls and dumped_elem is None):
55
            if key_transformer:
56
                key = key_transformer(key)
57
            result[key] = dumped_elem
58
    return result
59
60
61
def _store_cls_info(result: object, attr: str, original_obj: dict, **kwargs):
62
    if isinstance(result, dict) and kwargs.get('_store_cls'):
63
        cls = get_type(original_obj[attr])
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