[Python-ideas] Please reconsider the Boolean evaluation of midnight

Skip Montanaro skip at pobox.com
Wed Mar 5 15:34:16 CET 2014


On Wed, Mar 5, 2014 at 4:44 AM, Paul Moore <p.f.moore at gmail.com> wrote:
>>     if event.start_time:
>>         # stuff
>>
>> unexpectedly fails if start_time is midnight.
>
> Yeah, I was classing that as "application bug" and it's easy to fix
> with an "is not None".

+1, +1, +1. This is nothing more than an application bug. Issue 13936
should not be reopened.

This is a very common mistake when None is used as a sentinel value
(though people normally get away with it), especially by people coming
from languages having NULL pointers which shall not be named. After
all, "None" and "NULL" both start with the letter "N". Surely, they
must represent the same fundamental concept, right? <wink>

Let's change the problem slightly. Instead of time objects, let's
consider the domain of possible values to be integers. Clearly, None
is not a member of that set. You could thus use it as a sentinel. So,
tell me, OP. Would this usage be correct?

    if event.some_id:
        # stuff

I would argue, "no." I would not argue that 0 should not compare as
False, however. I would fix my code:

    if event.some_id is not None:
        # stuff

In contexts where None is an element of the set of possible values
(and thus can't be used as a sentinel value itself), it's common to
explicitly create such a (unique) value, e.g.:

    SENTINEL = ["xyz"]                # or [None] or {} or set([sys])
or ..., but not () or 1 or True!

When you check for the sentinel you have to be explicit (and you MUST
check for it using the "is" operator, to drag in another recent
thread):

    if something is SENTINEL:
        mix_the_special_sauce()

Using None as a sentinel value is no different, it just happens to a)
already exist, and b) be unique, saving you an exceedingly small
amount of typing. If you were trying to be terribly clever, there are
lots of other values in Python (at least in CPython) which happen to
be unique (the empty tuple, small integers, True and False, ...), and
could thus theoretically be used as a sentinel. Someone would
eventually slap your wrist for that sort of thing though (one would
hope).

Two final points.

1. If you wanted to modify the language (or the standard library) in
some way, perhaps the more theoretically reasonable request would be
to ask that None not be usable in a boolean context. Making that
change would certainly break a lot of code though, so it's too late to
do that.

2. The more I think about it, the more I think None should not be used
as a sentinel.

Skip


More information about the Python-ideas mailing list