]> git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.2/Lib/_weakrefset.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / _weakrefset.py
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.
4
5 from _weakref import ref
6
7 __all__ = ['WeakSet']
8
9
10 class _IterationGuard(object):
11 # This context manager registers itself in the current iterators of the
12 # weak container, such as to delay all removals until the context manager
13 # exits.
14 # This technique should be relatively thread-safe (since sets are).
15
16 def __init__(self, weakcontainer):
17 # Don't create cycles
18 self.weakcontainer = ref(weakcontainer)
19
20 def __enter__(self):
21 w = self.weakcontainer()
22 if w is not None:
23 w._iterating.add(self)
24 return self
25
26 def __exit__(self, e, t, b):
27 w = self.weakcontainer()
28 if w is not None:
29 s = w._iterating
30 s.remove(self)
31 if not s:
32 w._commit_removals()
33
34
35 class WeakSet(object):
36 def __init__(self, data=None):
37 self.data = set()
38 def _remove(item, selfref=ref(self)):
39 self = selfref()
40 if self is not None:
41 if self._iterating:
42 self._pending_removals.append(item)
43 else:
44 self.data.discard(item)
45 self._remove = _remove
46 # A list of keys to be removed
47 self._pending_removals = []
48 self._iterating = set()
49 if data is not None:
50 self.update(data)
51
52 def _commit_removals(self):
53 l = self._pending_removals
54 discard = self.data.discard
55 while l:
56 discard(l.pop())
57
58 def __iter__(self):
59 with _IterationGuard(self):
60 for itemref in self.data:
61 item = itemref()
62 if item is not None:
63 yield item
64
65 def __len__(self):
66 return sum(x() is not None for x in self.data)
67
68 def __contains__(self, item):
69 try:
70 wr = ref(item)
71 except TypeError:
72 return False
73 return wr in self.data
74
75 def __reduce__(self):
76 return (self.__class__, (list(self),),
77 getattr(self, '__dict__', None))
78
79 __hash__ = None
80
81 def add(self, item):
82 if self._pending_removals:
83 self._commit_removals()
84 self.data.add(ref(item, self._remove))
85
86 def clear(self):
87 if self._pending_removals:
88 self._commit_removals()
89 self.data.clear()
90
91 def copy(self):
92 return self.__class__(self)
93
94 def pop(self):
95 if self._pending_removals:
96 self._commit_removals()
97 while True:
98 try:
99 itemref = self.data.pop()
100 except KeyError:
101 raise KeyError('pop from empty WeakSet')
102 item = itemref()
103 if item is not None:
104 return item
105
106 def remove(self, item):
107 if self._pending_removals:
108 self._commit_removals()
109 self.data.remove(ref(item))
110
111 def discard(self, item):
112 if self._pending_removals:
113 self._commit_removals()
114 self.data.discard(ref(item))
115
116 def update(self, other):
117 if self._pending_removals:
118 self._commit_removals()
119 if isinstance(other, self.__class__):
120 self.data.update(other.data)
121 else:
122 for element in other:
123 self.add(element)
124
125 def __ior__(self, other):
126 self.update(other)
127 return self
128
129 # Helper functions for simple delegating methods.
130 def _apply(self, other, method):
131 if not isinstance(other, self.__class__):
132 other = self.__class__(other)
133 newdata = method(other.data)
134 newset = self.__class__()
135 newset.data = newdata
136 return newset
137
138 def difference(self, other):
139 return self._apply(other, self.data.difference)
140 __sub__ = difference
141
142 def difference_update(self, other):
143 if self._pending_removals:
144 self._commit_removals()
145 if self is other:
146 self.data.clear()
147 else:
148 self.data.difference_update(ref(item) for item in other)
149 def __isub__(self, other):
150 if self._pending_removals:
151 self._commit_removals()
152 if self is other:
153 self.data.clear()
154 else:
155 self.data.difference_update(ref(item) for item in other)
156 return self
157
158 def intersection(self, other):
159 return self._apply(other, self.data.intersection)
160 __and__ = intersection
161
162 def intersection_update(self, other):
163 if self._pending_removals:
164 self._commit_removals()
165 self.data.intersection_update(ref(item) for item in other)
166 def __iand__(self, other):
167 if self._pending_removals:
168 self._commit_removals()
169 self.data.intersection_update(ref(item) for item in other)
170 return self
171
172 def issubset(self, other):
173 return self.data.issubset(ref(item) for item in other)
174 __lt__ = issubset
175
176 def __le__(self, other):
177 return self.data <= set(ref(item) for item in other)
178
179 def issuperset(self, other):
180 return self.data.issuperset(ref(item) for item in other)
181 __gt__ = issuperset
182
183 def __ge__(self, other):
184 return self.data >= set(ref(item) for item in other)
185
186 def __eq__(self, other):
187 if not isinstance(other, self.__class__):
188 return NotImplemented
189 return self.data == set(ref(item) for item in other)
190
191 def symmetric_difference(self, other):
192 return self._apply(other, self.data.symmetric_difference)
193 __xor__ = symmetric_difference
194
195 def symmetric_difference_update(self, other):
196 if self._pending_removals:
197 self._commit_removals()
198 if self is other:
199 self.data.clear()
200 else:
201 self.data.symmetric_difference_update(ref(item) for item in other)
202 def __ixor__(self, other):
203 if self._pending_removals:
204 self._commit_removals()
205 if self is other:
206 self.data.clear()
207 else:
208 self.data.symmetric_difference_update(ref(item) for item in other)
209 return self
210
211 def union(self, other):
212 return self._apply(other, self.data.union)
213 __or__ = union
214
215 def isdisjoint(self, other):
216 return len(self.intersection(other)) == 0