blob: 0046133925df9f6d0950efb145cc9bb1372b2b75 [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
Georg Brandl9dba5d92008-05-18 16:27:29 +000026 def __len__(self):
27 return sum(x() is not None for x in self.data)
28
Raymond Hettinger93fa6082008-02-05 00:20:01 +000029 def __contains__(self, item):
30 return ref(item) in self.data
31
32 def __reduce__(self):
33 return (self.__class__, (list(self),),
34 getattr(self, '__dict__', None))
35
36 def add(self, item):
37 self.data.add(ref(item, self._remove))
38
39 def clear(self):
40 self.data.clear()
41
42 def copy(self):
43 return self.__class__(self)
44
45 def pop(self):
46 while True:
Georg Brandlbf93b042008-05-18 07:46:13 +000047 try:
48 itemref = self.data.pop()
49 except KeyError:
50 raise KeyError('pop from empty WeakSet')
Raymond Hettinger93fa6082008-02-05 00:20:01 +000051 item = itemref()
52 if item is not None:
53 return item
54
55 def remove(self, item):
56 self.data.remove(ref(item))
57
58 def discard(self, item):
59 self.data.discard(ref(item))
60
61 def update(self, other):
62 if isinstance(other, self.__class__):
63 self.data.update(other.data)
64 else:
65 for element in other:
66 self.add(element)
Georg Brandl9dba5d92008-05-18 16:27:29 +000067 def __ior__(self, other):
68 self.update(other)
69 return self
Raymond Hettinger93fa6082008-02-05 00:20:01 +000070
71 # Helper functions for simple delegating methods.
72 def _apply(self, other, method):
73 if not isinstance(other, self.__class__):
74 other = self.__class__(other)
75 newdata = method(other.data)
76 newset = self.__class__()
77 newset.data = newdata
78 return newset
79
Raymond Hettinger93fa6082008-02-05 00:20:01 +000080 def difference(self, other):
81 return self._apply(other, self.data.difference)
82 __sub__ = difference
83
84 def difference_update(self, other):
Georg Brandl9dba5d92008-05-18 16:27:29 +000085 if self is other:
86 self.data.clear()
87 else:
88 self.data.difference_update(ref(item) for item in other)
89 def __isub__(self, other):
90 if self is other:
91 self.data.clear()
92 else:
93 self.data.difference_update(ref(item) for item in other)
94 return self
Raymond Hettinger93fa6082008-02-05 00:20:01 +000095
96 def intersection(self, other):
97 return self._apply(other, self.data.intersection)
98 __and__ = intersection
99
100 def intersection_update(self, other):
Georg Brandl9dba5d92008-05-18 16:27:29 +0000101 self.data.intersection_update(ref(item) for item in other)
102 def __iand__(self, other):
103 self.data.intersection_update(ref(item) for item in other)
104 return self
Raymond Hettinger93fa6082008-02-05 00:20:01 +0000105
106 def issubset(self, other):
107 return self.data.issubset(ref(item) for item in other)
108 __lt__ = issubset
109
Georg Brandl9dba5d92008-05-18 16:27:29 +0000110 def __le__(self, other):
111 return self.data <= set(ref(item) for item in other)
112
Raymond Hettinger93fa6082008-02-05 00:20:01 +0000113 def issuperset(self, other):
114 return self.data.issuperset(ref(item) for item in other)
115 __gt__ = issuperset
116
Georg Brandl9dba5d92008-05-18 16:27:29 +0000117 def __ge__(self, other):
118 return self.data >= set(ref(item) for item in other)
119
120 def __eq__(self, other):
121 return self.data == set(ref(item) for item in other)
122
Raymond Hettinger93fa6082008-02-05 00:20:01 +0000123 def symmetric_difference(self, other):
124 return self._apply(other, self.data.symmetric_difference)
125 __xor__ = symmetric_difference
126
127 def symmetric_difference_update(self, other):
Georg Brandl9dba5d92008-05-18 16:27:29 +0000128 if self is other:
129 self.data.clear()
130 else:
131 self.data.symmetric_difference_update(ref(item) for item in other)
132 def __ixor__(self, other):
133 if self is other:
134 self.data.clear()
135 else:
136 self.data.symmetric_difference_update(ref(item) for item in other)
137 return self
Raymond Hettinger93fa6082008-02-05 00:20:01 +0000138
139 def union(self, other):
Georg Brandlbf93b042008-05-18 07:46:13 +0000140 return self._apply(other, self.data.union)
Raymond Hettinger93fa6082008-02-05 00:20:01 +0000141 __or__ = union
Georg Brandl9dba5d92008-05-18 16:27:29 +0000142
143 def isdisjoint(self, other):
144 return len(self.intersection(other)) == 0