diff options
author | Georg Brandl <georg@python.org> | 2007-10-23 06:26:46 (GMT) |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2007-10-23 06:26:46 (GMT) |
commit | 3b8cb17695209c48bfc618ba265d201e81d1603a (patch) | |
tree | 104dda0dd1ec84e9c8eacf05194cacb5698c9f36 /Lib/weakref.py | |
parent | b98dd2e5d2133b1c8cebd1dd221cf69eefeb154f (diff) | |
download | cpython-3b8cb17695209c48bfc618ba265d201e81d1603a.zip cpython-3b8cb17695209c48bfc618ba265d201e81d1603a.tar.gz cpython-3b8cb17695209c48bfc618ba265d201e81d1603a.tar.bz2 |
#1061 (mainly by Thomas Wouters): use weak sets for abc caches.
Diffstat (limited to 'Lib/weakref.py')
-rw-r--r-- | Lib/weakref.py | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/Lib/weakref.py b/Lib/weakref.py index c5e5247..c54a072 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -337,3 +337,108 @@ class WeakKeyDictionary(UserDict.UserDict): d[ref(key, self._remove)] = value if len(kwargs): self.update(kwargs) + + +class WeakSet: + def __init__(self, data=None): + self.data = set() + def _remove(item, selfref=ref(self)): + self = selfref() + if self is not None: + self.data.discard(item) + self._remove = _remove + if data is not None: + self.update(data) + + def __iter__(self): + for itemref in self.data: + item = itemref() + if item is not None: + yield item + + def __contains__(self, item): + return ref(item) in self.data + + def __reduce__(self): + return (self.__class__, (list(self),), + getattr(self, '__dict__', None)) + + def add(self, item): + self.data.add(ref(item, self._remove)) + + def clear(self): + self.data.clear() + + def copy(self): + return self.__class__(self) + + def pop(self): + while True: + itemref = self.data.pop() + item = itemref() + if item is not None: + return item + + def remove(self, item): + self.data.remove(ref(item)) + + def discard(self, item): + self.data.discard(ref(item)) + + def update(self, other): + if isinstance(other, self.__class__): + self.data.update(other.data) + else: + for element in other: + self.add(element) + __ior__ = update + + # Helper functions for simple delegating methods. + def _apply(self, other, method): + if not isinstance(other, self.__class__): + other = self.__class__(other) + newdata = method(other.data) + newset = self.__class__() + newset.data = newdata + return newset + + def _apply_mutate(self, other, method): + if not isinstance(other, self.__class__): + other = self.__class__(other) + method(other) + + def difference(self, other): + return self._apply(other, self.data.difference) + __sub__ = difference + + def difference_update(self, other): + self._apply_mutate(self, self.data.difference_update) + __isub__ = difference_update + + def intersection(self, other): + return self._apply(other, self.data.intersection) + __and__ = intersection + + def intersection_update(self, other): + self._apply_mutate(self, self.data.intersection_update) + __iand__ = intersection_update + + def issubset(self, other): + return self.data.issubset(ref(item) for item in other) + __lt__ = issubset + + def issuperset(self, other): + return self.data.issuperset(ref(item) for item in other) + __gt__ = issuperset + + def symmetric_difference(self, other): + return self._apply(other, self.data.symmetric_difference) + __xor__ = symmetric_difference + + def symmetric_difference_update(self, other): + self._apply_mutate(other, self.data.symmetric_difference_update) + __ixor__ = symmetric_difference_update + + def union(self, other): + self._apply_mutate(other, self.data.union) + __or__ = union |