[Python-3000] Need closure on __cmp__ removal

Guido van Rossum guido at python.org
Wed Jan 9 20:08:29 CET 2008

On Jan 9, 2008 12:04 AM, Mark Summerfield <mark at qtrac.eu> wrote:
> 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).

That's due to object's implementation of __eq__ and __ne__; this is
done by having a tp_richcompare slot and then the wrapper generator
adds wrappers for all six operators to the class dict. This is not
easy to fix.

--Guido van Rossum (home page: http://www.python.org/~guido/)

More information about the Python-3000 mailing list