Deprecated __cmp__ and total ordering

__cmp__ used to provide a convenient way to make all ordering operators work by defining a single method. For better or worse, it's gone in 3.0. To provide total ordering without __cmp__ one has to implement all of __lt__, __gt__, __le__, __ge__, __eq__ and __ne__. However, in all but a few cases it suffices only to provide a "real" implementation for e.g. __lt__ and define all the other methods in terms of it as follows: class TotalOrderMixin(object): def __lt__(self, other): raise NotImplemented # override this def __gt__(self, other): return other < self def __le__(self, other): return not (other < self) def __ge__(self, other): return not (self < other) __eq__ and __ne__ are somewhat special, although it is possible to define them in terms of __lt__ def __eq__(self, other): return not (self == other) def __ne__(self, other): return self < other or other < self it may be inefficient. So, to avoid the situation where all the projects that match http://www.google.com/codesearch?q=__cmp__+lang%3Apython have to implement their own TotalOrderMixin, perhaps one could be provided in the stdlib? Or even better, shouldn't a class grow automagic __gt__, __le__, __ge__ if __lt__ is provided, and, in a similar vein, __ne__ if __eq__ is provided?

Hello Mart, This has been discussed before. Guido was against automatically filling in these methods based I think on the fact that this may not be what you want - worth searching the archives for. See here for a class decorator that provides all rich comparison methods for classes that only implement one (e.g. __lt__): http://code.activestate.com/recipes/576529/ Michael Foord Mart Sõmermaa wrote:
__cmp__ used to provide a convenient way to make all ordering operators work by defining a single method. For better or worse, it's gone in 3.0.
To provide total ordering without __cmp__ one has to implement all of __lt__, __gt__, __le__, __ge__, __eq__ and __ne__. However, in all but a few cases it suffices only to provide a "real" implementation for e.g. __lt__ and define all the other methods in terms of it as follows:
class TotalOrderMixin(object): def __lt__(self, other): raise NotImplemented # override this
def __gt__(self, other): return other < self
def __le__(self, other): return not (other < self)
def __ge__(self, other): return not (self < other)
__eq__ and __ne__ are somewhat special, although it is possible to define them in terms of __lt__
def __eq__(self, other): return not (self == other)
def __ne__(self, other): return self < other or other < self
it may be inefficient.
So, to avoid the situation where all the projects that match http://www.google.com/codesearch?q=__cmp__+lang%3Apython have to implement their own TotalOrderMixin, perhaps one could be provided in the stdlib? Or even better, shouldn't a class grow automagic __gt__, __le__, __ge__ if __lt__ is provided, and, in a similar vein, __ne__ if __eq__ is provided? ------------------------------------------------------------------------
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/fuzzyman%40voidspace.org.u...

[Mart Sõmermaa]
To provide total ordering without __cmp__ one has to implement all of __lt__, __gt__, __le__, __ge__, __eq__ and __ne__. However, in all but a few cases it suffices only to provide a "real" implementation for e.g. __lt__ and define all the other methods in terms of it as follows:
FWIW, I'm working on a solution for the problem using class decorators. The idea is that it would scan a class and fill-in missing methods based on the ones already there. That way, any one of the four ordering relations can be provided as a starting point and we won't have to annoint one like __lt__ as the one true underlying method. When it's ready, I'll bring it to python-dev for discussion. Raymond

Raymond Hettinger wrote:
[Mart Sõmermaa]
To provide total ordering without __cmp__ one has to implement all of __lt__, __gt__, __le__, __ge__, __eq__ and __ne__. However, in all but a few cases it suffices only to provide a "real" implementation for e.g. __lt__ and define all the other methods in terms of it as follows:
FWIW, I'm working on a solution for the problem using class decorators. The idea is that it would scan a class and fill-in missing methods based on the ones already there. That way, any one of the four ordering relations can be provided as a starting point and we won't have to annoint one like __lt__ as the one true underlying method.
When it's ready, I'll bring it to python-dev for discussion.
Is there something you don't like about this one: http://code.activestate.com/recipes/576529/ Michael
Raymond _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/fuzzyman%40voidspace.org.u...

