[Python-Dev] Rich Comparisons technical prerelease

Guido van Rossum guido@python.org
Tue, 16 Jan 2001 23:22:54 -0500

I've got a working version of the rich comparisons ready for preview.

The patch is here:


It's also referenced at sourceforge:


Here's a summary:

- The comparison operators support "rich comparison overloading" (PEP
  207).  C extension types can provide a rich comparison function in
  the new tp_richcompare slot in the type object.  The cmp() function
  and the C function PyObject_Compare() first try the new rich
  comparison operators before trying the old 3-way comparison.  There
  is also a new C API PyObject_RichCompare() (which also falls back on
  the old 3-way comparison, but does not constrain the outcome of the
  rich comparison to a Boolean result).

  The rich comparison function takes two objects (at least one of
  which is guaranteed to have the type that provided the function) and
  an integer indicating the opcode, which can be Py_LT, Py_LE, Py_EQ,
  Py_NE, Py_GT, Py_GE (for <, <=, ==, !=, >, >=), and returns a Python
  object, which may be NotImplemented (in which case the tp_compare
  slot function is used as a fallback, if defined).

  Classes can overload individual comparison operators by defining one
  or more of the methods__lt__, __le__, __eq__, __ne__, __gt__,
  __ge__.  There are no explicit "reversed argument" versions of
  these; instead, __lt__ and __gt__ are each other's reverse, likewise
  for__le__ and __ge__; __eq__ and __ne__ are their own reverse
  (similar at the C level).  No other implications are made; in
  particular, Python does not assume that == is the inverse of !=, or
  that < is the inverse of >=.  This makes it possible to define types
  with partial orderings.

  Classes or types that want to implement (in)equality tests but not
  the ordering operators (i.e. unordered types) should implement ==
  and !=, and raise an error for the ordering operators.

  It is possible to define types whose comparison results are not
  Boolean; e.g. a matrix type might want to return a matrix of bits
  for A < B, giving elementwise comparisons.  Such types should ensure
  that any interpretation of their value in a Boolean context raises
  an exception, e.g. by defining __nonzero__ (or the tp_nonzero slot
  at the C level) to always raise an exception.

  XXX TO DO for this feature:

  - the test "test_compare" fails, because of the changed semantics
    for complex number comparisons (1j<2j raises an error now)
  - tuple, dict should implement EQ/NE so containers containing
    complex numbers can be compared for equality (list is already
    done) -- or complex numbers should be reverted to old behavior
  - list.sort() shoud use rich comparison
  - check for memory leaks
  - int, long, float contain new-style-cmp functions that aren't used
    to their full potential any more (the new-style-cmp functions
    introduced by Neil's coercion work are gone again)
  - decide on unresolved issues from PEP 207
  - documentation
  - more testing
  - compare performance to 2.0 (microbench?)

Please give this a good spin -- I'm hoping to check this in and
make it part of the alpha 1 release Friday...

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