# (c) Copyright 2020 by Coinkite Inc. This file is covered by license found in COPYING-CC. # # objstruct.py # class ObjectStruct(dict): '''An object like both a dict and also an object that you can easily use attr reference to get members. Construct with a dict or like a dict. ''' def __getattr__(self, name): if name in self: return self[name] else: # Do not return a default here because it breaks things raise AttributeError('No such attribute: %s' % name) def __setattr__(self, name, value): self[name] = value def __delattr__(self, name): del self[name] def __repr__(self): ret = '<%s:' % self.__class__.__name__ for k,v in self.items(): ret += ' %s=%r' % (k, v) return ret + '>' @classmethod def promote(cls, x): # Often I get a dict() from an API wrapper that's taken some json and # run it thru json.loads(). It would be better to have that as nested # ObjectStruct (which is easily done with some arguments to loads, but # usually they don't provide that feature)... so call this function # if isinstance(x, list): return [cls.promote(i) for i in x] if isinstance(x, dict): x = cls(x) for k in x: x[k] = cls.promote(x[k]) return x class DefaultObjectStruct(ObjectStruct): ''' Same, but can provide a default value if get_default is overriden''' def get_default(self, fldname): # override me return None def __getattr__(self, name): if name in self: return self[name] else: # sometimes you do want a default. return self.get_default(name) # EOF