This rule raises an issue when a class defines one or more rich comparison methods (__lt__, __le__, __gt__,
__ge__) without using the functools.total_ordering decorator or defining all of them.
Python classes can implement rich comparison methods to enable sorting and comparison operations. These methods include:
__lt__ for less than (<)__le__ for less than or equal to (<=)__gt__ for greater than (>)__ge__ for greater than or equal to (>=)__eq__ for equality (==)__ne__ for inequality (!=)When you define only some of these methods, Python cannot automatically infer the missing ones. This leads to inconsistent behavior:
TypeError exceptionsa < b being true implying b > a is also true, may behave
unexpectedlyPython provides the functools.total_ordering decorator specifically to solve this problem. It allows you to define just
__eq__ and one other comparison method, and it automatically generates the rest. This ensures consistent and correct comparison behavior
across all operations.
Incomplete comparison method implementations can cause several problems:
sorted() or list methods like sort() may raise exceptions
or produce incorrect orderingWhile this typically will not cause security vulnerabilities, it can lead to application logic errors that are difficult to diagnose and debug.
Either use the @functools.total_ordering decorator and define __eq__ and one ordering method, typically
__lt__, or define all four ordering methods (__lt__, __le__, __gt__, __ge__)
explicitly.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __lt__(self, other): # Noncompliant
return self.age < other.age
from functools import total_ordering
@total_ordering
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
return self.age == other.age
def __lt__(self, other):
return self.age < other.age
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __lt__(self, other): # Noncompliant
return self.x < other.x
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __lt__(self, other):
return self.x < other.x
def __le__(self, other):
return self.x <= other.x
def __gt__(self, other):
return self.x > other.x
def __ge__(self, other):
return self.x >= other.x
The @functools.total_ordering decorator automatically generates all missing comparison methods from the ones you define. This ensures
consistent and correct comparison behavior across all operations.
functools.total_ordering