# -*- coding: utf-8 -*- from benedict.dicts import KeylistDict from benedict.utils import keypath_util class KeypathDict(KeylistDict): _keypath_separator = None def __init__(self, *args, **kwargs): self._keypath_separator = kwargs.pop('keypath_separator', '.') super(KeypathDict, self).__init__(*args, **kwargs) 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(KeypathDict, self).__contains__( self._parse_key(key)) def __delitem__(self, key): super(KeypathDict, self).__delitem__( self._parse_key(key)) def __getitem__(self, key): return super(KeypathDict, self).__getitem__( self._parse_key(key)) def __setitem__(self, key, value): keypath_util.check_keys(value, self._keypath_separator) super(KeypathDict, self).__setitem__( self._parse_key(key), value) 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(KeypathDict, self).get( self._parse_key(key), default) def pop(self, key, *args): return super(KeypathDict, self).pop( self._parse_key(key), *args) def set(self, key, value): self.__setitem__(key, value) def setdefault(self, key, default=None): if key not in self: self.set(key, default) return default return self.__getitem__(key) def update(self, other): keypath_util.check_keys(other, self._keypath_separator) super(KeypathDict, self).update(other)