Adjustments/retabbing for attrdict.py

Redid some of the logic behind AttrDict. It now raises AttributeError
when necessary, instead of giving the incorrect KeyError response.

This has restored compatibility with copy.deepcopy().
This commit is contained in:
karxi 2016-12-30 20:59:47 -05:00
parent d43220535f
commit 02019c7dc5

View file

@ -8,7 +8,7 @@ class AttrDict(dict):
def __setstate__(self, items):
for key, val in items: self.__dict__[key] = val
def __repr__(self):
return "%s(%s)" % (
return "{}({})".format(
type(self).__name__,
super(AttrDict, self).__repr__()
)
@ -18,10 +18,28 @@ class AttrDict(dict):
return super(AttrDict, self).__getitem__(name)
def __delitem__(self, name):
return super(AttrDict, self).__delitem__(name)
__getattr__ = __getitem__
def __getattr__(self, name):
# Basically, fall back on __getitem__ first
# Try to access ourselves as a dict. Failing that, check for attributes
# with the same name. Failing *that*, throw AttributeError to keep
# other code happy.
try: retval = self[name]
except KeyError as err:
try: retval = self.__dict__[name]
except KeyError:
# Raising KeyError here will confuse __deepcopy__, so don't do
# that.
raise AttributeError("No key/attr {!r}".format(name))
return retval
__setattr__ = __setitem__
__delattr__ = __delitem__
def __delattr__(self, name):
try: del self[name]
except KeyError as err:
try: del self.__dict__[name]
except KeyError:
raise AttributeError(str(err))
def copy(self): return type(self)(self)
__copy__ = copy
## end of http://code.activestate.com/recipes/473786/ }}}
class DefAttrDict(AttrDict):