[Python-ideas] bool(datetime.time(0, 0))

Steven D'Aprano steve at pearwood.info
Wed May 9 05:20:56 CEST 2012


Nick Coghlan wrote:
> On Tue, May 8, 2012 at 3:42 PM, Steven D'Aprano <steve at pearwood.info> wrote:

>> Consider:
>>
>> t = get_job_start_time()  # returns a datetime.time object, or None
>> if t:
>>    do_something_with(t)
>>
>>
>> Oops, we have a bug. If the job happens to have started at exactly
>> midnight, it will wrongly be treated as false.
> 
> IMO, you've completely misdiagnosed the source of that bug. Never
> *ever* rely on boolean evaluation when testing against None. *Always*
> use the "is not None" trailer.

and then in a follow-up post:

> The problem is not using boolean evaluation - it's assuming that boolean
> evaluation is defined as "x is not None". Doing so introduces a completely
> unnecessary dependency on the type of "x". I'm frankly astonished that so
> many people seem to think it's a reasonable thing to do.

I am perfectly aware that None is not the only falsey value, and that bool 
tests are not implemented as comparisons against None. It is unfortunate that 
this thread has been hijacked into a argument about testing objects in a bool 
context, because that's not the fundamental problem.

In my example code I intentionally assumed that time values don't have a false 
value, to show how the time values encourage buggy code. At the time I wrote 
that example I thought that the behaviour of time values in a bool context was 
undocumented, an easy mistake to make: the only documentation I have found is 
buried under the entry for time.tzinfo:

     a time object is considered to be true if and only if, after
     converting it to minutes and subtracting utcoffset() (or 0
     if that’s None), the result is non-zero.

http://docs.python.org/py3k/library/datetime.html#datetime.time.tzinfo


The complicated nature of this bool context should have been a clue that it 
might have been a bad idea. The false time value is, perhaps "unpredictable" 
is a little strong, but certainly surprising. If my timezone calculations are 
correct, the local time which is falsey for me is 10am. Anyone keen to defend 
having 10am local time treated as false?


Also, be careful about dogmatic prohibitions like "*never* ever rely on 
boolean evaluation when testing against None". The equivalent comparison for 
re MatchObjects is unproblematic. They are explicitly documented as always 
being true, with the explicit aim of allowing boolean evaluation to work 
correctly:

"Match objects always have a boolean value of True. This lets you use a simple 
if-statement to test whether a match was found."

http://docs.python.org/py3k/library/re.html#match-objects

and indeed, there are at least five instances in the standard library that use 
the idiom

mo = re.match(blah blah)
if mo:
     ...

or similar.


It is unfortunate that time values don't operate similarly.



-- 
Steven



More information about the Python-ideas mailing list