diff options
author | Mark Dickinson <dickinsm@gmail.com> | 2010-05-30 13:18:10 (GMT) |
---|---|---|
committer | Mark Dickinson <dickinsm@gmail.com> | 2010-05-30 13:18:10 (GMT) |
commit | 4ca7c3c089cf59d14a76f8035b360f4fbf98f9bb (patch) | |
tree | 12e13bfbc97606d0c62096d2f1e5ce536cc0d0e5 /Objects | |
parent | 4b3035d0b8f10112e2e9f348ded2bd721ad6ddb8 (diff) | |
download | cpython-4ca7c3c089cf59d14a76f8035b360f4fbf98f9bb.zip cpython-4ca7c3c089cf59d14a76f8035b360f4fbf98f9bb.tar.gz cpython-4ca7c3c089cf59d14a76f8035b360f4fbf98f9bb.tar.bz2 |
Issue #8748: Fix incorrect results from comparisons between an integer
and a complex instance. Based on a patch by Meador Inge.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/complexobject.c | 63 |
1 files changed, 54 insertions, 9 deletions
diff --git a/Objects/complexobject.c b/Objects/complexobject.c index dacafe6..677ac0e 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -783,25 +783,70 @@ complex_coerce(PyObject **pv, PyObject **pw) static PyObject * complex_richcompare(PyObject *v, PyObject *w, int op) { - Py_complex i, j; PyObject *res; + Py_complex i; + int equal; + if (op != Py_EQ && op != Py_NE) { + /* for backwards compatibility, comparisons with non-numbers return + * NotImplemented. Only comparisons with core numeric types raise + * TypeError. + */ + if (PyInt_Check(w) || PyLong_Check(w) || + PyFloat_Check(w) || PyComplex_Check(w)) { + PyErr_SetString(PyExc_TypeError, + "no ordering relation is defined " + "for complex numbers"); + return NULL; + } + goto Unimplemented; + } + + assert(PyComplex_Check(v)); TO_COMPLEX(v, i); - TO_COMPLEX(w, j); - if (op != Py_EQ && op != Py_NE) { - PyErr_SetString(PyExc_TypeError, - "no ordering relation is defined for complex numbers"); - return NULL; + if (PyInt_Check(w) || PyLong_Check(w)) { + /* Check for 0.0 imaginary part first to avoid the rich + * comparison when possible. + */ + if (i.imag == 0.0) { + PyObject *j, *sub_res; + j = PyFloat_FromDouble(i.real); + if (j == NULL) + return NULL; + + sub_res = PyObject_RichCompare(j, w, op); + Py_DECREF(j); + return sub_res; + } + else { + equal = 0; + } + } + else if (PyFloat_Check(w)) { + equal = (i.real == PyFloat_AsDouble(w) && i.imag == 0.0); + } + else if (PyComplex_Check(w)) { + Py_complex j; + + TO_COMPLEX(w, j); + equal = (i.real == j.real && i.imag == j.imag); + } + else { + goto Unimplemented; } - if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ)) - res = Py_True; + if (equal == (op == Py_EQ)) + res = Py_True; else - res = Py_False; + res = Py_False; Py_INCREF(res); return res; + + Unimplemented: + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; } static PyObject * |