|
import weakref |
|
|
|
class WeakList(list): |
|
def __init__(self, seq=()): |
|
list.__init__(self) |
|
self._refs = [] |
|
self._dirty=False |
|
for x in seq: self.append(x) |
|
|
|
def _mark_dirty(self, wref): |
|
self._dirty = True |
|
|
|
def flush(self): |
|
self._refs = [x for x in self._refs if x() is not None] |
|
self._dirty=False |
|
|
|
def __getitem__(self, idx): |
|
if self._dirty: self.flush() |
|
return self._refs[idx]() |
|
|
|
def __iter__(self): |
|
for ref in self._refs: |
|
obj = ref() |
|
if obj is not None: yield obj |
|
|
|
def __repr__(self): |
|
return "WeakList(%r)" % list(self) |
|
|
|
def __len__(self): |
|
if self._dirty: self.flush() |
|
return len(self._refs) |
|
|
|
def __setitem__(self, idx, obj): |
|
if isinstance(idx, slice): |
|
self._refs[idx] = [weakref.ref(obj, self._mark_dirty) for x in obj] |
|
else: |
|
self._refs[idx] = weakref.ref(obj, self._mark_dirty) |
|
|
|
def __delitem__(self, idx): |
|
del self._refs[idx] |
|
|
|
def append(self, obj): |
|
self._refs.append(weakref.ref(obj, self._mark_dirty)) |
|
|
|
def count(self, obj): |
|
return list(self).count(obj) |
|
|
|
def extend(self, items): |
|
for x in items: self.append(x) |
|
|
|
def index(self, obj): |
|
return list(self).index(obj) |
|
|
|
def insert(self, idx, obj): |
|
self._refs.insert(idx, weakref.ref(obj, self._mark_dirty)) |
|
|
|
def pop(self, idx): |
|
if self._dirty: self.flush() |
|
obj=self._refs[idx]() |
|
del self._refs[idx] |
|
return obj |
|
|
|
def remove(self, obj): |
|
if self._dirty: self.flush() |
|
for i, x in enumerate(self): |
|
if x == obj: |
|
del self[i] |
|
|
|
def reverse(self): |
|
self._refs.reverse() |
|
|
|
def sort(self, cmp=None, key=None, reverse=False): |
|
if self._dirty: self.flush() |
|
if key is not None: |
|
key = lambda x,key=key: key(x()) |
|
else: |
|
key = apply |
|
self._refs.sort(cmp=cmp, key=key, reverse=reverse) |
|
|
|
def __add__(self, other): |
|
l = WeakList(self) |
|
l.extend(other) |
|
return l |
|
|
|
def __iadd__(self, other): |
|
self.extend(other) |
|
return self |
|
|
|
def __contains__(self, obj): |
|
return obj in list(self) |
|
|
|
def __mul__(self, n): |
|
return WeakList(list(self)*n) |
|
|
|
def __imul__(self, n): |
|
self._refs *= n |
|
return self |