voc icon indicating copy to clipboard operation
voc copied to clipboard

Look into cleaning up __xxx___ and __rxxx__ accross types

Open uranusjr opened this issue 8 years ago • 2 comments

Another thing on my own todo list…

It seems some operations in CPython are provided by rxxx, but this is not followed. So currently there are snippets like

@org.python.Method(
            __doc__ = ""
    )
    public org.python.Object __mul__(org.python.Object other) {
        if ((other instanceof org.python.types.List) ||
                (other instanceof org.python.types.Tuple) ||
                (other instanceof org.python.types.Str) ||
                (other instanceof org.python.types.ByteArray) ||
                (other instanceof org.python.types.Bytes)) {
            throw new org.python.exceptions.TypeError("can't multiply sequence by non-int of type '" + this.typeName() + "'");
        }
        return super.__mul__(other);
    }

but the correct implementation would be (taking __mul__ for example, but the same applies for all binary operations)

  1. Check whether LHO implements __mul__, fallback to Object.__mul__ if not handled. Fallback to Object.__mul__. This is done automatically by Java inheritance.
  2. In Object.__mul__, check whether RHO implements __rmul__. If it does (no AttributeError raised and does not return NotImplemented), use it.
  3. Return NotImplemented.

uranusjr avatar Sep 15 '17 07:09 uranusjr

I agree that this should be addressed, but I'm not sure if I understand the proposal. Can you point to a reference that indicates that is the correct behavior?

I thought if __mul__ returned NotImplemented, then __rmul__ would be attempted.

eliasdorneles avatar Oct 15 '17 03:10 eliasdorneles

There is an additional case at the start:

If the right operand’s type is a subclass of the left operand’s type and that subclass provides the reflected method for the operation, this method will be called before the left operand’s non-reflected method.

cflee avatar Mar 01 '18 06:03 cflee