Re: richcmpfunc semantics
harold fellermann <[EMAIL PROTECTED]> writes: > Thank you Greg, > > I figured most of it out in the meantime, myself. I only differ > from you in one point. > >>> 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.) > > 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 = A('return') >>> b = B() >>> a == b A.__eq__ B.__eq__ True >>> b == a B.__eq__ True >>> a == a 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 = A('raise') >>> b = B() >>> a == b A.__eq__ Traceback (most recent call last): File "", line 1, in ? File "x.py", line 9, in __eq__ raise Exception Exception >>> b == a B.__eq__ True >>> a == a A.__eq__ Traceback (most recent call last): File "", 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. -- |>|\/|< /--\ |David M. Cooke |cookedm(at)physics(dot)mcmaster(dot)ca -- http://mail.python.org/mailman/listinfo/python-list
Re: richcmpfunc semantics
Thank you Greg, I figured most of it out in the meantime, myself. I only differ from you in one point. 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.) 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 - -- I like pigs. Dogs look up to us. Cats look down to us. Pigs treat us as equal. -- Winston Churchill -- http://mail.python.org/mailman/listinfo/python-list
Re: richcmpfunc semantics
harold fellermann wrote: 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. -- Greg Ewing, Computer Science Dept, University of Canterbury, Christchurch, New Zealand http://www.cosc.canterbury.ac.nz/~greg -- http://mail.python.org/mailman/listinfo/python-list
richcmpfunc semantics
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 - -- "Scientist are very good in answering the questions they choose to answer." -- Richard Alley -- http://mail.python.org/mailman/listinfo/python-list