blob: e56ac048dd571f37c2e1997481263aa8a2df01e6 [file] [log] [blame]
Raymond Hettinger93fa6082008-02-05 00:20:01 +00001# Access WeakSet through the weakref module.
2# This code is separated-out because it is needed
3# by abc.py to load everything else at startup.
4
5from _weakref import ref
6
7__all__ = ['WeakSet']
8
9class WeakSet:
10 def __init__(self, data=None):
11 self.data = set()
12 def _remove(item, selfref=ref(self)):
13 self = selfref()
14 if self is not None:
15 self.data.discard(item)
16 self._remove = _remove
17 if data is not None:
18 self.update(data)
19
20 def __iter__(self):
21 for itemref in self.data:
22 item = itemref()
23 if item is not None:
24 yield item
25
26 def __contains__(self, item):
27 return ref(item) in self.data
28
29 def __reduce__(self):
30 return (self.__class__, (list(self),),
31 getattr(self, '__dict__', None))
32
33 def add(self, item):
34 self.data.add(ref(item, self._remove))
35
36 def clear(self):
37 self.data.clear()
38
39 def copy(self):
40 return self.__class__(self)
41
42 def pop(self):
43 while True:
44 itemref = self.data.pop()
45 item = itemref()
46 if item is not None:
47 return item
48
49 def remove(self, item):
50 self.data.remove(ref(item))
51
52 def discard(self, item):
53 self.data.discard(ref(item))
54
55 def update(self, other):
56 if isinstance(other, self.__class__):
57 self.data.update(other.data)
58 else:
59 for element in other:
60 self.add(element)
61 __ior__ = update
62
63 # Helper functions for simple delegating methods.
64 def _apply(self, other, method):
65 if not isinstance(other, self.__class__):
66 other = self.__class__(other)
67 newdata = method(other.data)
68 newset = self.__class__()
69 newset.data = newdata
70 return newset
71
72 def _apply_mutate(self, other, method):
73 if not isinstance(other, self.__class__):
74 other = self.__class__(other)
75 method(other)
76
77 def difference(self, other):
78 return self._apply(other, self.data.difference)
79 __sub__ = difference
80
81 def difference_update(self, other):
82 self._apply_mutate(self, self.data.difference_update)
83 __isub__ = difference_update
84
85 def intersection(self, other):
86 return self._apply(other, self.data.intersection)
87 __and__ = intersection
88
89 def intersection_update(self, other):
90 self._apply_mutate(self, self.data.intersection_update)
91 __iand__ = intersection_update
92
93 def issubset(self, other):
94 return self.data.issubset(ref(item) for item in other)
95 __lt__ = issubset
96
97 def issuperset(self, other):
98 return self.data.issuperset(ref(item) for item in other)
99 __gt__ = issuperset
100
101 def symmetric_difference(self, other):
102 return self._apply(other, self.data.symmetric_difference)
103 __xor__ = symmetric_difference
104
105 def symmetric_difference_update(self, other):
106 self._apply_mutate(other, self.data.symmetric_difference_update)
107 __ixor__ = symmetric_difference_update
108
109 def union(self, other):
110 self._apply_mutate(other, self.data.union)
111 __or__ = union