Skip to content

Commit 10ab4ae

Browse files
committed
Patch by Keir Mierle so that sets can be compared to other objects that know
how to compare themselves to sets. (Prep work for making dict views more set-like.)
1 parent 928115a commit 10ab4ae

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

Lib/test/test_set.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,42 @@ def test_weakref(self):
492492
s = None
493493
self.assertRaises(ReferenceError, str, p)
494494

495+
def test_rich_compare(self):
496+
class TestRichSetCompare:
497+
def __gt__(self, some_set):
498+
self.gt_called = True
499+
return False
500+
def __lt__(self, some_set):
501+
self.lt_called = True
502+
return False
503+
def __ge__(self, some_set):
504+
self.ge_called = True
505+
return False
506+
def __le__(self, some_set):
507+
self.le_called = True
508+
return False
509+
510+
# This first tries the bulitin rich set comparison, which doesn't know
511+
# how to handle the custom object. Upon returning NotImplemented, the
512+
# corresponding comparison on the right object is invoked.
513+
myset = {1, 2, 3}
514+
515+
myobj = TestRichSetCompare()
516+
myset < myobj
517+
self.assert_(myobj.gt_called)
518+
519+
myobj = TestRichSetCompare()
520+
myset > myobj
521+
self.assert_(myobj.lt_called)
522+
523+
myobj = TestRichSetCompare()
524+
myset <= myobj
525+
self.assert_(myobj.ge_called)
526+
527+
myobj = TestRichSetCompare()
528+
myset >= myobj
529+
self.assert_(myobj.le_called)
530+
495531
# C API test only available in a debug build
496532
if hasattr(set, "test_c_api"):
497533
def test_c_api(self):

Objects/setobject.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,12 +1607,8 @@ set_richcompare(PySetObject *v, PyObject *w, int op)
16071607
PyObject *r1, *r2;
16081608

16091609
if(!PyAnySet_Check(w)) {
1610-
if (op == Py_EQ)
1611-
Py_RETURN_FALSE;
1612-
if (op == Py_NE)
1613-
Py_RETURN_TRUE;
1614-
PyErr_SetString(PyExc_TypeError, "can only compare to a set");
1615-
return NULL;
1610+
Py_INCREF(Py_NotImplemented);
1611+
return Py_NotImplemented;
16161612
}
16171613
switch (op) {
16181614
case Py_EQ:

0 commit comments

Comments
 (0)