update pydoc topics
[python/dscho.git] / Lib / _weakrefset.py
blobaddc7afeef9a3afdbdd975649ac5a9c5fdb9ded1
1 # 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.
5 from _weakref import ref
7 __all__ = ['WeakSet']
9 class 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)
20 def __iter__(self):
21 for itemref in self.data:
22 item = itemref()
23 if item is not None:
24 yield item
26 def __len__(self):
27 return sum(x() is not None for x in self.data)
29 def __contains__(self, item):
30 return ref(item) in self.data
32 def __reduce__(self):
33 return (self.__class__, (list(self),),
34 getattr(self, '__dict__', None))
36 def add(self, item):
37 self.data.add(ref(item, self._remove))
39 def clear(self):
40 self.data.clear()
42 def copy(self):
43 return self.__class__(self)
45 def pop(self):
46 while True:
47 try:
48 itemref = self.data.pop()
49 except KeyError:
50 raise KeyError('pop from empty WeakSet')
51 item = itemref()
52 if item is not None:
53 return item
55 def remove(self, item):
56 self.data.remove(ref(item))
58 def discard(self, item):
59 self.data.discard(ref(item))
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)
67 def __ior__(self, other):
68 self.update(other)
69 return self
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
80 def difference(self, other):
81 return self._apply(other, self.data.difference)
82 __sub__ = difference
84 def difference_update(self, other):
85 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
96 def intersection(self, other):
97 return self._apply(other, self.data.intersection)
98 __and__ = intersection
100 def intersection_update(self, other):
101 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
106 def issubset(self, other):
107 return self.data.issubset(ref(item) for item in other)
108 __lt__ = issubset
110 def __le__(self, other):
111 return self.data <= set(ref(item) for item in other)
113 def issuperset(self, other):
114 return self.data.issuperset(ref(item) for item in other)
115 __gt__ = issuperset
117 def __ge__(self, other):
118 return self.data >= set(ref(item) for item in other)
120 def __eq__(self, other):
121 if not isinstance(other, self.__class__):
122 return NotImplemented
123 return self.data == set(ref(item) for item in other)
125 def symmetric_difference(self, other):
126 return self._apply(other, self.data.symmetric_difference)
127 __xor__ = symmetric_difference
129 def symmetric_difference_update(self, other):
130 if self is other:
131 self.data.clear()
132 else:
133 self.data.symmetric_difference_update(ref(item) for item in other)
134 def __ixor__(self, other):
135 if self is other:
136 self.data.clear()
137 else:
138 self.data.symmetric_difference_update(ref(item) for item in other)
139 return self
141 def union(self, other):
142 return self._apply(other, self.data.union)
143 __or__ = union
145 def isdisjoint(self, other):
146 return len(self.intersection(other)) == 0