Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
87 lines (70 sloc) 2.38 KB
import collections
class Expando(object):
"""
A completely promiscous object that makes attributes out of
key/value parameters to it's `__init__()` method.
"""
def __init__(self, *args, **kw):
self.update(**kw)
def update(self, **variation):
"""
Writes over arbitrary attributes in the `Expando` object, same
semantics as `dict.update()`.
"""
self.__dict__.update(variation)
def __repr__(self):
"""
Writes out all attributes of the object.
Thanks Chris Jones
"""
a = ', '.join('%s=%r' % i for i in self.__dict__.items())
return '<%s object at 0x%x%s%s>' % (
type(self).__name__, id(self), ': ' if a else '', a)
def __nonzero__(self):
return bool(self.__dict__)
E = Expando
class forget:
"""
Marker class to signal a value that should be deleted in an
Altered States run.
"""
def change(orig, getter, setter, deleter, **attrs):
"""
Alter `orig` using the functions `getter`, `setter` and `deleter`
with the contents of `**attrs`. The get/set/delete use the same
semantics as standard `getattr`/`setattr` and `delattr`.
While `change()` alters `orig` it also builds a diff of what it
has done to later be passed to `restore()` to reset `orig` till
it's original state.
"""
diff = {}
for key, val in attrs.iteritems():
diff[key] = getter(orig, key, forget)
if val is forget:
deleter(orig, key)
else:
setter(orig, key, val)
return diff
def restore(orig, diff, getter, setter, deleter):
"""
Takes a diff produced by `change()` and applies it to `orig` to
make it revert to the state it had before `change()` was called on
it.
"""
for key, old in diff.iteritems():
if old is forget:
deleter(orig, key)
else:
setter(orig, key, old)
def dictlike(cand):
"Determines if `dict` or `object` semantics should be used"
return isinstance(cand, collections.Mapping)
def dictget(dct, key, default):
"Provides `getattr` semantics for modifying dictionaries."
return dct.get(key, default)
def dictset(dct, key, val):
"Provides `setattr` semantics for modifying dictionaries."
dct[key] = val
def dictdel(dct, key):
"Provides `delattr` semantics for modifiyng dictionaries."
del dct[key]