""" Copyright 2001, Andres Tuells Permission to use, copy, modify, and distribute this software for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of the authors not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """ from weakref import ref, BaseIter from UserList import UserList class WeakList(UserList): """A list class that references items weakly. Entries in the list will be discarded when no strong reference to the value exists anymore """ def __init__(self, _list = []): self.data = [] self.extend(_list) def append(self, item): self.data.append(self.__ref(item)) def count(self, item): self.data.count(self.__ref(item)) def extend(self, items): self.data.extend(map(self.__ref,self.__cast(items))) def index(self, item): return self.data.index(self.__ref(item)) def insert(self, i, item): self.data.insert(i,self.__ref(item)) def pop(self, index = -1): while 1: result = self.data.pop(index)() if result is not None: return result def remove(self, item): self.data.remove(self.__ref(item)) def reverse(self): self.data.reverse() def sort(self): _list = map(apply,self.data) _list.sort() self.data = map(self.__ref, _list) def toList(self): while 1: result = map(apply,self.data) if not None in result: return result def __add__(self, items): return WeakList(self.toList() + items) def __iadd__(self, items): self.extend(items) return self def __contains__(self, item): return self.__ref(item) in self.data def __len__(self): return len(self.data) def __mul__(self, i): return self.__class__(self.toList()*i) def __rmul__(self, i): return self.__class__(i*self.toList()) def __imul__(self, i): _list = self.toList() _list*=i self.data = [] self.extend(_list) return self def __getitem__(self, i): while 1: result = self.data[i]() if result is not None: return result def __setitem__(self, i, item): self.data[i] = self.__ref(item) def __delitem__(self, i): del self.data[i] def __getslice__(self, i, j): while 1: result = map(apply, self.data[i:j]) if not None in result: return self.__class__(result) def __setslice__(self, i, j, items): self.data[i:j]= map(self.__ref,items[:]) def __delslice__(self, i, j): del self.data[i:j] def __str__(self): return "" % (id(self), self.toList()) __repr__ = __str__ def __iter__(self): return WeakListIterator(self) def __lt__(self, other): return self.toList() < self.__cast(other) def __le__(self, other): return self.toList() <= self.__cast(other) def __eq__(self, other): return self.toList() == self.__cast(other) def __ne__(self, other): return self.toList() != self.__cast(other) def __gt__(self, other): return self.toList() > self.__cast(other) def __ge__(self, other): return self.toList() >= self.__cast(other) def __cmp__(self, other): return cmp(self.toList(), self.__cast(other)) def __cast(self,_list): if isinstance(_list, self.__class__):return _list.toList() return list(_list) def __ref(self, obj): return ref(obj, self.__removeAll) def __removeAll(self, item): l = self.data while item in l: l.remove(item) class WeakListIterator(BaseIter): def __init__(self, weakList): self._weakList = WeakList(weakList.toList()) def next(self): try: return self._weakList.pop(0) except IndexError: raise StopIteration del UserList