Issue #14195: Make WeakSet.__lt__ and WeakSet.__gt__ irreflexive.

This commit is contained in:
Meador Inge 2012-03-04 22:02:17 -06:00
parent 94c2d6df54
commit 104f18977f
3 changed files with 33 additions and 17 deletions

View file

@ -154,17 +154,17 @@ class WeakSet(object):
def issubset(self, other): def issubset(self, other):
return self.data.issubset(ref(item) for item in other) return self.data.issubset(ref(item) for item in other)
__lt__ = issubset __le__ = issubset
def __le__(self, other): def __lt__(self, other):
return self.data <= set(ref(item) for item in other) return self.data < set(ref(item) for item in other)
def issuperset(self, other): def issuperset(self, other):
return self.data.issuperset(ref(item) for item in other) return self.data.issuperset(ref(item) for item in other)
__gt__ = issuperset __ge__ = issuperset
def __ge__(self, other): def __gt__(self, other):
return self.data >= set(ref(item) for item in other) return self.data > set(ref(item) for item in other)
def __eq__(self, other): def __eq__(self, other):
if not isinstance(other, self.__class__): if not isinstance(other, self.__class__):

View file

@ -41,6 +41,12 @@ class TestWeakSet(unittest.TestCase):
self.items = [SomeClass(c) for c in ('a', 'b', 'c')] self.items = [SomeClass(c) for c in ('a', 'b', 'c')]
self.items2 = [SomeClass(c) for c in ('x', 'y', 'z')] self.items2 = [SomeClass(c) for c in ('x', 'y', 'z')]
self.letters = [SomeClass(c) for c in string.ascii_letters] self.letters = [SomeClass(c) for c in string.ascii_letters]
self.ab_items = [SomeClass(c) for c in 'ab']
self.abcde_items = [SomeClass(c) for c in 'abcde']
self.def_items = [SomeClass(c) for c in 'def']
self.ab_weakset = WeakSet(self.ab_items)
self.abcde_weakset = WeakSet(self.abcde_items)
self.def_weakset = WeakSet(self.def_items)
self.s = WeakSet(self.items) self.s = WeakSet(self.items)
self.d = dict.fromkeys(self.items) self.d = dict.fromkeys(self.items)
self.obj = SomeClass('F') self.obj = SomeClass('F')
@ -149,22 +155,28 @@ class TestWeakSet(unittest.TestCase):
self.assertEqual(self.s ^ frozenset(self.items2), i) self.assertEqual(self.s ^ frozenset(self.items2), i)
def test_sub_and_super(self): def test_sub_and_super(self):
pl, ql, rl = map(lambda s: [SomeClass(c) for c in s], ['ab', 'abcde', 'def']) self.assertTrue(self.ab_weakset <= self.abcde_weakset)
p, q, r = map(WeakSet, (pl, ql, rl)) self.assertTrue(self.abcde_weakset <= self.abcde_weakset)
self.assertTrue(p < q) self.assertTrue(self.abcde_weakset >= self.ab_weakset)
self.assertTrue(p <= q) self.assertFalse(self.abcde_weakset <= self.def_weakset)
self.assertTrue(q <= q) self.assertFalse(self.abcde_weakset >= self.def_weakset)
self.assertTrue(q > p)
self.assertTrue(q >= p)
self.assertFalse(q < r)
self.assertFalse(q <= r)
self.assertFalse(q > r)
self.assertFalse(q >= r)
self.assertTrue(set('a').issubset('abc')) self.assertTrue(set('a').issubset('abc'))
self.assertTrue(set('abc').issuperset('a')) self.assertTrue(set('abc').issuperset('a'))
self.assertFalse(set('a').issubset('cbs')) self.assertFalse(set('a').issubset('cbs'))
self.assertFalse(set('cbs').issuperset('a')) self.assertFalse(set('cbs').issuperset('a'))
def test_lt(self):
self.assertTrue(self.ab_weakset < self.abcde_weakset)
self.assertFalse(self.abcde_weakset < self.def_weakset)
self.assertFalse(self.ab_weakset < self.ab_weakset)
self.assertFalse(WeakSet() < WeakSet())
def test_gt(self):
self.assertTrue(self.abcde_weakset > self.ab_weakset)
self.assertFalse(self.abcde_weakset > self.def_weakset)
self.assertFalse(self.ab_weakset > self.ab_weakset)
self.assertFalse(WeakSet() > WeakSet())
def test_gc(self): def test_gc(self):
# Create a nest of cycles to exercise overall ref count check # Create a nest of cycles to exercise overall ref count check
s = WeakSet(Foo() for i in range(1000)) s = WeakSet(Foo() for i in range(1000))

View file

@ -101,6 +101,10 @@ Core and Builtins
Library Library
------- -------
- Issue #14195: An issue that caused weakref.WeakSet instances to incorrectly
return True for a WeakSet instance 'a' in both 'a < a' and 'a > a' has been
fixed.
- Issue #14159: Fix the len() of weak sets to return a better approximation - Issue #14159: Fix the len() of weak sets to return a better approximation
when some objects are dead or dying. Moreover, the implementation is now when some objects are dead or dying. Moreover, the implementation is now
O(1) rather than O(n). O(1) rather than O(n).