In Python, special methods corresponding to numeric operators, rich comparison operators and the __length_hint__ method should return NotImplemented when the operation is not supported. These methods should not raise NotImplementedError as callers don't expect it and won't catch this exception.

For example A + B is equivalent to calling A.__add__(B). If this binary operation is not supported by class A, A.__add__(B) should return NotImplemented. The interpreter will then try the reverse operation, i.e. B.__radd__(A). This enables adding new operations by changing only one class instead of two.

This rule raises an issue when one of the following methods raises NotImplementedError instead of returning NotImplemented:

Noncompliant Code Example

class MyClass:
    def __add__(self, other):
        raise NotImplementedError()  # Noncompliant
    def __radd__(self, other):
        raise NotImplementedError()  # Noncompliant

class MyOtherClass:
    def __add__(self, other):
        return 42
    def __radd__(self, other):
        return 42

MyClass() + MyOtherClass()  # This will raise NotImplementedError

Compliant Solution

class MyClass:
    def __add__(self, other):
        return NotImplemented
    def __radd__(self, other):
        return NotImplemented

class MyOtherClass:
    def __add__(self, other):
        return 42
    def __radd__(self, other):
        return 42

MyClass() + MyOtherClass()  # This returns 42

See