summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2010-05-21 14:55:26 (GMT)
committerMark Dickinson <dickinsm@gmail.com>2010-05-21 14:55:26 (GMT)
commitcc6a982de8b9030a04d85f69a29772bf6c3f442f (patch)
tree29cf0726c7e791329c7a540b7f4847956c50c1e9 /Objects
parentf0feec2cb684681139ad81acf4a6a541b57a6274 (diff)
downloadcpython-cc6a982de8b9030a04d85f69a29772bf6c3f442f.zip
cpython-cc6a982de8b9030a04d85f69a29772bf6c3f442f.tar.gz
cpython-cc6a982de8b9030a04d85f69a29772bf6c3f442f.tar.bz2
Issue #8748: Fix two issues with comparisons between complex and integer
objects. (1) The comparison could incorrectly return True in some cases (2**53+1 == complex(2**53) == 2**53), breaking transivity of equality. (2) The comparison raised an OverflowError for large integers, leading to unpredictable exceptions when combining integers and complex objects in sets or dicts. Patch by Meador Inge.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/complexobject.c52
1 files changed, 44 insertions, 8 deletions
diff --git a/Objects/complexobject.c b/Objects/complexobject.c
index ec26e0a..9e1e217 100644
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -620,22 +620,58 @@ static PyObject *
complex_richcompare(PyObject *v, PyObject *w, int op)
{
PyObject *res;
- Py_complex i, j;
- TO_COMPLEX(v, i);
- TO_COMPLEX(w, j);
+ Py_complex i;
+ int equal;
if (op != Py_EQ && op != Py_NE) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
+ goto Unimplemented;
}
- if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ))
- res = Py_True;
+ assert(PyComplex_Check(v));
+ TO_COMPLEX(v, i);
+
+ if (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 (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 *