@@ -36,41 +36,26 @@ def __exit__(self, e, t, b):
36
36
class WeakSet :
37
37
def __init__ (self , data = None ):
38
38
self .data = set ()
39
+
39
40
def _remove (item , selfref = ref (self )):
40
41
self = selfref ()
41
42
if self is not None :
42
- if self ._iterating :
43
- self ._pending_removals .append (item )
44
- else :
45
- self .data .discard (item )
43
+ self .data .discard (item )
44
+
46
45
self ._remove = _remove
47
- # A list of keys to be removed
48
- self ._pending_removals = []
49
- self ._iterating = set ()
50
46
if data is not None :
51
47
self .update (data )
52
48
53
- def _commit_removals (self ):
54
- pop = self ._pending_removals .pop
55
- discard = self .data .discard
56
- while True :
57
- try :
58
- item = pop ()
59
- except IndexError :
60
- return
61
- discard (item )
62
-
63
49
def __iter__ (self ):
64
- with _IterationGuard (self ):
65
- for itemref in self .data :
66
- item = itemref ()
67
- if item is not None :
68
- # Caveat: the iterator will keep a strong reference to
69
- # `item` until it is resumed or closed.
70
- yield item
50
+ for itemref in self .data .copy ():
51
+ item = itemref ()
52
+ if item is not None :
53
+ # Caveat: the iterator will keep a strong reference to
54
+ # `item` until it is resumed or closed.
55
+ yield item
71
56
72
57
def __len__ (self ):
73
- return len (self .data ) - len ( self . _pending_removals )
58
+ return len (self .data )
74
59
75
60
def __contains__ (self , item ):
76
61
try :
@@ -83,21 +68,15 @@ def __reduce__(self):
83
68
return self .__class__ , (list (self ),), self .__getstate__ ()
84
69
85
70
def add (self , item ):
86
- if self ._pending_removals :
87
- self ._commit_removals ()
88
71
self .data .add (ref (item , self ._remove ))
89
72
90
73
def clear (self ):
91
- if self ._pending_removals :
92
- self ._commit_removals ()
93
74
self .data .clear ()
94
75
95
76
def copy (self ):
96
77
return self .__class__ (self )
97
78
98
79
def pop (self ):
99
- if self ._pending_removals :
100
- self ._commit_removals ()
101
80
while True :
102
81
try :
103
82
itemref = self .data .pop ()
@@ -108,18 +87,12 @@ def pop(self):
108
87
return item
109
88
110
89
def remove (self , item ):
111
- if self ._pending_removals :
112
- self ._commit_removals ()
113
90
self .data .remove (ref (item ))
114
91
115
92
def discard (self , item ):
116
- if self ._pending_removals :
117
- self ._commit_removals ()
118
93
self .data .discard (ref (item ))
119
94
120
95
def update (self , other ):
121
- if self ._pending_removals :
122
- self ._commit_removals ()
123
96
for element in other :
124
97
self .add (element )
125
98
@@ -136,8 +109,6 @@ def difference(self, other):
136
109
def difference_update (self , other ):
137
110
self .__isub__ (other )
138
111
def __isub__ (self , other ):
139
- if self ._pending_removals :
140
- self ._commit_removals ()
141
112
if self is other :
142
113
self .data .clear ()
143
114
else :
@@ -151,8 +122,6 @@ def intersection(self, other):
151
122
def intersection_update (self , other ):
152
123
self .__iand__ (other )
153
124
def __iand__ (self , other ):
154
- if self ._pending_removals :
155
- self ._commit_removals ()
156
125
self .data .intersection_update (ref (item ) for item in other )
157
126
return self
158
127
@@ -184,8 +153,6 @@ def symmetric_difference(self, other):
184
153
def symmetric_difference_update (self , other ):
185
154
self .__ixor__ (other )
186
155
def __ixor__ (self , other ):
187
- if self ._pending_removals :
188
- self ._commit_removals ()
189
156
if self is other :
190
157
self .data .clear ()
191
158
else :
0 commit comments