Given that in Python 3.0 __cmp__ is going away, I'm not sure how much it all matters -- but if you care, as long as it's supported at all, you might as well strive for the most compatibility with 2.5...
On Tue, Aug 5, 2008 at 1:43 PM, Leo Soto M. <[EMAIL PROTECTED]> wrote: > Hi Python developers! > > First, a quick introduction: My name is Leonardo Soto, I'm a GSoC > 2008 student working under PSF and the Jython project, and a Jython > commiter since one month ago. > > As part of what I did on this GSoC, I've improved Jython's __cmp__ a > bit. That made me go to look at CPython sources (v2.5.2) to read the > implementation of cmp(a,b). > > Aside from what I've already fixed on Jython, I've found four > differences between Jython and CPython cmp(a, b): > > (1). CPython's cmp() uses a.__cmp__(b) before rich-cmp methods if the > types of the two arguments are the same. > > (2). When using rich-cmp methods, CPython first check if the second > type is a subtype of the first, and starts trying with the second > method instead of the first. [i.e, the process starts by b.__gt__(a) > instead of a.__lt__(b) if type(b) != type(a) and issubclass(b, a)] > > (3). Similar to above, if the second argument to cmp(a, b) is a > old-style instance, and the first isn't, b.__cmp__(a) is used instead > of a.__cmp__(b). > > (4). CPython tries coercion as part of the three way comparison. But > doesn't do it exactly as advertised on > <http://docs.python.org/ref/coercion-rules.html>: it does coercion > *after* trying a.__cmp__(b), while the docs says *before*. And it only > uses the coerced values if both values have the same tp_compare > function. I fail to see why, and this is not mentioned on the docs > either. > > [The examples that show this behaviors are at the end of this mail.] > > Now, my questions: > > - Are (1), (2) and (3) intentional features? Frankly, Jython being > different on (1) and (3) isn't a big deal, but I'd like to match > CPython as much as possible (and reasonable). Point (2) is a more > interesting, because it seems to follow what > <http://docs.python.org/ref/coercion-rules.html> says for binary ops: > > "Exception to the previous item: if the left operand is an instance of > a built-in type or a new-style class, and the right operand is an > instance of a proper subclass of that type or class and overrides the > base's __rop__() method, the right operand's __rop__() method is tried > before the left operand's __op__() method." > > But I haven't found any documentation telling that it applies to > rich-cmp methods too. Interestingly, it *doesn't* apply to __cmp__ on > CPython 2.5.2. > > BTW, PyPy also fails to follow CPython on points (2) and (3), so it is > not just me failing to found the appropriate docs ;-) > > - What's the idea behind the current implemention of __cmp__ and > coercion, as described on (4)? I've to implement this feauture on > Jython, but checking that two Java instances have the same __cmp__ > method is not that easy as in C. And more important: it could be > wrong, depending on what is the idea behind the current CPython > implementation. > > Finally, here are the examples of the behaviors outlined at the start > of this mail. > > (1): > >>>> class A(object): > ... def __eq__(self, other): return True > ... def __cmp__(self, other): return 1 > ... >>>> cmp(A(), A()) > 1 > > (2): > >>>> class A(object): > ... def __lt__(self, other): return True > ... def __gt__(self, other): return False > ... def __eq__(self, other): return False > ... >>>> class B(A): pass > ... >>>> cmp(A(), B()) > 1 > > (3): > >>>> class A(object): > ... def __cmp__(self, other): return 1 > ... >>>> class B: > ... def __cmp__(self, other): return 1 > ... >>>> cmp(A(), B()) > -1 > > (4): > >>>> class A(object): > ... def __coerce__(self, other): return 0, 0 > ... def __cmp__(self, other): return -1 > ... >>>> cmp(A(), A()) > -1 > > Regards, > -- > Leo Soto M. > http://blog.leosoto.com > _______________________________________________ > Python-Dev mailing list > Python-Dev@python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: > http://mail.python.org/mailman/options/python-dev/guido%40python.org > -- --Guido van Rossum (home page: http://www.python.org/~guido/) _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com