Skip to content

Commit 9dba5d9

Browse files
committed
Add a test suite for WeakSet mostly derived from test_set and fix some
issues in the weakset implementation discovered with it.
1 parent c4dc0d4 commit 9dba5d9

File tree

2 files changed

+353
-12
lines changed

2 files changed

+353
-12
lines changed

Lib/_weakrefset.py

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ def __iter__(self):
2323
if item is not None:
2424
yield item
2525

26+
def __len__(self):
27+
return sum(x() is not None for x in self.data)
28+
2629
def __contains__(self, item):
2730
return ref(item) in self.data
2831

@@ -61,7 +64,9 @@ def update(self, other):
6164
else:
6265
for element in other:
6366
self.add(element)
64-
__ior__ = update
67+
def __ior__(self, other):
68+
self.update(other)
69+
return self
6570

6671
# Helper functions for simple delegating methods.
6772
def _apply(self, other, method):
@@ -72,43 +77,68 @@ def _apply(self, other, method):
7277
newset.data = newdata
7378
return newset
7479

75-
def _apply_mutate(self, other, method):
76-
if not isinstance(other, self.__class__):
77-
other = self.__class__(other)
78-
method(other)
79-
8080
def difference(self, other):
8181
return self._apply(other, self.data.difference)
8282
__sub__ = difference
8383

8484
def difference_update(self, other):
85-
self._apply_mutate(self, self.data.difference_update)
86-
__isub__ = difference_update
85+
if self is other:
86+
self.data.clear()
87+
else:
88+
self.data.difference_update(ref(item) for item in other)
89+
def __isub__(self, other):
90+
if self is other:
91+
self.data.clear()
92+
else:
93+
self.data.difference_update(ref(item) for item in other)
94+
return self
8795

8896
def intersection(self, other):
8997
return self._apply(other, self.data.intersection)
9098
__and__ = intersection
9199

92100
def intersection_update(self, other):
93-
self._apply_mutate(self, self.data.intersection_update)
94-
__iand__ = intersection_update
101+
self.data.intersection_update(ref(item) for item in other)
102+
def __iand__(self, other):
103+
self.data.intersection_update(ref(item) for item in other)
104+
return self
95105

96106
def issubset(self, other):
97107
return self.data.issubset(ref(item) for item in other)
98108
__lt__ = issubset
99109

110+
def __le__(self, other):
111+
return self.data <= set(ref(item) for item in other)
112+
100113
def issuperset(self, other):
101114
return self.data.issuperset(ref(item) for item in other)
102115
__gt__ = issuperset
103116

117+
def __ge__(self, other):
118+
return self.data >= set(ref(item) for item in other)
119+
120+
def __eq__(self, other):
121+
return self.data == set(ref(item) for item in other)
122+
104123
def symmetric_difference(self, other):
105124
return self._apply(other, self.data.symmetric_difference)
106125
__xor__ = symmetric_difference
107126

108127
def symmetric_difference_update(self, other):
109-
self._apply_mutate(other, self.data.symmetric_difference_update)
110-
__ixor__ = symmetric_difference_update
128+
if self is other:
129+
self.data.clear()
130+
else:
131+
self.data.symmetric_difference_update(ref(item) for item in other)
132+
def __ixor__(self, other):
133+
if self is other:
134+
self.data.clear()
135+
else:
136+
self.data.symmetric_difference_update(ref(item) for item in other)
137+
return self
111138

112139
def union(self, other):
113140
return self._apply(other, self.data.union)
114141
__or__ = union
142+
143+
def isdisjoint(self, other):
144+
return len(self.intersection(other)) == 0

0 commit comments

Comments
 (0)