]> granicus.if.org Git - python/commitdiff
bpo-23699: Use a macro to reduce boilerplate code in rich comparison functions (GH...
authorstratakis <cstratak@redhat.com>
Thu, 2 Nov 2017 10:32:54 +0000 (11:32 +0100)
committerNick Coghlan <ncoghlan@gmail.com>
Thu, 2 Nov 2017 10:32:54 +0000 (20:32 +1000)
16 files changed:
Doc/c-api/typeobj.rst
Include/object.h
Misc/ACKS
Misc/NEWS.d/next/C API/2017-10-19-15-27-04.bpo-23699.-noVVc.rst [new file with mode: 0644]
Modules/_datetimemodule.c
Modules/_tkinter.c
Modules/parsermodule.c
Modules/selectmodule.c
Objects/bytearrayobject.c
Objects/bytesobject.c
Objects/cellobject.c
Objects/descrobject.c
Objects/listobject.c
Objects/longobject.c
Objects/tupleobject.c
Objects/unicodeobject.c

index 0b4577f5b950a9c54a3418034743e6b09bd8c04b..3bdf45ad9b61f77a8eecb3ef800b0a6a6edef15a 100644 (file)
@@ -623,6 +623,22 @@ type objects) *must* have the :attr:`ob_size` field.
    | :const:`Py_GE` | ``>=``     |
    +----------------+------------+
 
+   The following macro is defined to ease writing rich comparison functions:
+
+   .. c:function:: PyObject *Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, int op)
+
+      Return ``Py_True`` or ``Py_False`` from the function, depending on the
+      result of a comparison.
+      VAL_A and VAL_B must be orderable by C comparison operators (for example,
+      they may be C ints or floats). The third argument specifies the requested
+      operation, as for :c:func:`PyObject_RichCompare`.
+
+      The return value's reference count is properly incremented.
+
+      On error, sets an exception and returns NULL from the function.
+
+      .. versionadded:: 3.7
+
 
 .. c:member:: Py_ssize_t PyTypeObject.tp_weaklistoffset
 
