summaryrefslogtreecommitdiff
path: root/Lib/_weakrefset.py
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2008-02-05 00:20:01 +0000
committerRaymond Hettinger <python@rcn.com>2008-02-05 00:20:01 +0000
commit997b73cb240f2f5f80050926601855c0ed0c1cee (patch)
tree0533ca74a46047f4d236a16f8746be0c1897e257 /Lib/_weakrefset.py
parentc96164ac9fe9cbd94713e9f1a3f9a5b3499a74c2 (diff)
downloadcpython-997b73cb240f2f5f80050926601855c0ed0c1cee.tar.gz
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.py111
1 files changed, 111 insertions, 0 deletions
diff --git a/Lib/_weakrefset.py b/Lib/_weakrefset.py
new file mode 100644
index 0000000000..e56ac048dd
--- /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