NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

_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