Search code examples
pythonclasspython-class

Reflected dunder method doesn't work for instances of the same type


Here is a small repro - class A and B are exactly the same, with the dunder method implemented for the reflected right shift operator. So, x >> y is expected to resolve to y.__rrshift__(x).

class A:
    def __init__(self, x):
        self.x = x
        
    def __rrshift__(self, other):
        return self.__class__(self.x + other.x)

class B:
    def __init__(self, x):
        self.x = x
        
    def __rrshift__(self, other):
        return self.__class__(self.x + other.x)

However, the dunder method doesn't work on instances of the same class.

A(1) >> A(2)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for >>: 'A' and 'A'

While it works for instances from different classes.

A(1) >> B(2)

<__main__.B object at 0x7f6ca8294f40>

This was pretty surprising. And seems to be common behavior across other reflected operators too (like, radd). Is there a reason this doesn't work?


Solution

  • As the doc states, it works when operands are of different type

    These functions are only called if the left operand does not support the corresponding operation and the operands are of different types


    It seems you only need __rshift__ in both classes (only in A is valid for your examples)

    def __rshift__(self, other):
        return self.__class__(self.x + other.x)