benedict.dicts.keylist.keylist_util   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 22
eloc 62
dl 0
loc 81
rs 10
c 0
b 0
f 0

8 Functions

Rating   Name   Duplication   Size   Complexity  
A set_item() 0 12 3
A _new_item_value() 0 3 2
A _get_index() 0 4 2
A _get_or_new_item_value() 0 9 3
A get_item() 0 3 2
A get_items() 0 12 3
A _set_item_value() 0 12 3
A _get_item_key_and_value() 0 8 4
1
from benedict.utils import type_util
2
3
4
def _get_index(key):
5
    if type_util.is_integer(key):
6
        return key
7
    return None
8
9
10
def _get_item_key_and_value(item, key):
11
    if type_util.is_list_or_tuple(item):
12
        index = _get_index(key)
13
        if index is not None:
14
            return (index, item[index])
15
    elif type_util.is_dict(item):
16
        return (key, item[key])
17
    raise KeyError(f"Invalid key: '{key}'")
18
19
20
def _get_or_new_item_value(item, key, subkey):
21
    try:
22
        _, value = _get_item_key_and_value(item, key)
23
        if not type_util.is_dict_or_list_or_tuple(value):
24
            raise TypeError
25
    except (IndexError, KeyError, TypeError):
26
        value = _new_item_value(subkey)
27
        _set_item_value(item, key, value)
28
    return value
29
30
31
def _new_item_value(key):
32
    index = _get_index(key)
33
    return {} if index is None else []
34
35
36
def _set_item_value(item, key, value):
37
    index = _get_index(key)
38
    if index is not None:
39
        try:
40
            # overwrite existing index
41
            item[index] = value
42
        except IndexError:
43
            # insert index
44
            item += [None] * (index - len(item))
45
            item.insert(index, value)
46
    else:
47
        item[key] = value
48
49
50
def get_item(d, keys):
51
    items = get_items(d, keys)
52
    return items[-1] if items else (None, None, None)
53
54
55
def get_items(d, keys):
56
    items = []
57
    item = d
58
    for key in keys:
59
        try:
60
            item_key, item_value = _get_item_key_and_value(item, key)
61
            items.append((item, item_key, item_value))
62
            item = item_value
63
        except (IndexError, KeyError):
64
            items.append((None, None, None))
65
            break
66
    return items
67
68
69
def set_item(d, keys, value):
70
    item = d
71
    i = 0
72
    j = len(keys)
73
    while i < j:
74
        key = keys[i]
75
        if i < (j - 1):
76
            item = _get_or_new_item_value(item, key, keys[i + 1])
77
            i += 1
78
            continue
79
        _set_item_value(item, key, value)
80
        break
81