diff options
-rw-r--r-- | Lib/test/test_compare.py | 6 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Objects/typeobject.c | 17 |
3 files changed, 25 insertions, 1 deletions
diff --git a/Lib/test/test_compare.py b/Lib/test/test_compare.py index 1d0da69..c660837 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) @@ -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 e626a17..be6f279 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: |