# Access WeakSet through the weakref module.# This code is separated-out because it is needed# by abc.py to load everything else at startup.from _weakref import ref__all__ = ['WeakSet']class _IterationGuard:# This context manager registers itself in the current iterators of the# weak container, such as to delay all removals until the context manager# exits.# This technique should be relatively thread-safe (since sets are).def __init__(self, weakcontainer):# Don't create cyclesself.weakcontainer = ref(weakcontainer)def __enter__(self):w = self.weakcontainer()if w is not None:w._iterating.add(self)return selfdef __exit__(self, e, t, b):w = self.weakcontainer()if w is not None:s = w._iteratings.remove(self)if not s:w._commit_removals()class WeakSet:def __init__(self, data=None):self.data = set()def _remove(item, selfref=ref(self)):self = selfref()if self is not None:if self._iterating:self._pending_removals.append(item)else:self.data.discard(item)self._remove = _remove# A list of keys to be removedself._pending_removals = []self._iterating = set()if data is not None:self.update(data)def _commit_removals(self):l = self._pending_removalsdiscard = self.data.discardwhile l:discard(l.pop())def __iter__(self):with _IterationGuard(self):for itemref in self.data:item = itemref()if item is not None:# Caveat: the iterator will keep a strong reference to# `item` until it is resumed or closed.yield itemdef __len__(self):return len(self.data) - len(self._pending_removals)def __contains__(self, item):try:wr = ref(item)except TypeError:return Falsereturn wr in self.datadef __reduce__(self):return (self.__class__, (list(self),),getattr(self, '__dict__', None))def add(self, item):if self._pending_removals:self._commit_removals()self.data.add(ref(item, self._remove))def clear(self):if self._pending_removals:self._commit_removals()self.data.clear()def copy(self):return self.__class__(self)def pop(self):if self._pending_removals:self._commit_removals()while True:try:itemref = self.data.pop()except KeyError:raise KeyError('pop from empty WeakSet') from Noneitem = itemref()if item is not None:return itemdef remove(self, item):if self._pending_removals:self._commit_removals()self.data.remove(ref(item))def discard(self, item):if self._pending_removals:self._commit_removals()self.data.discard(ref(item))def update(self, other):if self._pending_removals:self._commit_removals()for element in other:self.add(element)def __ior__(self, other):self.update(other)return selfdef difference(self, other):newset = self.copy()newset.difference_update(other)return newset__sub__ = differencedef difference_update(self, other):self.__isub__(other)def __isub__(self, other):if self._pending_removals:self._commit_removals()if self is other:self.data.clear()else:self.data.difference_update(ref(item) for item in other)return selfdef intersection(self, other):return self.__class__(item for item in other if item in self)__and__ = intersectiondef intersection_update(self, other):self.__iand__(other)def __iand__(self, other):if self._pending_removals:self._commit_removals()self.data.intersection_update(ref(item) for item in other)return selfdef issubset(self, other):return self.data.issubset(ref(item) for item in other)__le__ = issubsetdef __lt__(self, other):return self.data < set(map(ref, other))def issuperset(self, other):return self.data.issuperset(ref(item) for item in other)__ge__ = issupersetdef __gt__(self, other):return self.data > set(map(ref, other))def __eq__(self, other):if not isinstance(other, self.__class__):return NotImplementedreturn self.data == set(map(ref, other))def symmetric_difference(self, other):newset = self.copy()newset.symmetric_difference_update(other)return newset__xor__ = symmetric_differencedef symmetric_difference_update(self, other):self.__ixor__(other)def __ixor__(self, other):if self._pending_removals:self._commit_removals()if self is other:self.data.clear()else:self.data.symmetric_difference_update(ref(item, self._remove) for item in other)return selfdef union(self, other):return self.__class__(e for s in (self, other) for e in s)__or__ = uniondef isdisjoint(self, other):return len(self.intersection(other)) == 0def __repr__(self):return repr(self.data)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。