[Python-ideas] A macro for easier rich comparisons

Petr Viktorin encukou at gmail.com
Fri Mar 20 15:24:04 CET 2015


On Wed, Mar 18, 2015 at 2:48 PM, Petr Viktorin <encukou at gmail.com> wrote:
> On Wed, Mar 18, 2015 at 12:01 PM, M.-A. Lemburg <mal at egenix.com> wrote:
>> On 18.03.2015 11:53, Petr Viktorin wrote:
>>> ...
>>> 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)
>>> ...
>>> Is this a PEP-worthy idea?
>>
>> This is a great idea, no need for a PEP :-) Please submit the patch on
>> the bug tracker and also include a patch for the C API documentation.
>
> Issue with patches is here: http://bugs.python.org/issue23699

Notes from the patch review: it is not so clear-cut after all.

A sequence of comparisons is less efficient than a switch statement.
Same with PyBool_FromLong vs. Py_RETURN_*
Also, it might be too complex for a macro.
These points could be solved by making it a function instead.

Another issue raised is that the use cases are too limited limited for
this to be a part of the Python API.
I don't agree with that; I think boilerplate-reducing features are
even if their usage is limited (see Py_RETURN_NOTIMPLEMENTED or
PyModule_AddIntConstant).


More information about the Python-ideas mailing list