index cb57359ea230a586ea2a1248859342980d27c5ab..b7051f3f17e36c1d229d791891efbaa63abdcd68 100644 (file)
@@ -931,6 +931,25 @@ PyAPI_DATA(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */
 #define Py_GT 4
 #define Py_GE 5
 
+/*
+ * Macro for implementing rich comparisons
+ *
+ * Needs to be a macro because any C-comparable type can be used.
+ */
+#define Py_RETURN_RICHCOMPARE(val1, val2, op)                               \
+    do {                                                                    \
+        switch (op) {                                                       \
+        case Py_EQ: if ((val1) == (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE;  \
+        case Py_NE: if ((val1) != (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE;  \
+        case Py_LT: if ((val1) < (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE;   \
+        case Py_GT: if ((val1) > (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE;   \
+        case Py_LE: if ((val1) <= (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE;  \
+        case Py_GE: if ((val1) >= (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE;  \
+        default:                                                            \
+            Py_UNREACHABLE();                                               \
+        }                                                                   \
+    } while (0)
+
 #ifndef Py_LIMITED_API
 /* Maps Py_LT to Py_GT, ..., Py_GE to Py_LE.
  * Defined in object.c.
index ac7a258df1826f2899232bad574907ab9e810ec5..1bd3c047d89a00ffdea5517abeac4ea0f9298098 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1646,7 +1646,7 @@ Mike Verdone
 Jaap Vermeulen
 Nikita Vetoshkin
 Al Vezza
-Petr Victorin
+Petr Viktorin
 Jacques A. Vidrine
 John Viega
 Dino Viehland
diff --git a/Misc/NEWS.d/next/C API/2017-10-19-15-27-04.bpo-23699.-noVVc.rst b/Misc/NEWS.d/next/C API/2017-10-19-15-27-04.bpo-23699.-noVVc.rst
new file mode 100644 (file)
index 0000000..d873666
--- /dev/null
@@ -0,0 +1,2 @@
+Add Py_RETURN_RICHCOMPARE macro to reduce boilerplate code in rich
+comparison functions.
index 09b557958a02facd9d5c94de48b8a5ccbf6e7d6c..b50cddad5dd2fd6e1c692ed31d98671e8f151f29 100644 (file)
@@ -1442,22 +1442,7 @@ build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
 static PyObject *
 diff_to_bool(int diff, int op)
 {
-    PyObject *result;
-    int istrue;
-
-    switch (op) {
-        case Py_EQ: istrue = diff == 0; break;
-        case Py_NE: istrue = diff != 0; break;
-        case Py_LE: istrue = diff <= 0; break;
-        case Py_GE: istrue = diff >= 0; break;
-        case Py_LT: istrue = diff < 0; break;
-        case Py_GT: istrue = diff > 0; break;
-        default:
-            Py_UNREACHABLE();
-    }
-    result = istrue ? Py_True : Py_False;
-    Py_INCREF(result);
-    return result;
+    Py_RETURN_RICHCOMPARE(diff, 0, op);
 }
 
 /* Raises a "can't compare" TypeError and returns NULL. */
index 005214e27f75b8028254661d80ea0d4071e13a94..7123da58851dc4bda5460a3782519ac05f7ba92c 100644 (file)
@@ -864,13 +864,10 @@ PyTclObject_repr(PyTclObject *self)
     return repr;
 }
 
-#define TEST_COND(cond) ((cond) ? Py_True : Py_False)
-
 static PyObject *
 PyTclObject_richcompare(PyObject *self, PyObject *other, int op)
 {
     int result;
-    PyObject *v;
 
     /* neither argument should be NULL, unless something's gone wrong */
     if (self == NULL || other == NULL) {
@@ -880,8 +877,7 @@ PyTclObject_richcompare(PyObject *self, PyObject *other, int op)
 
     /* both arguments should be instances of PyTclObject */
     if (!PyTclObject_Check(self) || !PyTclObject_Check(other)) {
-        v = Py_NotImplemented;
-        goto finished;
+        Py_RETURN_NOTIMPLEMENTED;
     }
 
     if (self == other)
@@ -890,33 +886,7 @@ PyTclObject_richcompare(PyObject *self, PyObject *other, int op)
     else
         result = strcmp(Tcl_GetString(((PyTclObject *)self)->value),
                         Tcl_GetString(((PyTclObject *)other)->value));
-    /* Convert return value to a Boolean */
-    switch (op) {
-    case Py_EQ:
-        v = TEST_COND(result == 0);
-        break;
-    case Py_NE:
-        v = TEST_COND(result != 0);
-        break;
-    case Py_LE:
-        v = TEST_COND(result <= 0);
-        break;
-    case Py_GE:
-        v = TEST_COND(result >= 0);
-        break;
-    case Py_LT:
-        v = TEST_COND(result < 0);
-        break;
-    case Py_GT:
-        v = TEST_COND(result > 0);
-        break;
-    default:
-        PyErr_BadArgument();
-        return NULL;
-    }
-  finished:
-    Py_INCREF(v);
-    return v;
+    Py_RETURN_RICHCOMPARE(result, 0, op);
 }
 
 PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
index 929f2deb16c428655cc7f088e80bdf5fc9db7dfd..2b98be40e308db4fcc0c9d59c7dc17ad928667fc 100644 (file)
@@ -299,13 +299,10 @@ parser_compare_nodes(node *left, node *right)
  *
  */
 
-#define TEST_COND(cond) ((cond) ? Py_True : Py_False)
-
 static PyObject *
 parser_richcompare(PyObject *left, PyObject *right, int op)
 {
     int result;
-    PyObject *v;
 
     /* neither argument should be NULL, unless something's gone wrong */
     if (left == NULL || right == NULL) {
@@ -315,8 +312,7 @@ parser_richcompare(PyObject *left, PyObject *right, int op)
 
     /* both arguments should be instances of PyST_Object */
     if (!PyST_Object_Check(left) || !PyST_Object_Check(right)) {
-        v = Py_NotImplemented;
-        goto finished;
+        Py_RETURN_NOTIMPLEMENTED;
     }
 
     if (left == right)
@@ -326,33 +322,7 @@ parser_richcompare(PyObject *left, PyObject *right, int op)
         result = parser_compare_nodes(((PyST_Object *)left)->st_node,
                                       ((PyST_Object *)right)->st_node);
 
-    /* Convert return value to a Boolean */
-    switch (op) {
-      case Py_EQ:
-        v = TEST_COND(result == 0);
-        break;
-      case Py_NE:
-        v = TEST_COND(result != 0);
-        break;
-      case Py_LE:
-        v = TEST_COND(result <= 0);
-        break;
-      case Py_GE:
-        v = TEST_COND(result >= 0);
-        break;
-      case Py_LT:
-        v = TEST_COND(result < 0);
-        break;
-      case Py_GT:
-        v = TEST_COND(result > 0);
-        break;
-      default:
-        PyErr_BadArgument();
-        return NULL;
-    }
-  finished:
-    Py_INCREF(v);
-    return v;
+    Py_RETURN_RICHCOMPARE(result, 0, op);
 }
 
 /*  parser_newstobject(node* st)
index 1cde6e849c4c53f598245f6b53ce1e9ee3b46f1e..f2f5cc86cdbe5113a529ad99f895bce979fba27c 100644 (file)
@@ -1929,27 +1929,7 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
            : 0;
 #undef CMP
 
-    switch (op) {
-    case Py_EQ:
-        result = (result == 0);
-        break;
-    case Py_NE:
-        result = (result != 0);
-        break;
-    case Py_LE:
-        result = (result <= 0);
-        break;
-    case Py_GE:
-        result = (result >= 0);
-        break;
-    case Py_LT:
-        result = (result < 0);
-        break;
-    case Py_GT:
-        result = (result > 0);
-        break;
-    }
-    return PyBool_FromLong((long)result);
+    Py_RETURN_RICHCOMPARE(result, 0, op);
 }
 
 static PyTypeObject kqueue_event_Type = {
index c92cfc01fd1860784fe51b4e195b35fa47d9b02d..83c3549d50bd0734f070803bce35ac9d6ec4d6da 100644 (file)
@@ -1012,8 +1012,6 @@ bytearray_richcompare(PyObject *self, PyObject *other, int op)
 {
     Py_ssize_t self_size, other_size;
     Py_buffer self_bytes, other_bytes;
-    PyObject *res;
-    Py_ssize_t minsize;
     int cmp, rc;
 
     /* Bytes can be compared to anything that supports the (binary)
@@ -1049,38 +1047,25 @@ bytearray_richcompare(PyObject *self, PyObject *other, int op)
 
     if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
         /* Shortcut: if the lengths differ, the objects differ */
-        cmp = (op == Py_NE);
+        PyBuffer_Release(&self_bytes);
+        PyBuffer_Release(&other_bytes);
+        return PyBool_FromLong((op == Py_NE));
     }
     else {
-        minsize = self_size;
-        if (other_size < minsize)
-            minsize = other_size;
-
-        cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
+        cmp = memcmp(self_bytes.buf, other_bytes.buf,
+                     Py_MIN(self_size, other_size));
         /* In ISO C, memcmp() guarantees to use unsigned bytes! */
 
-        if (cmp == 0) {
-            if (self_size < other_size)
-                cmp = -1;
-            else if (self_size > other_size)
-                cmp = 1;
-        }
+        PyBuffer_Release(&self_bytes);
+        PyBuffer_Release(&other_bytes);
 
-        switch (op) {
-        case Py_LT: cmp = cmp <  0; break;
-        case Py_LE: cmp = cmp <= 0; break;
-        case Py_EQ: cmp = cmp == 0; break;
-        case Py_NE: cmp = cmp != 0; break;
-        case Py_GT: cmp = cmp >  0; break;
-        case Py_GE: cmp = cmp >= 0; break;
+        if (cmp != 0) {
+            Py_RETURN_RICHCOMPARE(cmp, 0, op);
         }
+
+        Py_RETURN_RICHCOMPARE(self_size, other_size, op);
     }
 
-    res = cmp ? Py_True : Py_False;
-    PyBuffer_Release(&self_bytes);
-    PyBuffer_Release(&other_bytes);
-    Py_INCREF(res);
-    return res;
 }
 
 static void
index 7ba90aa307b890d5b8eae015667aaab792e09cb5..a921d9cb8c5e98117b79401ba816aa83d42446d5 100644 (file)
@@ -1566,7 +1566,6 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
     int c;
     Py_ssize_t len_a, len_b;
     Py_ssize_t min_len;
-    PyObject *result;
     int rc;
 
     /* Make sure both arguments are strings. */
@@ -1599,7 +1598,7 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
                 }
             }
         }
-        result = Py_NotImplemented;
+        Py_RETURN_NOTIMPLEMENTED;
     }
     else if (a == b) {
         switch (op) {
@@ -1607,12 +1606,12 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
         case Py_LE:
         case Py_GE:
             /* a string is equal to itself */
-            result = Py_True;
+            Py_RETURN_TRUE;
             break;
         case Py_NE:
         case Py_LT:
         case Py_GT:
-            result = Py_False;
+            Py_RETURN_FALSE;
             break;
         default:
             PyErr_BadArgument();
@@ -1622,7 +1621,7 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
     else if (op == Py_EQ || op == Py_NE) {
         int eq = bytes_compare_eq(a, b);
         eq ^= (op == Py_NE);
-        result = eq ? Py_True : Py_False;
+        return PyBool_FromLong(eq);
     }
     else {
         len_a = Py_SIZE(a);
@@ -1635,22 +1634,10 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
         }
         else
             c = 0;
-        if (c == 0)
-            c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
-        switch (op) {
-        case Py_LT: c = c <  0; break;
-        case Py_LE: c = c <= 0; break;
-        case Py_GT: c = c >  0; break;
-        case Py_GE: c = c >= 0; break;
-        default:
-            PyErr_BadArgument();
-            return NULL;
-        }
-        result = c ? Py_True : Py_False;
+        if (c != 0)
+            Py_RETURN_RICHCOMPARE(c, 0, op);
+        Py_RETURN_RICHCOMPARE(len_a, len_b, op);
     }
-
-    Py_INCREF(result);
-    return result;
 }
 
 static Py_hash_t
index af19229c4b6a7a415eb9a99066ba6d6110b4c406..7b05e61ce46fa0c68bda9dc2370c610209636db0 100644 (file)
@@ -53,22 +53,15 @@ cell_dealloc(PyCellObject *op)
     PyObject_GC_Del(op);
 }
 
-#define TEST_COND(cond) ((cond) ? Py_True : Py_False)
-
 static PyObject *
 cell_richcompare(PyObject *a, PyObject *b, int op)
 {
-    int result;
-    PyObject *v;
-
     /* neither argument should be NULL, unless something's gone wrong */
     assert(a != NULL && b != NULL);
 
     /* both arguments should be instances of PyCellObject */
     if (!PyCell_Check(a) || !PyCell_Check(b)) {
-        v = Py_NotImplemented;
-        Py_INCREF(v);
-        return v;
+        Py_RETURN_NOTIMPLEMENTED;
     }
 
     /* compare cells by contents; empty cells come before anything else */
@@ -77,32 +70,7 @@ cell_richcompare(PyObject *a, PyObject *b, int op)
     if (a != NULL && b != NULL)
         return PyObject_RichCompare(a, b, op);
 
-    result = (b == NULL) - (a == NULL);
-    switch (op) {
-    case Py_EQ:
-        v = TEST_COND(result == 0);
-        break;
-    case Py_NE:
-        v = TEST_COND(result != 0);
-        break;
-    case Py_LE:
-        v = TEST_COND(result <= 0);
-        break;
-    case Py_GE:
-        v = TEST_COND(result >= 0);
-        break;
-    case Py_LT:
-        v = TEST_COND(result < 0);
-        break;
-    case Py_GT:
-        v = TEST_COND(result > 0);
-        break;
-    default:
-        PyErr_BadArgument();
-        return NULL;
-    }
-    Py_INCREF(v);
-    return v;
+    Py_RETURN_RICHCOMPARE(b == NULL, a == NULL, op);
 }
 
 static PyObject *
index 5dc27ef67278a41c8d2d595c2e2c86d60e0cf8bc..71d522433a2d10869e74d2f4ecd3a3ae1bc764be 100644 (file)
@@ -1035,22 +1035,16 @@ wrapper_dealloc(wrapperobject *wp)
     Py_TRASHCAN_SAFE_END(wp)
 }
 
-#define TEST_COND(cond) ((cond) ? Py_True : Py_False)
-
 static PyObject *
 wrapper_richcompare(PyObject *a, PyObject *b, int op)
 {
-    intptr_t result;
-    PyObject *v;
     PyWrapperDescrObject *a_descr, *b_descr;
 
     assert(a != NULL && b != NULL);
 
     /* both arguments should be wrapperobjects */
     if (!Wrapper_Check(a) || !Wrapper_Check(b)) {
-        v = Py_NotImplemented;
-        Py_INCREF(v);
-        return v;
+        Py_RETURN_NOTIMPLEMENTED;
     }
 
     /* compare by descriptor address; if the descriptors are the same,
@@ -1063,32 +1057,7 @@ wrapper_richcompare(PyObject *a, PyObject *b, int op)
         return PyObject_RichCompare(a, b, op);
     }
 
-    result = a_descr - b_descr;
-    switch (op) {
-    case Py_EQ:
-        v = TEST_COND(result == 0);
-        break;
-    case Py_NE:
-        v = TEST_COND(result != 0);
-        break;
-    case Py_LE:
-        v = TEST_COND(result <= 0);
-        break;
-    case Py_GE:
-        v = TEST_COND(result >= 0);
-        break;
-    case Py_LT:
-        v = TEST_COND(result < 0);
-        break;
-    case Py_GT:
-        v = TEST_COND(result > 0);
-        break;
-    default:
-        PyErr_BadArgument();
-        return NULL;
-    }
-    Py_INCREF(v);
-    return v;
+    Py_RETURN_RICHCOMPARE(a_descr, b_descr, op);
 }
 
 static Py_hash_t
index 858532252e92a7f2787018d163857dea8db33cef..7eba61e7fed1fdff998310f6501779306fb4ca3a 100644 (file)
@@ -2330,13 +2330,10 @@ list_richcompare(PyObject *v, PyObject *w, int op)
 
     if (Py_SIZE(vl) != Py_SIZE(wl) && (op == Py_EQ || op == Py_NE)) {
         /* Shortcut: if the lengths differ, the lists differ */
-        PyObject *res;
         if (op == Py_EQ)
-            res = Py_False;
+            Py_RETURN_FALSE;
         else
-            res = Py_True;
-        Py_INCREF(res);
-        return res;
+            Py_RETURN_TRUE;
     }
 
     /* Search for the first index where items are different */
@@ -2351,25 +2348,7 @@ list_richcompare(PyObject *v, PyObject *w, int op)
 
     if (i >= Py_SIZE(vl) || i >= Py_SIZE(wl)) {
         /* No more items to compare -- compare sizes */
-        Py_ssize_t vs = Py_SIZE(vl);
-        Py_ssize_t ws = Py_SIZE(wl);
-        int cmp;
-        PyObject *res;
-        switch (op) {
-        case Py_LT: cmp = vs <  ws; break;
-        case Py_LE: cmp = vs <= ws; break;
-        case Py_EQ: cmp = vs == ws; break;
-        case Py_NE: cmp = vs != ws; break;
-        case Py_GT: cmp = vs >  ws; break;
-        case Py_GE: cmp = vs >= ws; break;
-        default: return NULL; /* cannot happen */
-        }
-        if (cmp)
-            res = Py_True;
-        else
-            res = Py_False;
-        Py_INCREF(res);
-        return res;
+        Py_RETURN_RICHCOMPARE(Py_SIZE(vl), Py_SIZE(wl), op);
     }
 
     /* We have an item that differs -- shortcuts for EQ/NE */
index c71b783cc03c35a79c60c2453775eaaa9d222597..6fd4feba12afed385c0e538ef4763d25e6fb6da6 100644 (file)
@@ -2915,45 +2915,16 @@ long_compare(PyLongObject *a, PyLongObject *b)
     return sign < 0 ? -1 : sign > 0 ? 1 : 0;
 }
 
-#define TEST_COND(cond) \
-    ((cond) ? Py_True : Py_False)
-
 static PyObject *
 long_richcompare(PyObject *self, PyObject *other, int op)
 {
     int result;
-    PyObject *v;
     CHECK_BINOP(self, other);
     if (self == other)
         result = 0;
     else
         result = long_compare((PyLongObject*)self, (PyLongObject*)other);
-    /* Convert the return value to a Boolean */
-    switch (op) {
-    case Py_EQ:
-        v = TEST_COND(result == 0);
-        break;
-    case Py_NE:
-        v = TEST_COND(result != 0);
-        break;
-    case Py_LE:
-        v = TEST_COND(result <= 0);
-        break;
-    case Py_GE:
-        v = TEST_COND(result >= 0);
-        break;
-    case Py_LT:
-        v = TEST_COND(result == -1);
-        break;
-    case Py_GT:
-        v = TEST_COND(result == 1);
-        break;
-    default:
-        PyErr_BadArgument();
-        return NULL;
-    }
-    Py_INCREF(v);
-    return v;
+    Py_RETURN_RICHCOMPARE(result, 0, op);
 }
 
 static Py_hash_t
index c150af8ed1acb8dbdae9ef09e34e9046d99000ab..35decd8bb802f6721f39c4acfc03c54560a75769 100644 (file)
@@ -647,23 +647,7 @@ tuplerichcompare(PyObject *v, PyObject *w, int op)
 
     if (i >= vlen || i >= wlen) {
         /* No more items to compare -- compare sizes */
-        int cmp;
-        PyObject *res;
-        switch (op) {
-        case Py_LT: cmp = vlen <  wlen; break;
-        case Py_LE: cmp = vlen <= wlen; break;
-        case Py_EQ: cmp = vlen == wlen; break;
-        case Py_NE: cmp = vlen != wlen; break;
-        case Py_GT: cmp = vlen >  wlen; break;
-        case Py_GE: cmp = vlen >= wlen; break;
-        default: return NULL; /* cannot happen */
-        }
-        if (cmp)
-            res = Py_True;
-        else
-            res = Py_False;
-        Py_INCREF(res);
-        return res;
+        Py_RETURN_RICHCOMPARE(vlen, wlen, op);
     }
 
     /* We have an item that differs -- shortcuts for EQ/NE */
index 6533f4142b54b8329f9ccc7f05a9818fa3e0bc5d..194c5bcdcf11e21608deb51e6456913d5418db04 100644 (file)
@@ -11152,14 +11152,10 @@ _PyUnicode_EqualToASCIIId(PyObject *left, _Py_Identifier *right)
     return unicode_compare_eq(left, right_uni);
 }
 
-#define TEST_COND(cond)                         \
-    ((cond) ? Py_True : Py_False)
-
 PyObject *
 PyUnicode_RichCompare(PyObject *left, PyObject *right, int op)
 {
     int result;
-    PyObject *v;
 
     if (!PyUnicode_Check(left) || !PyUnicode_Check(right))
         Py_RETURN_NOTIMPLEMENTED;
@@ -11174,13 +11170,11 @@ PyUnicode_RichCompare(PyObject *left, PyObject *right, int op)
         case Py_LE:
         case Py_GE:
             /* a string is equal to itself */
-            v = Py_True;
-            break;
+            Py_RETURN_TRUE;
         case Py_NE:
         case Py_LT:
         case Py_GT:
-            v = Py_False;
-            break;
+            Py_RETURN_FALSE;
         default:
             PyErr_BadArgument();
             return NULL;
@@ -11189,32 +11183,12 @@ PyUnicode_RichCompare(PyObject *left, PyObject *right, int op)
     else if (op == Py_EQ || op == Py_NE) {
         result = unicode_compare_eq(left, right);
         result ^= (op == Py_NE);
-        v = TEST_COND(result);
+        return PyBool_FromLong(result);
     }
     else {
         result = unicode_compare(left, right);
-
-        /* Convert the return value to a Boolean */
-        switch (op) {
-        case Py_LE:
-            v = TEST_COND(result <= 0);
-            break;
-        case Py_GE:
-            v = TEST_COND(result >= 0);
-            break;
-        case Py_LT:
-            v = TEST_COND(result == -1);
-            break;
-        case Py_GT:
-            v = TEST_COND(result == 1);
-            break;
-        default:
-            PyErr_BadArgument();
-            return NULL;
-        }
+        Py_RETURN_RICHCOMPARE(result, 0, op);
     }
-    Py_INCREF(v);
-    return v;
 }
 
 int