Message3398

Author leosoto
Recipients fwierzbicki, leosoto, pjenvey
Date 2008-08-04.22:53:05
SpamBayes Score 4.8106056e-05
Marked as misclassified No
Message-id <1217890386.91.0.648088928178.issue1031@psf.upfronthosting.co.za>
In-reply-to
Content
For completeness, I've followed the __cmp__ code path on Jython and
found that it has roughly the same structure as CPython, ie:

 - First, rich comparison is tried (on PyObject#_cmp itself)
 - Then, 3-way comparison (on PyObject#_cmp_unsafe)
 - Finally, the old "default" comparison (PyObject#_default_cmp)

Where the main difference being that we start directly by rich
comparison functions, instead of the old 3-way comparison for same
types. This means that the following gives different results on CPython
and Jython:

>>> class A(object):
...   def __eq__(self, other): return True
...   def __cmp__(self, other): return 1
... 
>>> cmp(A(), A())

CPython gives 1, while Jython gives 0. Interestingly, Jython is
following http://docs.python.org/ref/customization.html closely here.

Now, inside rich comparison we don't do the subtype check (first step of
this particular recipe on CPython), and here we have another subtle
difference:

>>> 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())

Which outputs 1 on CPython and -1 on Jython.

On the 3-way comparison step (PyObject#_cmp_unsafe -- no idea why the
"unsafe" name), we don't check first for old-style instances, so this is
also different:

class A(object):
    def __cmp__(self, other): return 1

class B:
    def __cmp__(self, other): return 1

print cmp(A(), B())

[CPython: -1, Jython: 1]

Finally, and also on PyObject#_cmp_unsafe, we don't try to coerce the
arguments. This must be fixed ASAP, as it is making test_coercion fail
on the asm branch. I don't see yet how we are going to mimic CPython
here, because we can't easily check that two PyObjects have the same
__cmp__ implementation. 

Maybe I just need to understand why CPython puts that restriction
instead of trying coerced_v.__cmp__(coerced_w) and then
-coerced_w.__cmp__(coerced_v) if the first attempt doesn't work.
History
Date User Action Args
2008-08-04 22:53:06leosotosetmessageid: <1217890386.91.0.648088928178.issue1031@psf.upfronthosting.co.za>
2008-08-04 22:53:06leosotosetrecipients: + leosoto, fwierzbicki, pjenvey
2008-08-04 22:53:06leosotolinkissue1031 messages
2008-08-04 22:53:06leosotocreate