_weakrefset.py (5934B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\_weakrefset.py 2 from _weakref import ref 3 __all__ = ['WeakSet'] 4 5 class _IterationGuard(object): 6 7 def __init__(self, weakcontainer): 8 self.weakcontainer = ref(weakcontainer) 9 10 def __enter__(self): 11 w = self.weakcontainer() 12 if w is not None: 13 w._iterating.add(self) 14 return self 15 16 def __exit__(self, e, t, b): 17 w = self.weakcontainer() 18 if w is not None: 19 s = w._iterating 20 s.remove(self) 21 if not s: 22 w._commit_removals() 23 24 25 class WeakSet(object): 26 27 def __init__(self, data = None): 28 self.data = set() 29 30 def _remove(item, selfref = ref(self)): 31 self = selfref() 32 if self is not None: 33 if self._iterating: 34 self._pending_removals.append(item) 35 else: 36 self.data.discard(item) 37 38 self._remove = _remove 39 self._pending_removals = [] 40 self._iterating = set() 41 if data is not None: 42 self.update(data) 43 44 def _commit_removals(self): 45 l = self._pending_removals 46 discard = self.data.discard 47 while l: 48 discard(l.pop()) 49 50 def __iter__(self): 51 with _IterationGuard(self): 52 for itemref in self.data: 53 item = itemref() 54 if item is not None: 55 yield item 56 57 def __len__(self): 58 return sum((x() is not None for x in self.data)) 59 60 def __contains__(self, item): 61 return ref(item) in self.data 62 63 def __reduce__(self): 64 return (self.__class__, (list(self),), getattr(self, '__dict__', None)) 65 66 __hash__ = None 67 68 def add(self, item): 69 if self._pending_removals: 70 self._commit_removals() 71 self.data.add(ref(item, self._remove)) 72 73 def clear(self): 74 if self._pending_removals: 75 self._commit_removals() 76 self.data.clear() 77 78 def copy(self): 79 return self.__class__(self) 80 81 def pop(self): 82 if self._pending_removals: 83 self._commit_removals() 84 while True: 85 try: 86 itemref = self.data.pop() 87 except KeyError: 88 raise KeyError('pop from empty WeakSet') 89 90 item = itemref() 91 if item is not None: 92 return item 93 94 def remove(self, item): 95 if self._pending_removals: 96 self._commit_removals() 97 self.data.remove(ref(item)) 98 99 def discard(self, item): 100 if self._pending_removals: 101 self._commit_removals() 102 self.data.discard(ref(item)) 103 104 def update(self, other): 105 if self._pending_removals: 106 self._commit_removals() 107 if isinstance(other, self.__class__): 108 self.data.update(other.data) 109 else: 110 for element in other: 111 self.add(element) 112 113 def __ior__(self, other): 114 self.update(other) 115 return self 116 117 def _apply(self, other, method): 118 if not isinstance(other, self.__class__): 119 other = self.__class__(other) 120 newdata = method(other.data) 121 newset = self.__class__() 122 newset.data = newdata 123 return newset 124 125 def difference(self, other): 126 return self._apply(other, self.data.difference) 127 128 __sub__ = difference 129 130 def difference_update(self, other): 131 if self._pending_removals: 132 self._commit_removals() 133 if self is other: 134 self.data.clear() 135 else: 136 self.data.difference_update((ref(item) for item in other)) 137 138 def __isub__(self, other): 139 if self._pending_removals: 140 self._commit_removals() 141 if self is other: 142 self.data.clear() 143 else: 144 self.data.difference_update((ref(item) for item in other)) 145 return self 146 147 def intersection(self, other): 148 return self._apply(other, self.data.intersection) 149 150 __and__ = intersection 151 152 def intersection_update(self, other): 153 if self._pending_removals: 154 self._commit_removals() 155 self.data.intersection_update((ref(item) for item in other)) 156 157 def __iand__(self, other): 158 if self._pending_removals: 159 self._commit_removals() 160 self.data.intersection_update((ref(item) for item in other)) 161 return self 162 163 def issubset(self, other): 164 return self.data.issubset((ref(item) for item in other)) 165 166 __lt__ = issubset 167 168 def __le__(self, other): 169 return self.data <= set((ref(item) for item in other)) 170 171 def issuperset(self, other): 172 return self.data.issuperset((ref(item) for item in other)) 173 174 __gt__ = issuperset 175 176 def __ge__(self, other): 177 return self.data >= set((ref(item) for item in other)) 178 179 def __eq__(self, other): 180 if not isinstance(other, self.__class__): 181 return NotImplemented 182 return self.data == set((ref(item) for item in other)) 183 184 def symmetric_difference(self, other): 185 return self._apply(other, self.data.symmetric_difference) 186 187 __xor__ = symmetric_difference 188 189 def symmetric_difference_update(self, other): 190 if self._pending_removals: 191 self._commit_removals() 192 if self is other: 193 self.data.clear() 194 else: 195 self.data.symmetric_difference_update((ref(item) for item in other)) 196 197 def __ixor__(self, other): 198 if self._pending_removals: 199 self._commit_removals() 200 if self is other: 201 self.data.clear() 202 else: 203 self.data.symmetric_difference_update((ref(item) for item in other)) 204 return self 205 206 def union(self, other): 207 return self._apply(other, self.data.union) 208 209 __or__ = union 210 211 def isdisjoint(self, other): 212 return len(self.intersection(other)) == 0