[Python-3000] Need closure on __cmp__ removal

Mark Summerfield mark at qtrac.eu
Wed Jan 9 09:04:50 CET 2008

On 2008-01-09, Christian Heimes wrote:
> Guido van Rossum wrote:
> > That's a different issue altogether (and your wish is not likely going
> > to be granted unless you write a PEP).
> You could write and implement a PEP about exposing the tp_richcompare
> slot to Python code.
> import sys
> class Example:
>     def __richcmp__(self, other: object, op: int) -> bool:
>         if op == sys.CMP_EQ:
>             return self.value == other.value
>         ...

I'm using this as a class decorator that fills in "missing" comparisons:

def complete_comparisons(cls):
    class CompleteComparisonsError(Exception): pass

    if hasattr(cls.__lt__, "__objclass__"): # i.e. < inherited from object
        raise CompleteComparisonsError("{0} must define < and "
                "ideally ==".format(cls.__name__))
    if hasattr(cls.__eq__, "__objclass__"): # i.e. == inherited from object
        cls.__eq__ = lambda self, other: not (
                cls.__lt__(self, other) or cls.__lt__(other, self))
    cls.__ne__ = lambda self, other: not cls.__eq__(self, other)
    cls.__gt__ = lambda self, other: cls.__lt__(other, self)
    cls.__le__ = lambda self, other: (cls.__lt__(self, other) or
                                      cls.__eq__(self, other))
    cls.__ge__ = lambda self, other: (cls.__lt__(other, self) or
                                      cls.__eq__(self, other))
    return cls

The reason for the ugly hasattr() calls is that object itself defines
the comparison operators (in Python 3.0a2).

Mark Summerfield, Qtrac Ltd., www.qtrac.eu

More information about the Python-3000 mailing list