From eee0beef88d135640871050b40844272a3aee790 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Tue, 15 Sep 2015 17:20:18 -0400 Subject: [PATCH 1/2] Ensure that we don't overlook errors in first PyObject_RichCompareBool call. Python 3.5 turns such cases into SystemErrors. See: https://bugs.python.org/issue23571 Fixes #15. --- BTrees/_compat.h | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/BTrees/_compat.h b/BTrees/_compat.h index e004d54..19dd377 100644 --- a/BTrees/_compat.h +++ b/BTrees/_compat.h @@ -27,9 +27,25 @@ #define TEXT_FROM_STRING PyUnicode_FromString #define TEXT_FORMAT PyUnicode_Format -#define COMPARE(lhs, rhs) \ - PyObject_RichCompareBool((lhs), (rhs), Py_LT) > 0 ? -1 : \ - (PyObject_RichCompareBool((lhs), (rhs), Py_EQ) > 0 ? 0 : 1) +/* Emulate Python2's __cmp__, wrapping PyObject_RichCompareBool(), + * Return -2/-3 for errors, -1 for lhsrhs. + */ +static inline +int __compare(PyObject *lhs, PyObject *rhs) { + int less, equal; + + less = PyObject_RichCompareBool(lhs, rhs, Py_LT); + if ( less == -1 ) { + return -2; + } + equal = PyObject_RichCompareBool(lhs, rhs, Py_EQ); + if ( equal == -1 ) { + return -3; + } + return less ? -1 : (equal ? 0 : 1); +} + +#define COMPARE(lhs, rhs) __compare((lhs), (rhs)) #else From ff4c3309fe471f2b9bdd642b8f7d1c2fe0f5e458 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Sun, 20 Sep 2015 11:07:10 -0400 Subject: [PATCH 2/2] Avoid unnecessary comparison for 'Py_EQ' if 'Py_LT' returned True. --- BTrees/_compat.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/BTrees/_compat.h b/BTrees/_compat.h index 19dd377..ece2bf9 100644 --- a/BTrees/_compat.h +++ b/BTrees/_compat.h @@ -38,11 +38,14 @@ int __compare(PyObject *lhs, PyObject *rhs) { if ( less == -1 ) { return -2; } + if (less) { + return -1; + } equal = PyObject_RichCompareBool(lhs, rhs, Py_EQ); if ( equal == -1 ) { return -3; } - return less ? -1 : (equal ? 0 : 1); + return equal ? 0 : 1; } #define COMPARE(lhs, rhs) __compare((lhs), (rhs))