2020-01-30 14:31:53 +00:00
|
|
|
from benedict.utils import type_util
|
2020-01-30 11:56:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
def _get_index(key):
|
2020-01-30 14:31:53 +00:00
|
|
|
if type_util.is_integer(key):
|
2020-01-30 11:56:00 +00:00
|
|
|
return key
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
2020-02-04 11:10:54 +00:00
|
|
|
def _get_item_key_and_value(item, key):
|
2021-10-02 14:56:28 +00:00
|
|
|
if type_util.is_list_or_tuple(item):
|
2020-01-30 11:56:00 +00:00
|
|
|
index = _get_index(key)
|
|
|
|
if index is not None:
|
2021-10-12 12:27:35 +00:00
|
|
|
return (index, item[index])
|
2020-01-30 14:31:53 +00:00
|
|
|
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-01-30 11:56:00 +00:00
|
|
|
|
|
|
|
|
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)
|
2021-10-02 14:56:28 +00:00
|
|
|
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
|
|
|
|
|
|
|
|
2020-01-31 12:02:07 +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
|
|
|
|
|
|
|
|
|
2020-01-30 11:56:00 +00:00
|
|
|
def get_item(d, keys):
|
2020-01-31 12:02:07 +00:00
|
|
|
items = get_items(d, keys)
|
2021-10-12 12:27:35 +00:00
|
|
|
return items[-1] if items else (None, None, None)
|
2020-01-31 12:02:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_items(d, keys):
|
2020-01-30 11:56:00 +00:00
|
|
|
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))
|
2020-01-30 11:56:00 +00:00
|
|
|
break
|
2020-01-31 12:02:07 +00:00
|
|
|
return items
|
2020-01-30 11:56:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
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])
|
2020-01-30 11:56:00 +00:00
|
|
|
i += 1
|
|
|
|
continue
|
2020-02-04 11:10:54 +00:00
|
|
|
_set_item_value(item, key, value)
|
2020-01-30 11:56:00 +00:00
|
|
|
break
|