Skip to content

Commit d94a65a

Browse files
bpo-25732: Make functools.total_ordering implementing __ne__. (#3748)
Patch by Raymond Hettinger.
1 parent 5f5da72 commit d94a65a

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed

Lib/functools.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,23 +55,28 @@ def total_ordering(cls):
5555
convert = {
5656
'__lt__': [('__gt__', lambda self, other: not (self < other or self == other)),
5757
('__le__', lambda self, other: self < other or self == other),
58+
('__ne__', lambda self, other: not self == other),
5859
('__ge__', lambda self, other: not self < other)],
5960
'__le__': [('__ge__', lambda self, other: not self <= other or self == other),
6061
('__lt__', lambda self, other: self <= other and not self == other),
62+
('__ne__', lambda self, other: not self == other),
6163
('__gt__', lambda self, other: not self <= other)],
6264
'__gt__': [('__lt__', lambda self, other: not (self > other or self == other)),
6365
('__ge__', lambda self, other: self > other or self == other),
66+
('__ne__', lambda self, other: not self == other),
6467
('__le__', lambda self, other: not self > other)],
6568
'__ge__': [('__le__', lambda self, other: (not self >= other) or self == other),
6669
('__gt__', lambda self, other: self >= other and not self == other),
70+
('__ne__', lambda self, other: not self == other),
6771
('__lt__', lambda self, other: not self >= other)]
6872
}
69-
roots = set(dir(cls)) & set(convert)
73+
defined_methods = set(dir(cls))
74+
roots = defined_methods & set(convert)
7075
if not roots:
7176
raise ValueError('must define at least one ordering operation: < > <= >=')
7277
root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__
7378
for opname, opfunc in convert[root]:
74-
if opname not in roots:
79+
if opname not in defined_methods:
7580
opfunc.__name__ = opname
7681
opfunc.__doc__ = getattr(int, opname).__doc__
7782
setattr(cls, opname, opfunc)

Lib/test/test_functools.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,59 @@ def __lt__(self, other):
600600
with self.assertRaises(TypeError):
601601
TestTO(8) <= ()
602602

603+
def test_bug_25732(self):
604+
@functools.total_ordering
605+
class A:
606+
def __init__(self, value):
607+
self.value = value
608+
def __gt__(self, other):
609+
return self.value > other.value
610+
def __eq__(self, other):
611+
return self.value == other.value
612+
self.assertTrue(A(1) != A(2))
613+
self.assertFalse(A(1) != A(1))
614+
615+
@functools.total_ordering
616+
class A(object):
617+
def __init__(self, value):
618+
self.value = value
619+
def __gt__(self, other):
620+
return self.value > other.value
621+
def __eq__(self, other):
622+
return self.value == other.value
623+
self.assertTrue(A(1) != A(2))
624+
self.assertFalse(A(1) != A(1))
625+
626+
@functools.total_ordering
627+
class A:
628+
def __init__(self, value):
629+
self.value = value
630+
def __gt__(self, other):
631+
return self.value > other.value
632+
def __eq__(self, other):
633+
return self.value == other.value
634+
def __ne__(self, other):
635+
raise RuntimeError(self, other)
636+
with self.assertRaises(RuntimeError):
637+
A(1) != A(2)
638+
with self.assertRaises(RuntimeError):
639+
A(1) != A(1)
640+
641+
@functools.total_ordering
642+
class A(object):
643+
def __init__(self, value):
644+
self.value = value
645+
def __gt__(self, other):
646+
return self.value > other.value
647+
def __eq__(self, other):
648+
return self.value == other.value
649+
def __ne__(self, other):
650+
raise RuntimeError(self, other)
651+
with self.assertRaises(RuntimeError):
652+
A(1) != A(2)
653+
with self.assertRaises(RuntimeError):
654+
A(1) != A(1)
655+
603656
def test_main(verbose=None):
604657
test_classes = (
605658
TestPartial,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
`functools.total_ordering()` now implements the `__ne__` method.

0 commit comments

Comments
 (0)