pypsyc/mjacob2/pypsyc/client/observable.py

109 lines
2.9 KiB
Python

"""
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])