""" pypsyc.client.observable ~~~~~~~~~~~~~~~~~~ :copyright: 2010 by Manuel Jacob :license: MIT """ from collections import MutableSequence, MutableMapping from pypsyc.util import Event class ObsAttr(object): def __init__(self, name): self.name = name def __get__(self, instance, owner): try: return instance.__dict__[self.name] except KeyError: raise AttributeError def __set__(self, instance, value): old = instance.__dict__.get(self.name) instance.__dict__[self.name] = value if value != old: instance.update_evt[self.name](old, value) def __delete__(self, instance): old = instance.__dict__.get(self.name) try: del instance.__dict__[self.name] except KeyError: raise AttributeError instance.update_evt[self.name](old, None) class ObsObj(object): def __init__(self): self.update_evt = dict((obs_attr.name, Event()) for obs_attr in self.__class__.__dict__.itervalues() if isinstance(obs_attr, ObsAttr)) class ObsList(list, MutableSequence): def __init__(self, *args, **kwds): list.__init__(self, *args, **kwds) self.setitem_evt = Event() self.delitem_evt = Event() self.insert_evt = Event() self.update_evt = Event() def __setitem__(self, index, value): old = self[index] list.__setitem__(self, index, value) if value != old: self.setitem_evt(index, old, value) def __delitem__(self, index): if index < 0: index = len(self) + index old = self[index] list.__delitem__(self, index) self.delitem_evt(index, old) def insert(self, index, value): list.insert(self, index, value) self.insert_evt(index, value) append = MutableSequence.append reverse = MutableSequence.reverse extend = MutableSequence.extend pop = MutableSequence.pop remove = MutableSequence.remove __iadd__ = MutableSequence.__iadd__ def updated_item(self, obj): self.update_evt(self.index(obj), obj) class ObsDict(dict, MutableMapping): def __init__(self, *args, **kwds): dict.__init__(self, *args, **kwds) self.setitem_evt = Event() self.delitem_evt = Event() self.update_evt = Event() def __setitem__(self, key, value): old = self.get(key) dict.__setitem__(self, key, value) if value != old: self.setitem_evt(key, old, value) def __delitem__(self, key): old = self.get(key) dict.__delitem__(self, key) self.delitem_evt(key, old) pop = MutableMapping.pop popitem = MutableMapping.popitem clear = MutableMapping.clear update = MutableMapping.update setdefault = MutableMapping.setdefault def updated_item(self, key): self.update_evt(key, self[key])