diff options
author | Raymond Hettinger <python@rcn.com> | 2008-02-05 00:20:01 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2008-02-05 00:20:01 (GMT) |
commit | 93fa608626562d3925104f98372dbdd27aeafcf0 (patch) | |
tree | 2f2b204763333a3e637e3effa274f3b8895c9124 /Lib/_weakrefset.py | |
parent | 2add352c435f8973274f16c37eb6246f86799722 (diff) | |
download | cpython-93fa608626562d3925104f98372dbdd27aeafcf0.zip cpython-93fa608626562d3925104f98372dbdd27aeafcf0.tar.gz cpython-93fa608626562d3925104f98372dbdd27aeafcf0.tar.bz2 |
Moved WeakSet into a bootstap module use by abc.py.
This makes it possible to use ABCs in weakref.py
(which will be done in a later checkin).
Diffstat (limited to 'Lib/_weakrefset.py')
-rw-r--r-- | Lib/_weakrefset.py | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/Lib/_weakrefset.py b/Lib/_weakrefset.py new file mode 100644 index 0000000..e56ac04 --- /dev/null +++ b/Lib/_weakrefset.py @@ -0,0 +1,111 @@ +# Access WeakSet through the weakref module. +# This code is separated-out because it is needed +# by abc.py to load everything else at startup. + +from _weakref import ref + +__all__ = ['WeakSet'] + +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 |