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