Passed
Push — master ( db2481...3bd527 )
by Fabio
03:28
created

benedict.dicts.keylist.keylist_util   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 84
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 22
eloc 64
dl 0
loc 84
rs 10
c 0
b 0
f 0

7 Functions

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