richcmpfunc semantics

  • Thread starter harold fellermann
  • Start date
H

harold fellermann

Hi all,

I want to implement rich comparision in an extension class. Problem is
I cannot
find good documentation of the richcmpfunc semantics. Given the
signature

richcmpfunc compare(PyObject *,PyObject, int);

I supposed the two objects passed are the ones to be compared.
What is the meaning of the integer argument? Does it specify the kind
of comparision operator (e.g. __eq__ or __le__), and if so, how?
What is my richcmpfunc supposed to return? 0 or 1 indicating False or
True? What has to be done, if the function is invoked for an operator
I don't want to define?

Maybe there is some good documentation available, but I cannot find it.
So, any references or help is appreciated.

Cheers,

- harold -
 
G

Greg Ewing

harold said:
richcmpfunc compare(PyObject *,PyObject, int);

I supposed the two objects passed are the ones to be compared.
Yes.

What is the meaning of the integer argument? Does it specify the kind
of comparision operator (e.g. __eq__ or __le__), and if so, how?


< 0

<= 1

== 2

!= 3
> 4
>= 5

What is my richcmpfunc supposed to return? 0 or 1 indicating False or
True?

In the usual case, yes, although it can return any
Python object. Rich comparison doesn't impose any
semantics on the operations -- this is one of the
reasons for its existence.
What has to be done, if the function is invoked for an operator
I don't want to define?

Return Py_NotImplemented. (Note that's return, *not* raise.)
Maybe there is some good documentation available, but I cannot find it.

I found most of this out by reading the source, I think.
 
H

harold fellermann

Thank you Greg,

I figured most of it out in the meantime, myself. I only differ
from you in one point.
Return Py_NotImplemented. (Note that's return, *not* raise.)

I used

PyErr_BadArgument();
return NULL;

instead. What is the difference between the two and which one
is to prefer. Also, do you need to increment the reference count
of Py_NotImeplemented before returning it?

Thanks,

- harold -
 
D

David M. Cooke

harold fellermann said:
Thank you Greg,

I figured most of it out in the meantime, myself. I only differ
from you in one point.


I used

PyErr_BadArgument();
return NULL;

instead. What is the difference between the two and which one
is to prefer.

If you do it your way you're a bad neighbour: If your object is the
first one (left-hand side) of the operator, it will prevent the other
object from handling the case if it can. This is the same advice as
for all of the other operators (__add__, etc.)

Consider the pure-python version:

class A:
def __init__(self, what_to_do='return'):
self.what_to_do = what_to_do
def __eq__(self, other):
print 'A.__eq__'
if self.what_to_do == 'return':
return NotImplemented
else:
raise Exception

class B:
def __eq__(self, other):
print 'B.__eq__'
return True
A.__eq__
B.__eq__
True B.__eq__
True
A.__eq__
A.__eq__
A.__eq__
A.__eq__
True

So the B class handles the case where A doesn't know what to do. Also
note the last case, where Python falls back on id() comparisions to
determine equality.

Now, compare with this:
A.__eq__
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "x.py", line 9, in __eq__
raise Exception
Exception
B.__eq__
True
A.__eq__
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "x.py", line 9, in __eq__
raise Exception
Exception

So now comparing A and B objects can fail. If you *know* A and B
objects can't be compared for equality, it'd be ok to raise a
TypeError, but that should be after a type test.
Also, do you need to increment the reference count
of Py_NotImeplemented before returning it?

Yes; it's a singleton like Py_None.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,234
Messages
2,571,178
Members
47,811
Latest member
Adisty

Latest Threads

Top