Hello, Rich comparison functions of many builtin types include a block of boilerplate code with a switch on the "op" argument, like this example from tupleobject: 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; Each time it's implemented slightly differently: sometimes there are two values to compare, sometimes there's a cmp-style 0/1/-1 result to process; invalid "op" values are handled in various ways. Such code is also required in third-party extensions. I propose adding a public macro to ease this. My version takes two C-orderable values and the operation, similar to richcmpfunc: #define Py_RICHCOMPARE(val1, val2, op) ( \ ((op) == Py_EQ) ? PyBool_FromLong((val1) == (val2)) : \ ((op) == Py_NE) ? PyBool_FromLong((val1) != (val2)) : \ ((op) == Py_LT) ? PyBool_FromLong((val1) < (val2)) : \ ((op) == Py_GT) ? PyBool_FromLong((val1) > (val2)) : \ ((op) == Py_LE) ? PyBool_FromLong((val1) <= (val2)) : \ ((op) == Py_GE) ? PyBool_FromLong((val1) >= (val2)) : \ (Py_INCREF(Py_NotImplemented), Py_NotImplemented)) (As for the behavior for unknown op: for most cases the best thing to do is setting an error and returning NULL, but that doesn't fit into a macro. A surprising number of richcmpfunc's in CPython either return NULL without error (e.g. tupleobject), or fall through and return True/False arbitrarily (as in bytearrayobject). Datetime does an assert. I think Py_NotImplemented is a good value to return) I've made a patch with the macro and its use in CPython itself. Read it as examples of usage: I'm not saying that all these modules should start using it immediately (or ever, e.g. for speed reasons), and if they do, many could use some refactoring in other code paths. The patch is here: https://github.com/encukou/cpython/compare/master...richcmp Why I'm interested in this: When porting old code to Python 3, rich comparisons a major cause of added boilerplate – especially when wrapping a C library that exposes either trivially comparable types or "cmp" functions. With this macro, a typical trivial rich comparison function reduces to: static PyObject* mytype_richcmp(PyObject *obj1, PyObject *obj2, int op) { if (mytype_Check(obj1) && mytype_Check(obj2)) { return PY_RICHCOMPARE(mytype_get_data(obj1), mytype_get_data(obj2), op); } Py_RETURN_NOTIMPLEMENTED; } ... or with `PY_RICHCOMPARE(mytype_cmp(obj1, obj2), 0, op)`. (Note that even adding this to 3.5/3.6, would help in porting efforts: the macro itself is be easy to backport, but there are big benefits in having a standard name, known semantics, and official documentation.) Is this a PEP-worthy idea?