classification
Title: RFE: change bool(datetime.time(0, 0, 0)) to evaluate as True
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Alexander.Belopolsky, Amber.Yust, Andreas.Pelme, BreamoreBoy, Hanxue.Lee, Lakin.Wecker, alex, belopolsky, cvrebert, dstufft, eric.araujo, ethan.furman, fandingo, georg.brandl, gwrtheyrn, lemburg, lilydjwg, mark.dickinson, ncoghlan, pitrou, python-dev, r.david.murray, shai, skip.montanaro, tim.peters, westley.martinez, yselivanov
Priority: normal Keywords:

Created on 2012-02-03 20:43 by Lakin.Wecker, last changed 2014-03-20 23:02 by python-dev. This issue is now closed.

Messages (51)
msg152556 - (view) Author: Lakin Wecker (Lakin.Wecker) Date: 2012-02-03 20:43
midnight is represented by datetime.time(0,0,0).  However, this time (unlike all other valid times, including datetime.time(0,0,1)) evalutes to false in if conditions:

import datetime
if datetime.time(0,0,0):
    print "datetime.time(0,0,0) is not a bug!"
else:
    print "datetime.time(0,0,0) is a bug!"

if datetime.time(0,0,1):
    print "datetime.time(0,0,1) is not a bug!"
else:
    print "datetime.time(0,0,1) is a bug!"
msg152557 - (view) Author: Lakin Wecker (Lakin.Wecker) Date: 2012-02-03 20:43
I'm updating the versions to the ones that I've actually tried it on - this is not an exhaustive search at this point.
msg152558 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2012-02-03 20:52
I don't think I would have ever thought of testing a datetime for its truth value.  But the behavior you observe is consistent with the rest of Python: 0 is false.

I wonder if this is by design or by accident.
msg152559 - (view) Author: Lakin Wecker (Lakin.Wecker) Date: 2012-02-03 20:55
Right. I've updated my code to be more correct:

instead of:

if not start_time:
    start_time = default_time

it now reads:

if start_time is None:
    start_time = default_time

which operates correctly and works fine for my case, I just thought it was odd that one time out of all of them evaluates to False.  I too wonder if it's by design or not.

It's definitely not documented if it is by design.
msg152560 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2012-02-03 21:04
It must be by design -- someone has implemented a __bool__ (formerly __nonzero__) method; otherwise all objects would be true.
msg152561 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2012-02-03 21:05
BTW, "being a valid time" is not a good argument: 0, "" or False are all valid instances of their types.
msg152562 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2012-02-03 21:09
This is by design.  I don't have a reference, but I do remember this being discussed.  Suggestions for improving the documentation are welcome.
msg152563 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2012-02-03 21:19
From the docs, at:

http://docs.python.org/library/datetime.html#time-objects

"""
in Boolean contexts, 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.
"""
msg152564 - (view) Author: Lakin Wecker (Lakin.Wecker) Date: 2012-02-03 21:23
Although I find it odd, you are all correct.

It is documented.  (I don't know how I missed that when I read those docs looking for that exact documentation).

It is consistent with the rest of python.

Do I close this? Do you guys? I'm fine with closing it.  Thanks and sorry for the noise.
msg152565 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2012-02-03 21:28
It is odd, but really no odder than "zero values" of other types evaluating to false in Boolean contexts ;-)  Closing as "invalid".
msg152567 - (view) Author: Lakin Wecker (Lakin.Wecker) Date: 2012-02-03 21:30
Yeah - good point, and I agree.
msg176475 - (view) Author: Danilo Bargen (gwrtheyrn) Date: 2012-11-27 14:10
I disagree, I think this bug should be reopened and fixed.

