python-benedict/benedict/dicts/keypath/keypath_dict.py

66 lines
1.9 KiB
Python

from benedict.dicts import KeylistDict
from benedict.dicts.keypath import keypath_util
class KeypathDict(KeylistDict):
_keypath_separator = None
def __init__(self, *args, **kwargs):
self._keypath_separator = kwargs.pop("keypath_separator", ".")
check_keys = kwargs.pop("check_keys", True)
super().__init__(*args, **kwargs)
if check_keys:
keypath_util.check_keys(self, self._keypath_separator)
@property
def keypath_separator(self):
return self._keypath_separator
@keypath_separator.setter
def keypath_separator(self, value):
keypath_util.check_keys(self, value)
self._keypath_separator = value
def __contains__(self, key):
return super().__contains__(self._parse_key(key))
def __delitem__(self, key):
super().__delitem__(self._parse_key(key))
def __getitem__(self, key):
return super().__getitem__(self._parse_key(key))
def __setitem__(self, key, value):
keypath_util.check_keys(value, self._keypath_separator)
super().__setitem__(self._parse_key(key), value)
def __setstate__(self, state):
super().__setstate__(state)
self._keypath_separator = state["_keypath_separator"]
def _parse_key(self, key):
keys = keypath_util.parse_keys(key, self._keypath_separator)
keys_count = len(keys)
if keys_count == 0:
return None
elif keys_count == 1:
return keys[0]
return keys
@classmethod
def fromkeys(cls, sequence, value=None):
d = cls()
for key in sequence:
d[key] = value
return d
def get(self, key, default=None):
return super().get(self._parse_key(key), default)
def pop(self, key, *args):
return super().pop(self._parse_key(key), *args)
def update(self, other):
keypath_util.check_keys(other, self._keypath_separator)
super().update(other)