[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