[Python-Dev] A macro for easier rich comparisons

Petr Viktorin encukou at gmail.com
Tue Apr 28 12:05:59 CEST 2015


On Tue, Apr 28, 2015 at 11:13 AM, Victor Stinner
<victor.stinner at gmail.com> wrote:
> Hi,
>
> 2015-04-27 16:02 GMT+02:00 Petr Viktorin <encukou at gmail.com>:
>> A macro like this would reduce boilerplate in stdlib and third-party C
>> extensions. It would ease porting C extensions to Python 3, where rich
>> comparison is mandatory.
>
> It would be nice to have a six module for C extensions. I'm quite sure
> that many projects are already full of #ifdef PYTHON3 ... #else ...
> #endif macros.

The idea actually came from my work on such a library:
http://py3c.readthedocs.org/en/latest/

>> #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;  \
>>         }                                                                   \
>>         Py_RETURN_NOTIMPLEMENTED;                                           \
>>     } while (0)
>
> I would prefer a function for that:
>
> PyObject *Py_RichCompare(long val1, long2, int op);

The original version of the macro used ternary statements. This was
shot down because a chain of comparisons would be slower than a case
statement. (See discussion on the issue.) Wouldn't a function call
also be slower?
Also, a function with long arguments won't work on unsigned long or long long.

> You should also handle invalid operator. PyUnicode_RichCompare() calls
> PyErr_BadArgument() in this case.

There are many different precedents, from ignoring this case to doing
an assert. Is PyErr_BadArgument() better than returning
NotImplemented?

> Anyway, please open an issue for this idea.

http://bugs.python.org/issue23699


More information about the Python-Dev mailing list