All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.l10n.py.rules.python.S5712.html Maven / Gradle / Ivy

The newest version!

This rule raises an issue when a special method raises a NotImplementedError instead of returning NotImplemented.

Why is this an issue?

In Python, special methods corresponding to numeric operators and rich comparison operators should return NotImplemented when the operation is not supported.

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). If these special methods were to raise NotImplementedError, the callers would not catch the exception and the reverse operation would not be called.

Below is the list of special methods this rule applies to:

  • __lt__(self, other)
  • __le__(self, other)
  • __eq__(self, other)
  • __ne__(self, other)
  • __gt__(self, other)
  • __ge__(self, other)
  • __add__(self, other)
  • __sub__(self, other)
  • __mul__(self, other)
  • __matmul__(self, other)
  • __truediv__(self, other)
  • __floordiv__(self, other)
  • __mod__(self, other)
  • __divmod__(self, other)
  • __pow__(self, other[, modulo])
  • __lshift__(self, other)
  • __rshift__(self, other)
  • __and__(self, other)
  • __xor__(self, other)
  • __or__(self, other)
  • __radd__(self, other)
  • __rsub__(self, other)
  • __rmul__(self, other)
  • __rmatmul__(self, other)
  • __rtruediv__(self, other)
  • __rfloordiv__(self, other)
  • __rmod__(self, other)
  • __rdivmod__(self, other)
  • __rpow__(self, other[, modulo])
  • __rlshift__(self, other)
  • __rrshift__(self, other)
  • __rand__(self, other)
  • __rxor__(self, other)
  • __ror__(self, other)
  • __iadd__(self, other)
  • __isub__(self, other)
  • __imul__(self, other)
  • __imatmul__(self, other)
  • __itruediv__(self, other)
  • __ifloordiv__(self, other)
  • __imod__(self, other)
  • __ipow__(self, other[, modulo])
  • __ilshift__(self, other)
  • __irshift__(self, other)
  • __iand__(self, other)
  • __ixor__(self, other)
  • __ior__(self, other)
  • __length_hint__(self)

How to fix it

Make sure special methods return NotImplemented instead of raising a NotImplementedError.

Code examples

Noncompliant code example

class MyClass:
    def __add__(self, other):
        raise NotImplementedError()  # Noncompliant: the exception will be propagated
    def __radd__(self, other):
        raise NotImplementedError()  # Noncompliant: the exception will be propagated

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

Pitfalls

The __length_hint__ special method also requires to return a NotImplemented. Its behavior differs from the other methods, because when it returns NotImplemented, a default value will be returned instead. See PEP 424 for more information.

Resources

Documentation

Standards





© 2015 - 2025 Weber Informatics LLC | Privacy Policy