A use case that I just ran into: I'm using a Django form with time fields that aren't required, but that are only valid in combination (if there's a open time there has to be a close time).

    if not (self.closed or (self.open_time and self.close_time )):                  
        raise ValidationError("Invalid times")

This leads to a Validation Error when using the times 12:00 and 00:00.

Of course, this case is debatable and can be worked around by using `self.open is not None and self.close is not None`, but there are even more problems when using the times inside the template.

I'm using the following widespread pattern inside my templates:

    <p>Close time: {{ close_time|default:"-" }}</p>

The "default" filter used in this case displays the string "-" if the value on the left side of the | symbol evaluates to False. That makes sense in almost all of the cases.

In the case of the `datetime.time(0, 0)` object, the default value is displayed, even though `datetime.time(0, 0).__str__()` results in a valid string (in this case '00:00:00').

(By the way, through these experiments I also found a bug in Django's date formatting template function caused by this inconsistency, which I will report separately.)

I agree that casting time objects to a boolean value doesn't make much sense. But especially because of that, inconsistencies in the resulting boolean value should NOT exist. Yet another argument for this is that in many regions midnight isn't considered 00:00, but 24:00, which would obviously not evaluate to False.

Please fix this. Otherwise it will lead to a whole lot of weird bugs in software using the datetime library.
msg212732 - (view) Author: Shai Berger (shai) Date: 2014-03-04 17:41
Just got bit by this.

Tim Peters said: """
It is odd, but really no odder than "zero values" of other types evaluating to false in Boolean contexts.
"""

I disagree. Midnight is not a "zero value", it is just a value. It does not have any special qualities analogous to those of 0, "", or the empty set. Time values cannot be added or multiplied. Midnight evaluting to false makes as much sense as date(1,1,1) -- the minimal valid date value -- evaluating to false (and it doesn't).

It makes perfect sense for timedelta(0) to evaluate to false, and it does. time is different.

Also, while I appreciate this will never be fixed for Python2, the same behavior exists in Python3, where there may still be room for improvement.

I second Danilo Bergen's request. Please reopen.
msg212738 - (view) Author: Andreas Pelme (Andreas.Pelme) * Date: 2014-03-04 20:14
I agree with Danilo and Shai -- this behavior very surprising. I deal with datetimes a lot, and this bug has bitten me a number of times.

I cannot really think of a single case where "if timeobj:" is useful with the current behavior. It results in a check for "is timeobj midnight or false?"

Would that ever be useful in practice? If you are indeed checking for midnight, surely "if timeobj == time(0, 0):" would be the most explicit and obvious way to do it?
msg212743 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2014-03-04 22:21
> Please reopen.

Please bring your case to python-ideas.  All developers who commented on this issue agree that it is invalid.
msg212771 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2014-03-05 22:36
Rewording the issue title and reopening based on the python-ideas thread. The rationale for making this change is that the current behaviour converts a stylistic problem in checking values against a sentinel via "bool(value)" instead of "value is not None" into a subtle data driven behavioural bug that only occurs exactly at midnight UTC.

If someone wants to write the patch to deprecate this behaviour in Python 3.5 (reporting a deprecation warning whenever midnight is interpreted as False, perhaps suggesting the use of "is" or "is not" instead), and then actually change the behaviour in 3.6, I don't believe we should actively oppose them from doing so.
msg212777 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2014-03-05 23:29
Discussion in #20855 made me realise that any deprecation warning should explain how to convert a time object to "seconds since midnight". That model of time of day is the most likely origin of the current behaviour, and explicit conversion to that form would be the easiest way to avoid the deprecation warning in any cases where the current behaviour is actually considered desirable.
msg212778 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2014-03-05 23:30
I like the current behavior. We have modulo arithmetic here and
bool(96%24) is false, too.
msg212779 - (view) Author: Donald Stufft (dstufft) * (Python committer) Date: 2014-03-05 23:34
It's not modulo arithmetic.
msg212782 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2014-03-05 23:49
Unix time modulo 86400 gives the number of elapsed seconds in a day
and is zero at midnight.  Also, modular arithmetic is colloquially
called "clock arithmetic" for a reason.
msg212783 - (view) Author: Amber Yust (Amber.Yust) Date: 2014-03-06 00:06
Yes, but a datetime.time object is definitely not UNIX time.
msg212784 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2014-03-06 01:27
#20855 was meant as a joke, so I'll keep serious responses here.

Nick wrote:

"""
Alexander, my goal is to flip the default assumption in the time discussion. It is clear from the documentation that the current behaviour is intentional, but there is no concrete *use case* given for it. This is in stark contrast to the other types where treating zero or an empty container differently is quite common, and hence generally unsurprising.
"""

I gave a use case on the list:

if dt.time():
   counts[dt.date()] += 1
else:
   counts[dt.date() - timedelta(1)] += 1

I see nothing wrong with this code and I don't think rewriting it as

if dt.time() != datetime.time(0): ..

is an improvement.

"""
This has resulted in a problem, since the default for most types is that all instances are true, and users mistakenly assume that assumption will hold for datetime.time objects. This is particularly likely for newer users that don't have experience with lower level models of time of day as "seconds since midnight" (which is the mental model where the current behaviour makes sense, and the most plausible rationale for its origins).
"""

datetime module types being spelled in lower-case may be enough of a hint to new users that they should expect the instances to behave more like those of builtin types rather than of user-defined classes.
msg212785 - (view) Author: Donald Stufft (dstufft) * (Python committer) Date: 2014-03-06 01:34
I am not even sure what that is supposed to be doing... You're trying to count midnight as the previous day instead of the actual day? That seems extremely contrived.
msg212786 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2014-03-06 01:42
Nick wrote:

> any deprecation warning should explain how to convert
> a time object to "seconds since midnight".

I would like to see such an explanation regardless of the outcome here.

The best I can think of is

timedelta(hours=t.hour, minutes=t.minute, seconds=t.second, microseconds=t.microsecond).total_seconds()

which is only a marginal improvement over 

(t.hour*60 + t.minute)*60 + t.second + 1e-6*t.microsecond

See also #17267.
msg212787 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2014-03-06 01:59
> You're trying to count midnight as the previous day instead of the actual day?

yes

> That seems extremely contrived

Why?  Midnight can be considered to be the last moment of the day or the first moment of the day.  In ISO standard there are separate notations for those: 24:00 and 00:00.  Python does not allow time(24), so an application that considers midnight to be the last moment of the day has to treat time(0) exceptionally.

See also #10427.
msg212788 - (view) Author: Donald Stufft (dstufft) * (Python committer) Date: 2014-03-06 02:02
If Midnight is considered the last moment of the day then it evaluating to false makes even less sense since the rationale given is "time is seconds since midnight". However if you're considering it the last moment then time would be "seconds since 12:01".

So in that case your example using midnight as false is even more confusing and even more wrong than not using ``is None`` on the conditional check. So maybe what you're attempting to do isn't contrived, but it doesn't actually help your position at all.
msg212789 - (view) Author: Donald Stufft (dstufft) * (Python committer) Date: 2014-03-06 02:09
Infact I would argue that ``if dt.time() != datetime.time(0):`` *would* be an improvement to that code because it is more accurately describing what you actually intend in the same way that ``if time_or_none is None`` would be an improvement to that code because it is more accurately describing what you actually intend.

The difference being here that of the two examples I would argue that yours is more wrong because it's nonsensical for a time, especially one that you're considering to be the last of some set and not the first, to be a False value.
msg212790 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2014-03-06 02:30
> If Midnight is considered the last moment of the day then it
> evaluating to false makes even less sense since the rationale
> given is "time is seconds since midnight".

You are erecting a straw-man.  Python clearly considers time(0) to be the first moment of the day, not the last:

>>> time(0) < time(1)
True

It is my application that makes the opposite choice.  Helpfully, boolean property of time(0) makes it easy to write code that treats midnight as a special case.
msg212791 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2014-03-06 02:33
> So in that case your example using midnight as false is even more
> confusing and even more wrong than not using ``is None`` on the
> conditional check.

I should have added that dt is a datetime instance and therefore dt.time() is None is always false.
msg212798 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2014-03-06 09:30
I agree that having midnight evaluate to false is completely unexpected and unintuitive. I can imagine situations where it bites people in production use in the uncommon case that a time is exactly equal to midnight.
msg212799 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2014-03-06 09:37
On 06.03.2014 10:30, Antoine Pitrou wrote:
> 
> Antoine Pitrou added the comment:
> 
> I agree that having midnight evaluate to false is completely unexpected and unintuitive. I can imagine situations where it bites people in production use in the uncommon case that a time is exactly equal to midnight.

datetime values with the time set to midnight are *very* common in practice.
You run into them whenever you convert dates into datetime values.
msg212801 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2014-03-06 09:59
Donald did some additional testing, and it turns out that it is
specifically midnight *UTC* that is false in boolean context. For a TZ
aware time, the false time depends on the offset (e.g. it would be false at
10 am here in Brisbane).
msg212806 - (view) Author: Donald Stufft (dstufft) * (Python committer) Date: 2014-03-06 12:12
It's actually a bit worse than that Nick. It's midnight UTC, as long as the UTC offset is Positive or Zero. This is because the way the check is implemented is naive.

It's implemented as: Take the time portion sans the tzinfo and convert to minutes, then take the utc offset and convert that to minutes, then subtract the second from the first and if that is zero it is False.

So if you take -5 for instance (my own timezone!) the equation to determine when the "False" time is would look like:

x - (-5 * 60) = 0
x - (-300) = 0
x + 300 = 0
x = -300

So we'd need a time that can be represented as -300 minutes. Since times can not be negative that means for a timezone aware time it is impossible for something with a negative UTC offset to ever be False while for a zero or positive UTC offset it'll be False at UTC midnight.
msg212807 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2014-03-06 12:26
I wrote up a longer post on python-ideas regarding the problems that the current behaviour poses when it comes to inferring a correct mental model for datetime.time(): https://mail.python.org/pipermail/python-ideas/2014-March/026647.html

As part of that, it's also worth noting the current behaviour in boolean context is effectively shorthand for:

    import datetime as dt

    naivemidnight = dt.time(0, 0)
    utcmidnight = dt.time(0, 0, tzinfo=dt.timezone.utc
    if x in (naivemidnight, utcmidnight):
        ...

So if the current boolean behaviour is deprecated and removed, it is easily reproduced through equality checks.

It may also make sense to offer an API to easily calculate seconds since midnight, but that would be a separate issue.
msg212871 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2014-03-07 10:33
More proposals from the thread (paraphrased):

- make any aware time() object always True (leave naive midnight as False)
- make any aware time() object with a non-zero UTC offset always True (leave naive midnight and UTC midnight as False)
- deprecate aware time() entirely (raises the thorny question of what to return from .time() on an aware datetime() object)
- add helpers to retrieve naivemidnight and utcmidnight constants, and calculate a localmidnight value (needs to be dynamic in case the local timezone is changed)


Independent observation:

- if time() objects are supposed to be interpreted as representing a time difference relative to midnight rather than a structured object, why is it so hard to actually convert them to an appropriate time delta? There's no method for it, you can't just subtract midnight, there's no constructor on time delta that accepts a time object, you can't easily attach a date to the time to calculate a time delta.

Use case presented for the current behaviour:

- a simulation that tracks the time and date of the simulation independently and relies on the implicit bool behaviour of time objects (not stated why this is considered more maintainable than explicit comparisons with appropriate midnight objects)
msg212873 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2014-03-07 11:03
Current status of thread discussion (yes, I'm biased, and that shows in the phrasing below):

Arguments raised for status quo:

- the module is behaving exactly as described in the documentation
- removing false time values will require affected users to update their code to instead explicitly compare with appropriate midnight values before migrating to Python 3.5 (or, since deprecation warnings are silent by default, except if a test framework enables them, Python 3.6)
- it wasn't an accident, it was designed so modulo arithmetic could reasonably be implemented for time() objects (which hasn't been demanded or implemented since the datetime module was created)
- changing behaviour so that a current subtle data driven bug instead becomes a harmless violation of recommended style for comparison against a sentinel value is encouraging bad programming practices

Arguments in favour of changing the behaviour:

- datetime.time() objects don't behave like a number in any other way (they don't support arithmetic and attempting to convert them with int, float, etc explicitly tells you they're not numbers), and don't even provide an easy way to convert them to a time delta relative to midnight (and hence to "seconds since midnight" via total_seconds), so it's surprising that they behave like a number in boolean context by having a concept of "zero"
- the current behaviour takes something that would be a harmless style error for most structured data types (including datetime and date objects) and instead makes it a subtle data driven behavioural bug (but only if you're using naive times or a timezone with a non-negative UTC offset)
- the current behaviour cannot even be accurately summarised as "midnight evaluates as False", because it is actually "naive midnight and UTC midnight with a non-negative UTC offset evaluate as false, while UTC midnight with a negative UTC offset evaluates as true". That's incoherent and really should be changed, and if we're going to change the behaviour anyway, we may as well change it to something less dangerous.
- any affected code that relies on some variants of midnight being False is already hard to understand (since most readers won't be aware of this subtlety of the behaviour of time objects) and would be made clearer by explicitly comparing against appropriate midnight objects
msg212877 - (view) Author: Skip Montanaro (skip.montanaro) * (Python committer) Date: 2014-03-07 13:19
> the current behaviour takes something that would be a harmless style error for most structured data types ...

I'm not sure what a "structured data type" is, but in my mind the original poster's construct is more than a style error. He was using None as a sentinel, but not explicitly testing for its presence. The same error would be present if he used None as a sentinel value where the range of possible values was the set of all integers.

If there are problems with the definition of "false time" such that there are some combinations of time and timezone where UTC midnight is not zero, I would prefer to correct them.

Further, playing the devil's advocate, if you dispense with any false elements of time objects, why not simply zero out the nb_nonzero slot in time_as_number? Once that's gone, the time_as_number structure is all zeros, so the tp_as_number slot in PyDateTime_TimeType can be cleared.
msg212879 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2014-03-07 14:22
Structured data is just a shorthand way of referring to any Python object
which is neither a number or a container and exhibits the default boolean
behaviour where all instances are true.

The problem datetime.time is both that its current behaviour is internally
incoherent (whether or not an aware time is false depends on the current
timezone in unpredictable ways) and *also* inconsistent with its other
behaviours that indicate it should be handled as a non-numeric value. Since
it isn't a container either, standard conventions suggest that it should
always be true. No *compelling* justifications for its atypical behaviour
have been presented, just a case of Tim wanting to leave the door open to
adding modular arithmetic directly on time instances.

I suggest it makes far more sense to instead eliminate the quirky behaviour
entirely and instead provide an easy way to convert a time to a timedelta
relative to midnight.
msg212880 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2014-03-07 15:12
> it wasn't an accident, it was designed so modulo arithmetic could reasonably be implemented for time() objects (which hasn't been demanded or implemented since the datetime module was created)

Ah, interesting.  I just wrote a program last month where I was baffled that time didn't support arithmetic, and had to dodge painfully through datetime instances to do the arithmetic.  I asked about it on IRC and someone said it was because arithmetic on times was ambiguous because of timezones, and I just accepted that rather than wonder why it hadn't been implemented.

Otherwise I'm pretty sympathetic to the RFE, but I'd really like time arithmetic to work, so I guess I'd have to be -1 in that case, wouldn't I?
msg212881 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2014-03-07 15:15
> Otherwise I'm pretty sympathetic to the RFE, but I'd really like time
> arithmetic to work, so I guess I'd have to be -1 in that case,
> wouldn't I?

Adding times of the day sounds as well-defined to me as adding
centigrade temperatures.
msg212883 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2014-03-07 15:31
As does adding dates.  I'm talking about timedelta arithmetic, just like for datetimes.  I believe that still requires modulo arithmetic :)
msg212884 - (view) Author: Alexander Belopolsky (Alexander.Belopolsky) Date: 2014-03-07 15:32
> On Mar 7, 2014, at 10:12 AM, "R. David Murray" <report@bugs.python.org> wrote:
> 
>  I asked about it on IRC and someone said it was because arithmetic on times was ambiguous because of timezones, and I just accepted that rather than wonder why it hadn't been implemented.
> 
> Otherwise I'm pretty sympathetic to the RFE, but I'd really like time arithmetic to work, so I guess I'd have to be -1 in that case, wouldn't I?

See http://bugs.python.org/issue17267
msg212886 - (view) Author: Alexander Belopolsky (Alexander.Belopolsky) Date: 2014-03-07 15:40
> On Mar 7, 2014, at 10:15 AM, Antoine Pitrou <report@bugs.python.org> wrote:
> 
> Adding times of the day sounds as well-defined to me as adding
> centigrade temperatures.

What is wrong with adding temperatures?  Climate people do it all the time when computing the averages.
msg212892 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2014-03-07 16:41
[Nick]
> - deprecate aware time() entirely (raises the thorny question of what to return from .time() on an aware datetime() object)

aware_datetime_object.time() already returns a naive time object.  The thorny question is what .timetz() should return - but if aware time objects _were_ deprecated, .timetz() itself would presumably be deprecated too.

> ... you can't easily attach a date to the time to calculate a time delta.

The class constructor datetime.combine(date_object, time_object) makes it easy to combine any two date and time objects into a datetime object.
msg212904 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2014-03-07 22:14
If no one else has gotten to this in the next six months or so, I will.  :)
msg212911 - (view) Author: Westley Martínez (westley.martinez) * Date: 2014-03-07 23:16
So is the plan to deprecate this in 3.5 and remove in 3.6?  If so, the question is where should the deprecation be thrown?
msg212915 - (view) Author: Mark Lawrence (BreamoreBoy) Date: 2014-03-08 00:40
There is no plan, other than the BDFL asking for a survey of what is happening with code that relies on this in the real world.  FTR I'm completely against this change.  I see no reason to change something that's been in use for maybe nine years and does what it's documented to do, based on somebody's expectations, failure to read the documents and buggy code.  To me it would be a nail in the coffin of Python's very conservative, and to me extremely proper, view of maintaining backward compatibility.
msg212916 - (view) Author: Donald Stufft (dstufft) * (Python committer) Date: 2014-03-08 00:53
To be specific, Guido said that if this 3.0 or 3.1 he'd be all for changing it, and the only question in his mind is how safe it is change. And that his intuition is that it's a nuisance feature and few people have actually relied on it and that he'd be OK with fixing (and breaking) it in 3.5, perhaps after a thorough search for how often the feature is actually relied on and how legitimate those uses are. (See the full response at https://mail.python.org/pipermail/python-ideas/2014-March/026785.html)
msg212921 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2014-03-08 04:39
Mark, we kinda proved we're willing to break backwards compatibility in the name of improving usability when we embarked down the path of creating Python 3 and an associated transition plan from Python 2, rather than just continuing to develop Python 2.

Compared to some of the backwards compatibility breaks within the Python 2 series that were handled using the normal deprecating cycle (removing string exceptions, anyone?), this one would be truly trivial.
msg213434 - (view) Author: Justin Brown (fandingo) Date: 2014-03-13 18:31
This behavior conflicts with the other major classes, datetime.date and datetime.datetime. The ostensible reason for this falsy behavior is that midnight represents a fundamental zero point. We should expect to see similar zero points that evaluate to False for the other two classes. However, they do not include such falsy behavior.

In [2]: bool(datetime.datetime(datetime.MINYEAR, 1, 1))
Out[2]: True
In [3]: bool(datetime.date(datetime.MINYEAR, 1, 1))
Out[3]: True

Why don't these classes have any sense of zero at their minimums?

datetime.time.__bool__ should be dropped if for nothing more than consistency.
msg214299 - (view) Author: Roundup Robot (python-dev) Date: 2014-03-20 23:02
New changeset 89aa669dcc61 by Benjamin Peterson in branch 'default':
remove the ability of datetime.time to be considered false (closes #13936)
http://hg.python.org/cpython/rev/89aa669dcc61
History
Date User Action Args
2014-03-20 23:02:51python-devsetstatus: open -> closed

nosy: + python-dev
messages: + msg214299

resolution: fixed
stage: resolved
2014-03-20 12:57:07lilydjwgsetnosy: + lilydjwg
2014-03-13 18:31:36fandingosetnosy: + fandingo
messages: + msg213434
2014-03-08 04:39:02ncoghlansetmessages: + msg212921
2014-03-08 00:53:48dstufftsetmessages: + msg212916
2014-03-08 00:40:34BreamoreBoysetnosy: + BreamoreBoy
messages: + msg212915
2014-03-07 23:16:47westley.martinezsetmessages: + msg212911
2014-03-07 22:14:51ethan.furmansetmessages: + msg212904
2014-03-07 19:12:44westley.martinezsetnosy: + westley.martinez
2014-03-07 17:58:48mark.dickinsonsetnosy: + mark.dickinson
2014-03-07 16:41:29tim.peterssetmessages: + msg212892
2014-03-07 15:40:29Alexander.Belopolskysetmessages: + msg212886
2014-03-07 15:32:44Alexander.Belopolskysetnosy: + Alexander.Belopolsky
messages: + msg212884
2014-03-07 15:31:59r.david.murraysetmessages: + msg212883
2014-03-07 15:15:17pitrousetmessages: + msg212881
2014-03-07 15:12:54r.david.murraysetmessages: + msg212880
2014-03-07 14:22:46ncoghlansetmessages: + msg212879
2014-03-07 13:19:21skip.montanarosetnosy: + skip.montanaro
messages: + msg212877
2014-03-07 11:03:43ncoghlansetmessages: + msg212873
2014-03-07 10:33:55ncoghlansetmessages: + msg212871
2014-03-07 05:13:28Hanxue.Leesetnosy: + Hanxue.Lee
2014-03-06 23:25:01ethan.furmansetnosy: + ethan.furman
2014-03-06 14:54:14alexsetnosy: + alex
2014-03-06 12:26:41ncoghlansetmessages: + msg212807
2014-03-06 12:12:46dstufftsetmessages: + msg212806
2014-03-06 09:59:07ncoghlansetmessages: + msg212801
2014-03-06 09:37:24lemburgsetmessages: + msg212799
title: RFE: change bool(datetime.time(0,0,0)) to evaluate as True -> RFE: change bool(datetime.time(0, 0, 0)) to evaluate as True
2014-03-06 09:30:46pitrousetnosy: + pitrou
messages: + msg212798
2014-03-06 02:33:52belopolskysetmessages: + msg212791
2014-03-06 02:30:25belopolskysetmessages: + msg212790
2014-03-06 02:09:55dstufftsetmessages: + msg212789
2014-03-06 02:02:39dstufftsetmessages: + msg212788
2014-03-06 01:59:10belopolskysetmessages: + msg212787
2014-03-06 01:42:46belopolskysetmessages: + msg212786
2014-03-06 01:34:00dstufftsetmessages: + msg212785
2014-03-06 01:27:58belopolskysetnosy: + belopolsky
messages: + msg212784
2014-03-06 00:08:32skrahsetnosy: - skrah
2014-03-06 00:06:30Amber.Yustsetnosy: + Amber.Yust
messages: + msg212783
2014-03-05 23:49:04skrahsetmessages: + msg212782
2014-03-05 23:34:10dstufftsetmessages: + msg212779
2014-03-05 23:30:16skrahsetnosy: + skrah
messages: + msg212778
2014-03-05 23:29:46ncoghlansetmessages: + msg212777
2014-03-05 22:59:59yselivanovsetnosy: + yselivanov
2014-03-05 22:59:46belopolskysetnosy: - belopolsky
2014-03-05 22:50:05dstufftsetnosy: + dstufft
2014-03-05 22:36:22ncoghlansetstatus: closed -> open

type: behavior -> enhancement

title: datetime.time(0,0,0) evaluates to False despite being a valid time -> RFE: change bool(datetime.time(0,0,0)) to evaluate as True
nosy: + ncoghlan
versions: + Python 3.5, - Python 2.6, Python 2.7
messages: + msg212771
resolution: not a bug -> (no value)
2014-03-05 21:59:15cvrebertsetnosy: + cvrebert
2014-03-04 22:21:52belopolskysetmessages: + msg212743
2014-03-04 20:14:17Andreas.Pelmesetnosy: + Andreas.Pelme
messages: + msg212738
2014-03-04 17:41:42shaisetnosy: + shai
messages: + msg212732
2012-11-27 14:10:11gwrtheyrnsetnosy: + gwrtheyrn
messages: + msg176475
2012-05-07 18:29:13eric.araujosetnosy: + eric.araujo
2012-02-03 21:30:47Lakin.Weckersetmessages: + msg152567
2012-02-03 21:28:18tim.peterssetstatus: open -> closed
resolution: not a bug
messages: + msg152565
2012-02-03 21:23:40Lakin.Weckersetmessages: + msg152564
2012-02-03 21:19:49tim.peterssetnosy: + tim.peters
messages: + msg152563
2012-02-03 21:09:22belopolskysetmessages: + msg152562
2012-02-03 21:05:37georg.brandlsetmessages: + msg152561
2012-02-03 21:04:48georg.brandlsetnosy: + georg.brandl, lemburg
messages: + msg152560
2012-02-03 20:55:10Lakin.Weckersetmessages: + msg152559
2012-02-03 20:52:17r.david.murraysetnosy: + belopolsky
2012-02-03 20:52:01r.david.murraysetnosy: + r.david.murray
messages: + msg152558
2012-02-03 20:44:23Lakin.Weckersettype: behavior
components: + Library (Lib)
2012-02-03 20:43:43Lakin.Weckersetmessages: + msg152557
versions: + Python 2.6, Python 2.7
2012-02-03 20:43:16Lakin.Weckercreate