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

M.-A. Lemburg mal at python.org
Mon Feb 17 13:11:47 CET 2014

On 17.02.2014 12:49, Gustavo Carneiro wrote:
> On 17 February 2014 11:43, M.-A. Lemburg <mal at egenix.com> wrote:
>> On 17.02.2014 12:23, Gustavo Carneiro wrote:
>>> On 17 February 2014 11:14, M.-A. Lemburg <mal at egenix.com> wrote:
>>>> On 15.02.2014 07:03, Stephen J. Turnbull wrote:
>>>>> M.-A. Lemburg writes:
>>>>>  > IMO, it was a mistake to have None return a TypeError in
>>>>>  > comparisons, since it makes many typical data operations
>>>>>  > fail, e.g.
>>>>> I don't understand this statement.  The theory is that they *should*
>>>>> fail.
>>>>> The example of sort is a good one.  Sometimes you want missing values
>>>>> to be collected at the beginning of a list, sometimes at the end.
>>>>> Sometimes you want them treated as top elements, sometimes as bottom.
>>>>> And sometimes it is a real error for missing values to be present.
>>>>> Not to mention that sometimes the programmer simply hasn't thought
>>>>> about the appropriate policy.  I don't think Python should silently
>>>>> impose a policy in that case, especially given that the programmer may
>>>>> have experience with any of the above treatments in other contexts.
>>>> None is special in Python and has always (and intentionally) sorted
>>>> before any other object. In data processing and elsewhere in Python
>>>> programming, it's used to signal: no value available.
>>>> Python 3 breaks this notion by always raising an exception when
>>>> using None in an ordered comparison, making it pretty much useless
>>>> for the above purpose.
>>>> Yes, there are ways around this, but none of them are intuitive.
>>>> Here's a particularly nasty case:
>>>>>>> l = [(1, None), (2, None)]
>>>>>>> l.sort()
>>>>>>> l
>>>> [(1, None), (2, None)]
>>>>>>> l = [(1, None), (2, None), (3, 4)]
>>>>>>> l.sort()
>>>>>>> l
>>>> [(1, None), (2, None), (3, 4)]
>>>>>>> l = [(1, None), (2, None), (3, 4), (2, 3)]
>>>>>>> l.sort()
>>>> Traceback (most recent call last):
>>>>   File "<stdin>", line 1, in <module>
>>>> TypeError: unorderable types: int() < NoneType()
>>> Maybe Python 3 should have a couple of None-like objects that compare the
>>> way you want: AlwaysComparesLess and AlwaysComparesGreater, but with
>> better
>>> names (maybe 'PlusInfinity' and 'MinusInfinity'?).  Just leave None
>> alone,
>>> please.
>> This doesn't only apply to numeric comparisons. In Python 2 you
>> can compare None with any kind of object and it always sorts first,
>> based on the intuition that nothing is less than anything :-)
> I still think that relying on your intuition is not the right way for
> Python.  Refuse the temptation to guess.

Hmm, are you sure ?

There should be one-- and preferably only one --obvious way to do it.

and then

Although that way may not be obvious at first unless you're Dutch.

which directly relates to:

changeset:   16123:f997ded4e219
branch:      legacy-trunk
user:        Guido van Rossum <guido at python.org>
date:        Mon Jan 22 19:28:09 2001 +0000
summary:     New special case in comparisons: None is smaller than any other object


>> FWIW, I don't think we need to invent a new name for it, just add
>> an appropriate tp_richcompare slot to the PyNoneType or readd the
>> special case to Object/object.c. This would also aid in porting
>> existing Python 2 code to Python 3.
> Based on your comment, SortsFirst and SortsLast sound like good names ;-)
> These would be "universal sortable objects", that could be compared to any
> other type.

Of course, it's easy to add a new type for this, but a lot of Python 2
code relies on None behaving this way, esp. code that reads data from
databases, since None is the Python mapping for SQL NULL.

Marc-Andre Lemburg
Python Software Foundation

More information about the Python-Dev mailing list