Passed
Push — master ( df3bcb...d239e0 )
by Fabio
01:14
created

benedict.dicts.keylist.keylist_util.set_item()   A

Complexity

Conditions 3

Size

Total Lines 12
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
dl 0
loc 12
rs 9.8
c 0
b 0
f 0
cc 3
nop 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_key_and_value(item, key):
13
    if type_util.is_list(item):
14
        index = _get_index(key)
15
        if index is not None:
16
            return (index, item[index], )
17
    elif type_util.is_dict(item):
18
        return (key, item[key], )
19
    raise KeyError
20
21
22
def _get_or_new_item_value(item, key, subkey):
23
    try:
24
        item_key, item_value = _get_item_key_and_value(item, key)
25
        if not type_util.is_dict_or_list(item_value):
26
            raise TypeError
27
    except (IndexError, KeyError, TypeError, ):
28
        item_value = _new_item_value(subkey)
29
        item[key] = item_value
30
    return item_value
31
32
33
def _new_item_value(key):
34
    index = _get_index(key)
35
    return {} if index is None else []
36
37
38
def _set_item_value(item, key, value):
39
    index = _get_index(key)
40
    if index is not None:
41
        try:
42
            # overwrite existing index
43
            item[index] = value
44
        except IndexError:
45
            # insert index
46
            item += ([None] * (index - len(item)))
47
            item.insert(index, value)
48
    else:
49
        item[key] = value
50
51
52
def get_item(d, keys):
53
    items = get_items(d, keys)
54
    return items[-1] if items else (None, None, None, )
55
56
57
def get_items(d, keys):
58
    items = []
59
    item = d
60
    value = None
61
    for key in keys:
62
        try:
63
            item_key, item_value = _get_item_key_and_value(item, key)
64
            items.append((item, item_key, item_value, ))
65
            item = item_value
66
        except (IndexError, KeyError, ):
67
            items.append((None, None, None, ))
68
            break
69
    return items
70
71
72
def set_item(d, keys, value):
73
    item = d
74
    i = 0
75
    j = len(keys)
76
    while i < j:
77
        key = keys[i]
78
        if i < (j - 1):
79
            item = _get_or_new_item_value(item, key, keys[i + 1])
80
            i += 1
81
            continue
82
        _set_item_value(item, key, value)
83
        break
84