You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
4.3 KiB
170 lines
4.3 KiB
5 years ago
|
import six
|
||
6 years ago
|
# coding=utf-8
|
||
|
|
||
|
|
||
|
class DictProxy(object):
|
||
|
store = None
|
||
|
|
||
|
def __init__(self, d):
|
||
|
self.Dict = d
|
||
|
super(DictProxy, self).__init__()
|
||
|
|
||
|
if self.store not in self.Dict or not self.Dict[self.store]:
|
||
|
self.Dict[self.store] = self.setup_defaults()
|
||
|
self.save()
|
||
|
self.__initialized = True
|
||
|
|
||
|
def __getattr__(self, name):
|
||
|
if name in self.Dict[self.store]:
|
||
|
return self.Dict[self.store][name]
|
||
|
return getattr(super(DictProxy, self), name)
|
||
|
|
||
|
def __setattr__(self, name, value):
|
||
5 years ago
|
if '_DictProxy__initialized' not in self.__dict__: # this test allows attributes to be set in the __init__ method
|
||
6 years ago
|
return object.__setattr__(self, name, value)
|
||
|
|
||
5 years ago
|
elif name in self.__dict__: # any normal attributes are handled normally
|
||
6 years ago
|
object.__setattr__(self, name, value)
|
||
|
|
||
|
else:
|
||
|
if name in self.Dict[self.store]:
|
||
|
self.Dict[self.store][name] = value
|
||
|
return
|
||
|
object.__setattr__(self, name, value)
|
||
|
|
||
|
def __cmp__(self, d):
|
||
|
return cmp(self.Dict[self.store], d)
|
||
|
|
||
|
def __contains__(self, item):
|
||
|
return item in self.Dict[self.store]
|
||
|
|
||
|
def __setitem__(self, key, item):
|
||
|
self.Dict[self.store][key] = item
|
||
|
self.Dict.Save()
|
||
|
|
||
|
def __iter__(self):
|
||
|
return iter(self.Dict[self.store])
|
||
|
|
||
|
def __getitem__(self, key):
|
||
|
if key in self.Dict[self.store]:
|
||
|
return self.Dict[self.store][key]
|
||
|
|
||
|
def __repr__(self):
|
||
|
return repr(self.Dict[self.store])
|
||
|
|
||
|
def __str__(self):
|
||
|
return str(self.Dict[self.store])
|
||
|
|
||
|
def __len__(self):
|
||
5 years ago
|
return len(list(self.Dict[self.store].keys()))
|
||
6 years ago
|
|
||
|
def __delitem__(self, key):
|
||
|
del self.Dict[self.store][key]
|
||
|
|
||
|
def save(self):
|
||
|
self.Dict.Save()
|
||
|
|
||
|
def clear(self):
|
||
|
del self.Dict[self.store]
|
||
|
return None
|
||
|
|
||
|
def copy(self):
|
||
|
return self.Dict[self.store].copy()
|
||
|
|
||
|
def has_key(self, k):
|
||
|
return k in self.Dict[self.store]
|
||
|
|
||
|
def pop(self, k, d=None):
|
||
|
return self.Dict[self.store].pop(k, d)
|
||
|
|
||
|
def update(self, *args, **kwargs):
|
||
|
return self.Dict[self.store].update(*args, **kwargs)
|
||
|
|
||
|
def keys(self):
|
||
5 years ago
|
return list(self.Dict[self.store].keys())
|
||
6 years ago
|
|
||
|
def values(self):
|
||
5 years ago
|
return list(self.Dict[self.store].values())
|
||
6 years ago
|
|
||
|
def items(self):
|
||
5 years ago
|
return list(self.Dict[self.store].items())
|
||
6 years ago
|
|
||
|
def __unicode__(self):
|
||
5 years ago
|
return six.text_type(repr(self.Dict[self.store]))
|
||
6 years ago
|
|
||
|
def setup_defaults(self):
|
||
|
raise NotImplementedError
|
||
|
|
||
|
|
||
|
class Dicked(object):
|
||
|
"""
|
||
|
mirrors a dictionary; readonly
|
||
|
"""
|
||
|
_entries = None
|
||
|
|
||
|
def __init__(self, **entries):
|
||
|
self._entries = entries or None
|
||
5 years ago
|
for key, value in six.iteritems(entries):
|
||
6 years ago
|
self.__dict__[key] = (Dicked(**value) if isinstance(value, dict) else value)
|
||
|
|
||
5 years ago
|
def has(self, key):
|
||
|
return self._entries is not None and key in self._entries
|
||
|
|
||
|
def get(self, key, default=None):
|
||
|
return self._entries.get(key, default) if self._entries else default
|
||
|
|
||
6 years ago
|
def __repr__(self):
|
||
|
return str(self)
|
||
|
|
||
|
def __unicode__(self):
|
||
5 years ago
|
return six.text_type(self.__digged__)
|
||
6 years ago
|
|
||
|
def __str__(self):
|
||
|
return str(self.__digged__)
|
||
|
|
||
|
def __lt__(self, d):
|
||
|
return self._entries < d
|
||
|
|
||
|
def __le__(self, d):
|
||
|
return self._entries <= d
|
||
|
|
||
|
def __eq__(self, d):
|
||
|
if d is None and not self._entries:
|
||
|
return True
|
||
|
|
||
|
return self._entries == d
|
||
|
|
||
|
def __ne__(self, d):
|
||
|
return self._entries != d
|
||
|
|
||
|
def __gt__(self, d):
|
||
|
return self._entries > d
|
||
|
|
||
|
def __ge__(self, d):
|
||
|
return self._entries >= d
|
||
|
|
||
|
def __getattr__(self, name):
|
||
|
# fixme: this might be wildly stupid; maybe implement stuff like .iteritems() directly
|
||
|
return getattr(self._entries, name, Dicked())
|
||
|
|
||
|
@property
|
||
|
def __digged__(self):
|
||
5 years ago
|
return {key: value for key, value in six.iteritems(self.__dict__) if key != "_entries"}
|
||
6 years ago
|
|
||
|
def __len__(self):
|
||
|
return len(self.__digged__)
|
||
|
|
||
|
def __nonzero__(self):
|
||
|
return bool(self.__digged__)
|
||
|
|
||
|
def __iter__(self):
|
||
|
return iter(self.__digged__)
|
||
|
|
||
|
def __hash__(self):
|
||
|
return hash(self.__digged__)
|
||
|
|
||
|
def __getitem__(self, name):
|
||
|
if name in self._entries:
|
||
|
return getattr(self, name)
|
||
|
raise KeyError(name)
|