Understanding cmp in python and recursion
I'm working with some existing code that redefines equality (via a __cmp__ method) for a class. It doesn't work as expected and in trying to fix it I've come across some behavior I don't understand. If you define __cmp__ on a class that just calls the built in function cmp, then I would expect it to always hit the maximum recursion depth. However if you try to compare an instance of the class to itself it returns 0.
Here's the code:
class A: def __cmp__(self, other): return cmp(self, other) a = A() b = A() cmp(a, a) # returns 0 cmp(b, b) # returns 0 cmp(a, b) # results in RuntimeError: maximum recursion depth exceeded
The RuntimeError I understand, but I don't understand why the first two calls to cmp succeed.
And, yes I understand that as written this is a totally pointless class. The code I'm working with tries to redefine equality in certain situations and otherwise falls through to a basecase. The basecase doesn't work as implemented and so I am trying to fix it. I thought calling cmp might work and discovered this issue. I'm hoping that understanding this will help me with finding a suitable solution.
Where two names reference the same object, they are equal by definition (edit: at least as far as cmp is concerned, where "equal" really means "neither greater than nor less than").
Since the semantics of cmp require that the objects being compared have an ordering relationship (i.e. exactly one of the following is true in a cmp(x, y) call: x < y, x == y, or x > y), cmp can assume that an argument is equal to itself and skip calls to any comparison methods if the arguments are the same object.
(A lot of things in Python assume that for any object x, x == x. This sometimes causes bugs (especially with NaN floating-point values), but most of the time, it's a useful optimization. In the case of cmp, it's fine, since cmp requires x == x as a precondition to cmp(x, x).)