From e27dc7230845aa341d9a0bf323fa14912713cf33 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Tue, 27 Mar 2007 22:37:34 +0000 Subject: [PATCH] By default, != returns the opposite of ==, unless the latter returns NotImplemented. (Is this worth backporting to 2.6? It seems so useful...!) --- Lib/test/test_compare.py | 6 ++++++ Misc/NEWS | 3 +++ Objects/typeobject.c | 17 ++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_compare.py b/Lib/test/test_compare.py index 1d0da692097..c6608379a13 100644 --- a/Lib/test/test_compare.py +++ b/Lib/test/test_compare.py @@ -39,6 +39,12 @@ class ComparisonTest(unittest.TestCase): self.assertEqual(a == b, id(a) == id(b), 'a=%r, b=%r' % (a, b)) + def test_ne_defaults_to_not_eq(self): + a = Cmp(1) + b = Cmp(1) + self.assertTrue(a == b) + self.assertFalse(a != b) + def test_main(): test_support.run_unittest(ComparisonTest) diff --git a/Misc/NEWS b/Misc/NEWS index c2699ec53ae..4f647d2be5e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -28,6 +28,9 @@ TO DO Core and Builtins ----------------- +- By default, != returns the opposite of ==, unless the latter returns + NotImplemented. + - Patch #1680961: sys.exitfunc has been removed and replaced with a private C-level API. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e626a17f76c..be6f279466f 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2314,7 +2314,22 @@ object_richcompare(PyObject *self, PyObject *other, int op) break; case Py_NE: - res = (self != other) ? Py_True : Py_False; + /* By default, != returns the opposite of ==, + unless the latter returns NotImplemented. */ + res = PyObject_RichCompare(self, other, Py_EQ); + if (res != NULL && res != Py_NotImplemented) { + int ok = PyObject_IsTrue(res); + Py_DECREF(res); + if (ok < 0) + res = NULL; + else { + if (ok) + res = Py_False; + else + res = Py_True; + Py_INCREF(res); + } + } break; default: