The issue is that __cmp__ wasn't "only one". For one thing, you generally want equality independent of ordering, so defining an explicit __eq__ that just handles equality is a decent idea. Otherwise either you define both cmp and eq, or you have your cmp including stuff like isinstance checks, in some cases, and having to decide if your custom class is more, or less, than a string (as masklinn notes below). Note: there's literally only bad answers here. Does cmp raise an exception? Yikes. Is MyCustomObject less than "hello world", or more, or does it depend on the internal state of MyCustomObject? Yikes, why do I have to choose? MyCustomObject isn't like "hello world".
So you want eq, seperate from cmp. Then you still need a way to define ordering, so either write them all for weird cases, or just pick one and have total_ordering do the legwork.
So why not just define `__eq__` and `__cmp__`. It just seems to make so much more sense... and only `__eq__` only if you need it different from `__cmp__ == 0`.
Because requiring you to define eq is more correct. Equality and ordering are different concepts. If they wanted to keep cmp, the only correct choice would be to require eq if you define cmp.
This again goes back to what masklinn said: a total ordering across all objects in python is a misfeature. The idea that `object() < 13 < "hello world" < 3+2j < [(frozenset(), frozenset())] < {type: int}` should evaluate to anything but a TypeError is horrifying!
And once you make that decision, if an object implements cmp, it must implement eq (because the safe thing should be the default, and allowing people to implement cmp in isolation lets them shoot themselves in the foot). And at that point, cmp is more work to write than le or gt, so instead just implement eq, and then if you want it, le or gt + total_ordering, or if you need weird things implement each method individually.
In practice, I've also found it much easier to reason about eq or le than cmp. People like to be tricky with cmp, and even when they don't, returning -1 or 1 is less explicit than just returning True or False.
> The idea that `object() < 13 < "hello world" < 3+2j < [(frozenset(), frozenset())] < {type: int}` should evaluate to anything but a TypeError is horrifying!
So you want eq, seperate from cmp. Then you still need a way to define ordering, so either write them all for weird cases, or just pick one and have total_ordering do the legwork.