[Python-Dev] python 3 niggle: None < 1 raises TypeError

Tim Peters tim.peters at gmail.com
Tue Feb 18 05:25:28 CET 2014

[M.-A. Lemburg]
> ...
> None worked as "compares less than all other objects" simply due
> to the fact that None is a singleton and doesn't implement the
> comparison slots (which for all objects not implementing rich
> comparisons, meant that the fallback code triggered in Python 2).

And the fallback code - which you've already found - went on to
special-case the snot out of None to make "less than" work.  It's not
like it was "a natural" outcome:  it was forced.

> In Python 3 the special casing was dropped and because None
> still doesn't implement the comparison slot (tp_richcompare this time),
> it doesn't support ordering comparisons anymore.

Which makes mixed-type non-numeric default comparisons involving None
work the same way all other mixed-type non-numeric default comparisons
work in Python 3.  This was the result of a deliberate design decision
about how comparison _should_ work in Python 3, not an accidental
consequence of the None type not defining tp_richcompare.

IOW, this is about design, not about implementation.  The differing
implementations you see are consequences of the differing designs.
Staring at the implementations is irrelevant to the design decisions.

> Now, the choice to have None compare less than all other objects
> may have been arbitrary, but IMO it was a good, consistent and
> useful choice.

Possibly useful for some apps, sure.  Not for my apps.  For example,
when I initialize an object attribute to None in Python 3, I _expect_
I'll get an exception if I try to use that attribute in most contexts.
 It makes no more sense to ask whether that attribute is, say, less
than 3, than it does to add 3 to it.  The exception is most useful
then.  More often than not, it was annoying to me that Python 2
_didn't_ whine about trying to compare None.

> So why not bring it back

A huge barrier is (or should be) that Python 3 is over 5 years old
now.  Fiddling with the semantics of basic builtin types was possible
- and even welcome - 6 years ago.  Now they really shouldn't be
touched in the absence of a critical bug, or a wholly
backward-compatible (with Python 3) addition.

> and perhaps this time in a way that actually does work consistently for
> all Python objects by implementing the tp_richcompare slot on
> PyNoneType objects and documenting it ?!

Something to suggest for Python 4, in which case I'll only be -0 ;-)

More information about the Python-Dev mailing list