[Mart Sõmermaa]
To provide total ordering without __cmp__ one has to implement all of __lt__, __gt__, __le__, __ge__, __eq__ and __ne__. However, in all but a few cases it suffices only to provide a "real" implementation for e.g. __lt__ and define all the other methods in terms of it as follows:
[Raymond Hettinger]
FWIW, I'm working on a solution for the problem using class decorators. The idea is that it would scan a class and fill-in missing methods based on the ones already there. That way, any one of the four ordering relations can be provided as a starting point and we won't have to annoint one like __lt__ as the one true underlying method.
When it's ready, I'll bring it to python-dev for discussion.
[Michael Foord]
Is there something you don't like about this one: http://code.activestate.com/recipes/576529/
Yes, that recipe has the basic idea! I think the implementation can be cleaned-up quite a bit and it can be made as fast as hand-written code (not the setup time, but the actual introduced method). Raymond

Raymond Hettinger wrote:
[Mart Sõmermaa]
To provide total ordering without __cmp__ one has to implement all of __lt__, __gt__, __le__, __ge__, __eq__ and __ne__. However, in all but a few cases it suffices only to provide a "real" implementation for e.g. __lt__ and define all the other methods in terms of it as follows:
[Raymond Hettinger]
FWIW, I'm working on a solution for the problem using class decorators. The idea is that it would scan a class and fill-in missing methods based on the ones already there. That way, any one of the four ordering relations can be provided as a starting point and we won't have to annoint one like __lt__ as the one true underlying method.
When it's ready, I'll bring it to python-dev for discussion.
[Michael Foord]
Is there something you don't like about this one: http://code.activestate.com/recipes/576529/
Yes, that recipe has the basic idea!
It was originally written after you issued a challenge at PyCon UK last year.
I think the implementation can be cleaned-up quite a bit and it can be made as fast as hand-written code (not the setup time, but the actual introduced method).
OK I'll take it back to Christian and Menno and see what we can come up with. Michael
Raymond

On Tue, Mar 10, 2009 at 3:57 PM, Michael Foord <fuzzyman@voidspace.org.uk>wrote:
Is there something you don't like about this one: http://code.activestate.com/recipes/576529/
Yes -- it is not in the standard library. As I said, eventually all the 15,000 matches on Google Code need to update their code and copy that snippet to their util/, write tests for it etc.

Mart Sõmermaa wrote:
On Tue, Mar 10, 2009 at 3:57 PM, Michael Foord <fuzzyman@voidspace.org.uk <mailto:fuzzyman@voidspace.org.uk>> wrote:
Is there something you don't like about this one: http://code.activestate.com/recipes/576529/
Yes -- it is not in the standard library. As I said, eventually all the 15,000 matches on Google Code need to update their code and copy that snippet to their util/, write tests for it etc.
That question was in reply to Raymond who said he was working on his own version. Michael
------------------------------------------------------------------------
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/fuzzyman%40voidspace.org.u...
-- http://www.ironpythoninaction.com/ http://www.voidspace.org.uk/blog

[Michael Foord]
Is there something you don't like about this one: http://code.activestate.com/recipes/576529/
[Mart Sõmermaa ]
Yes -- it is not in the standard library. As I said, eventually all the 15,000 matches on Google Code need to update their code and copy that snippet to their util/, write tests for it etc.
FWIW, my version is http://code.activestate.com/recipes/576685/ If you want to push for inclusion in the standard library, I would support your effort. The basic idea isn't controversial, but there probably would be a lengthy discussion on what to call it (total_ordering is one possibilty) and where to put it (functools is a possibility). Raymond
participants (3)
-
Mart Sõmermaa
-
Michael Foord
-
Raymond Hettinger