python-benedict/benedict/dicts/keylist/keylist_util.py

81 lines
1.9 KiB
Python
Raw Normal View History

from benedict.utils import type_util
def _get_index(key):
if type_util.is_integer(key):
return key
return None
2020-02-04 11:10:54 +00:00
def _get_item_key_and_value(item, key):
if type_util.is_list_or_tuple(item):
index = _get_index(key)
if index is not None:
2021-10-12 12:27:35 +00:00
return (index, item[index])
elif type_util.is_dict(item):
2021-10-12 12:27:35 +00:00
return (key, item[key])
2023-03-01 16:37:50 +00:00
raise KeyError(f"Invalid key: {key!r}")
2020-02-04 11:10:54 +00:00
def _get_or_new_item_value(item, key, subkey):
try:
2020-02-05 08:48:50 +00:00
_, value = _get_item_key_and_value(item, key)
if not type_util.is_dict_or_list_or_tuple(value):
2020-02-04 11:10:54 +00:00
raise TypeError
2021-10-12 12:27:35 +00:00
except (IndexError, KeyError, TypeError):
2020-02-05 08:48:50 +00:00
value = _new_item_value(subkey)
2022-08-23 08:00:10 +00:00
_set_item_value(item, key, value)
2020-02-05 08:48:50 +00:00
return value
2020-02-04 11:10:54 +00:00
def _new_item_value(key):
index = _get_index(key)
return {} if index is None else []
2020-02-04 11:10:54 +00:00
def _set_item_value(item, key, value):
index = _get_index(key)
if index is not None:
try:
# overwrite existing index
item[index] = value
except IndexError:
# insert index
2021-10-12 12:27:35 +00:00
item += [None] * (index - len(item))
2020-02-04 11:10:54 +00:00
item.insert(index, value)
else:
item[key] = value
def get_item(d, keys):
items = get_items(d, keys)
2021-10-12 12:27:35 +00:00
return items[-1] if items else (None, None, None)
def get_items(d, keys):
items = []
item = d
for key in keys:
try:
2020-02-04 11:10:54 +00:00
item_key, item_value = _get_item_key_and_value(item, key)
2021-10-12 12:27:35 +00:00
items.append((item, item_key, item_value))
2020-02-04 11:10:54 +00:00
item = item_value
2021-10-12 12:27:35 +00:00
except (IndexError, KeyError):
items.append((None, None, None))
break
return items
def set_item(d, keys, value):
item = d
i = 0
j = len(keys)
while i < j:
key = keys[i]
if i < (j - 1):
2020-02-04 11:10:54 +00:00
item = _get_or_new_item_value(item, key, keys[i + 1])
i += 1
continue
2020-02-04 11:10:54 +00:00
_set_item_value(item, key, value)
break