summaryrefslogtreecommitdiffstats
path: root/Objects/object.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2001-09-18 20:38:53 (GMT)
committerGuido van Rossum <guido@python.org>2001-09-18 20:38:53 (GMT)
commitab3b0343b89b4683148dadaf89728ee1198ebee5 (patch)
treece2bc61bcef280a23bbc326fd7ec755a72bf1baa /Objects/object.c
parenteb9490526508dc643c2329771f95a925e5412049 (diff)
downloadcpython-ab3b0343b89b4683148dadaf89728ee1198ebee5.zip
cpython-ab3b0343b89b4683148dadaf89728ee1198ebee5.tar.gz
cpython-ab3b0343b89b4683148dadaf89728ee1198ebee5.tar.bz2
Hopefully fix 3-way comparisons. This unfortunately adds yet another
hack, and it's even more disgusting than a PyInstance_Check() call. If the tp_compare slot is the slot used for overrides in Python, it's always called. Add some tests that show what should work too.
Diffstat (limited to 'Objects/object.c')
-rw-r--r--Objects/object.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/Objects/object.c b/Objects/object.c
index c56c3be..668bd4f 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -455,11 +455,25 @@ try_3way_compare(PyObject *v, PyObject *w)
/* Comparisons involving instances are given to instance_compare,
which has the same return conventions as this function. */
+ f = v->ob_type->tp_compare;
if (PyInstance_Check(v))
- return (*v->ob_type->tp_compare)(v, w);
+ return (*f)(v, w);
if (PyInstance_Check(w))
return (*w->ob_type->tp_compare)(v, w);
+ /* If both have the same (non-NULL) tp_compare, use it. */
+ if (f != NULL && f == w->ob_type->tp_compare) {
+ c = (*f)(v, w);
+ if (c < 0 && PyErr_Occurred())
+ return -1;
+ return c < 0 ? -1 : c > 0 ? 1 : 0;
+ }
+
+ /* If either tp_compare is _PyObject_SlotCompare, that's safe. */
+ if (f == _PyObject_SlotCompare ||
+ w->ob_type->tp_compare == _PyObject_SlotCompare)
+ return _PyObject_SlotCompare(v, w);
+
/* Try coercion; if it fails, give up */
c = PyNumber_CoerceEx(&v, &w);
if (c < 0)