diff options
author | Guido van Rossum <guido@python.org> | 2001-09-18 20:38:53 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-09-18 20:38:53 (GMT) |
commit | ab3b0343b89b4683148dadaf89728ee1198ebee5 (patch) | |
tree | ce2bc61bcef280a23bbc326fd7ec755a72bf1baa /Objects/object.c | |
parent | eb9490526508dc643c2329771f95a925e5412049 (diff) | |
download | cpython-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.c | 16 |
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) |