Completed
Push — master ( db4c81...c9ecbe )
by Ramon
25s queued 11s
created

_load_hashed_keys()   A

Complexity

Conditions 4

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 17
dl 0
loc 27
rs 9.55
c 0
b 0
f 0
cc 4
nop 4
1
from typing import Optional, Callable
2
3
from typish import get_args
4
5
from jsons._load_impl import load
6
from jsons.exceptions import DeserializationError
7
8
9
def default_dict_deserializer(
10
        obj: dict,
11
        cls: type,
12
        *,
13
        key_transformer: Optional[Callable[[str], str]] = None,
14
        **kwargs) -> dict:
15
    """
16
    Deserialize a dict by deserializing all instances of that dict.
17
    :param obj: the dict that needs deserializing.
18
    :param key_transformer: a function that transforms the keys to a different
19
    style (e.g. PascalCase).
20
    :param cls: not used.
21
    :param kwargs: any keyword arguments.
22
    :return: a deserialized dict instance.
23
    """
24
    key_tfr = key_transformer or (lambda key: key)
25
    cls_args = get_args(cls)
26
    kwargs_ = {**kwargs, 'key_transformer': key_transformer}
27
28
    obj_ = _load_hashed_keys(obj, cls, cls_args, key_transformer=key_transformer, **kwargs)
29
30
    if len(cls_args) == 2:
31
        cls_k, cls_v = cls_args
32
        kwargs_k = {**kwargs_, 'cls': cls_k}
33
        kwargs_v = {**kwargs_, 'cls': cls_v}
34
        res = {load(key_tfr(k), **kwargs_k): load(obj_[k], **kwargs_v)
35
               for k in obj_}
36
    else:
37
        res = {key_tfr(key): load(obj_[key], **kwargs_)
38
               for key in obj_}
39
    return res
40
41
42
def _load_hashed_keys(obj: dict, cls: type, cls_args: tuple, **kwargs) -> dict:
43
    # Load any hashed keys and return a copy of the given obj if any hashed
44
    # keys are unpacked.
45
    result = obj
46
47
    stored_keys = list(obj.get('-keys', []))
48
    if stored_keys:
49
        # Apparently, there are stored hashed keys, we need to unpack them.
50
        if len(cls_args) != 2:
51
            raise DeserializationError('A detailed type is needed for cls of '
52
                                       'the form Dict[<type>, <type>] to '
53
                                       'deserialize a dict with hashed keys.',
54
                                       obj, cls)
55
        result = {**obj}
56
        key_type = cls_args[0]
57
        for key in stored_keys:
58
            # Get the original (unhashed) key and load it.
59
            original_key = result['-keys'][key]
60
            loaded_key = load(original_key, cls=key_type, **kwargs)
61
62
            # Replace the hashed key by the loaded key entirely.
63
            result[loaded_key] = result[key]
64
            del result['-keys'][key]
65
            del result[key]
66
67
        del result['-keys']
68
    return result
69