Passed
Push — master ( 3318af...ce1cbc )
by Fabio
01:13
created

benedict.utils.keylist_util   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 63
dl 0
loc 80
rs 10
c 0
b 0
f 0
wmc 20

5 Functions

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