default_dict_serializer()   B
last analyzed

Complexity

Conditions 6

Size

Total Lines 53
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 31
dl 0
loc 53
rs 8.2026
c 0
b 0
f 0
cc 6
nop 8

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
from typing import Callable, Dict, Optional, Tuple
2
3
from jsons._common_impl import JSON_KEYS
4
from jsons._dump_impl import dump
5
6
7
def default_dict_serializer(
8
        obj: dict,
9
        cls: Optional[type] = None,
10
        *,
11
        strict: bool = False,
12
        strip_nulls: bool = False,
13
        key_transformer: Optional[Callable[[str], str]] = None,
14
        types: Optional[Dict[str, type]] = 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: not used.
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 strict: a bool to determine if the serializer should be strict
23
    (i.e. only dumping stuff that is known to ``cls``).
24
    :param strip_nulls: if ``True`` the resulting dict will not contain null
25
    values.
26
    :param key_transformer: a function that will be applied to all keys in the
27
    resulting dict.
28
    :param types: a ``dict`` with attribute names (keys) and their types
29
    (values).
30
    :param kwargs: any keyword arguments that may be given to the serialization
31
    process.
32
    :return: a dict of which all elements are serialized.
33
    """
34
    result = dict()
35
    types = types or dict()
36
    for key in obj:
37
        obj_ = obj[key]
38
        cls_ = types.get(key, None)
39
40
        # If key is not a valid json type, use the hash as key and store the
41
        # original key in a separate section.
42
        dict_and_key = _store_and_hash(result, key,
43
                                       key_transformer=key_transformer,
44
                                       strip_nulls=strip_nulls, strict=strict,
45
                                       types=types, **kwargs)
46
        if dict_and_key:
47
            result, key = dict_and_key
48
49
        dumped_elem = dump(obj_,
50
                           cls=cls_,
51
                           key_transformer=key_transformer,
52
                           strip_nulls=strip_nulls,
53
                           strict=strict,
54
                           **kwargs)
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_and_hash(
63
        obj: dict,
64
        key: object,
65
        **kwargs
66
) -> Optional[Tuple[dict, int]]:
67
    # Store the given key in the given dict under a special section if that
68
    # key is not a valid json key. Return a hash of that key.
69
    result = None
70
    if not _is_valid_json_key(key):
71
        # First try to dump the key, that might be enough already.
72
        dumped_key = dump(key, **kwargs)
73
        result = obj, dumped_key
74
        if not _is_valid_json_key(dumped_key):
75
            # Apparently, this was not enough; the key is still not "jsonable".
76
            key_hash = hash(key)
77
            obj_ = {**obj}
78
            obj_.setdefault('-keys', {})
79
            obj_['-keys'][key_hash] = dumped_key
80
            result = obj_, key_hash
81
    return result
82
83
84
def _is_valid_json_key(key: object) -> bool:
85
    return any(issubclass(type(key), json_key) for json_key in JSON_KEYS)
86