So ignoring the hype, here's the outcome-to-date...<p>The ticket was reconsidered, reopened and classified as a bug.
<a href="http://bugs.python.org/msg212771" rel="nofollow">http://bugs.python.org/msg212771</a><p>Nick Coghlan's dissection of the issue here: <a href="https://mail.python.org/pipermail/python-ideas/2014-March/026647.html" rel="nofollow">https://mail.python.org/pipermail/python-ideas/2014-March/02...</a> is pretty much perfect - wonderful piece of technical writing!<p>Donald Stufft has expressed an interest in making the patch for this happen, and <i>assuming</i> all goes as planned this usage will raise a deprecation warning in 3.5 and be fully fixed in 3.6.<p>News in brief: User raises issue. Issue gets resolved.
If I understand the argument there correctly, the responder is saying: Nobody should ever use this functionality, instead they should always check that the date is not None. So, we should leave this broken, because we don't want to break backwards-compatibility with that class of applications that nobody should ever write.<p>That philosophy, taken to its logical conclusion, results in everything being broken forever.
INADA Naoki's argument [1] is succinct and insightful.<p><pre><code> I feel zero value of non abelian group should not mean
False in bool context.
() + () == ()
"" + "" == ""
0 + 0 == 0
timedelta() + timedelta() == timedelta()
time() + time() => TypeError
</code></pre>
[1] <a href="https://mail.python.org/pipermail/python-ideas/2014-March/026674.html" rel="nofollow">https://mail.python.org/pipermail/python-ideas/2014-March/02...</a>
I've never seen a good argument for anything beside "false" to be considered false. Likewise for "true". Keystrokes are not a commodity for most coders, and compilers are not dumb; just be explicit and write "!= 0" or whatever.<p>(And 0 == False, "" != False, but both 0 and "" are considered false? C'mon Python, that's borderline JavaScript territory.)
I just got bit by this a few days ago. I was creating an event scheduling system that uses either repeating entries with a datetime.time, or one time entries with a datetime.datetime. I had code that said "if start_time" to see which it was, and discovered later that midnight evaluates to false. It's not the best idea.
Ignoring Python for a bit and thinking as a designer of some hypothetical future language: there is a nice rule given here for evaluation in a Boolean context. I wonder whether it should be taken as a general guideline for future languages.<p>The rule, in its entirety, is this:<p>- Booleans are falsy when false.<p>- Numbers are falsy when zero.<p>- Containers are falsy when empty.<p>- None is always falsy.<p>- No other type of value is ever falsy.<p>I can think of two ways we might possibly want to alter the rule.<p>The first is to expand the idea of <i>number</i> to include arbitrary groups (or monoids?), with the identity element being falsy. So, for example, a matrix with all entries zero might be falsy. Or a 3-D transformation might be falsy if it does not move anything.<p>The second is one I have encountered in C++. There, an I/O stream is falsy if it is in an error state. This makes error checking easy; there is one less member-function name to remember. We might expand this idea to include things like Python's urllib, or any object that wraps a connection or stream of some kind.<p>EDIT: OTOH, there is the Haskell philosophy, where the only thing that can be evaluated in a Boolean context is a Bool, so the only falsy thing is <i>False</i>.<p>EDIT 2: The comment by clarkevans (quoting a message from INADA Naoki) already partially addressed the above group idea: "I feel zero value of non abelian group should not mean False in bool context."
James Coglan recently pointed out that all of Python's falsy values are the additive identity of some type. Midnight fits the mold.<p>This results in some weird results from an intuitive perspective, but is very principled and elegant in other ways.<p>My one objection was that I don't know how None fits in.
Lots of Python objects are falsey: empty lists, empty strings, etc. So it's never a good idea to write "if <thing>" when you mean "if <thing> is not None".<p>This is pretty well-known, I thought.
Off the top of my head I can't think of a reason to check if a date exists, but I would certainly expect midnight to be truthy if I found a reason.
Whilst reading that thread, I stumbled accross:<p><pre><code> "goto fail" is a well-known error handling mechanism in open source
software, widely reputed for its robusteness:
http://opensource.apple.com/source/Security/Security-55471/libsecurity_ssl/lib/sslKeyExchange.c
https://www.gitorious.org/gnutls/gnutls/source/6aa26f78150ccbdf0aec1878a41c17c41d358a3b:lib/x509/verify.c
I believe Python needs to add support for this superior paradigm.
It would involve a new keyword "fail" and some means of goto'ing to it.
I suggest "raise to fail":
if (some_error):
raise to fail
fail:
<error handling code>
Unless there are many objections, this fantastic idea might be submitted
in a (short) PEP somewhere around the beginning of next month.
There is some obvious overlap with the rejected "goto PEP" (PEP 3163)
and the Python 2.3 goto module. However, the superiority of goto fail as
error generation and error handling paradigm has since then been
thoroughly proven.
</code></pre>
<a href="https://mail.python.org/pipermail/python-ideas/2014-March/026581.html" rel="nofollow">https://mail.python.org/pipermail/python-ideas/2014-March/02...</a>
I think he understates the most powerful part of his argument.<p>Midnight is a value, not a special value. There is no reason why it or any other valid time should be falsey on a daily cycle.
I think the interesting part is what is revealed about Python and the difference with something like Ruby.<p>Python is stable[0] and places a high degree of importance on backwards compatibility.<p>This behaviour is well documented (and called out for particular note). This reinforces that it is (a) official and (b) not a bug because it is the documented behaviour.<p>On the other hand Ruby (and most Ruby libraries) seem both less concerned with backwards compatibility, have less thorough documentation[1] but are more willing to change and improve.<p>There isn't a right and a wrong between these approaches although for most things I think I would prefer something between the two. I think I generally prefer Python in terms of syntax (Ruby is a bit too flexible with too many ways to do things for my taste) but I do wonder if Python will be left a little behind.<p>[0] Python 2/3 transition is a single big deliberate change.<p>[1] I have an open Rails issue that I don't know if is a bug or not because there isn't documentation that is sufficient to compare the behaviour with so it is a case of what feels right/wrong: <a href="https://github.com/rails/rails/issues/6659" rel="nofollow">https://github.com/rails/rails/issues/6659</a>
Not being a Pythonista, I have the following questions:<p>1) Is there a (native or custom) date type in Python? Is it an object?<p>2) Midnight <i>when</i>? Today? This date last year? Sure there's a "zero value" for dates - it's the epoch for whichever platform or library you're using.<p>3) Why in would anyone call it a "date" if it's really a <i>time</i>?<p>Maybe I'm getting off into the philosophical decisions of the reptile wranglers, but this particular debate sounds a lot like someone made a decision long ago that had ramifications further than expected and now the justification is engrained, things are built on it, and no one's willing to make the 'correction.'
Python has weird ideas about comparisons, I'm pretty sure it's the only language where this is possible: <a href="https://eval.in/113749" rel="nofollow">https://eval.in/113749</a>
The only reason for midnight being a falsy value that I can think of is that someone thought that <i>all</i> objects should provide some functionality for __nonzero__/__bool__.<p>It was a bad idea.
Midnight UTC is zero's all the way down. Seems false to me, but I'm from the land of C. This seems to be in line with some low level hardware or common assembly practice across many languages.<p>Everyone is talking higher echelons of consideration, but what effect is there on generated byte code or in fitting within the virtual machine's tight pants?
This offers a counterexample to the simplistic notion that 'duck typing' results in programs that automagically do the right thing. The reality is that duck typing does not relieve you of the responsibility of understanding the semantics of the elements you use to construct a program from.
This is freakishly similar to the discussion on a PHP bug I submitted in 2006:<p><a href="https://bugs.php.net/bug.php?id=39579" rel="nofollow">https://bugs.php.net/bug.php?id=39579</a>
This sub discussion seemed interesting to me:
<a href="https://mail.python.org/pipermail/python-ideas/2014-March/026656.html" rel="nofollow">https://mail.python.org/pipermail/python-ideas/2014-March/02...</a><p>My first thought was this:<p><a href="http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements005.htm" rel="nofollow">http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_el...</a>
While I agree this is surprising behavior and I wouldn't design an API this way, it is documented behavior. From the docs:<p>"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"<p>Changing at this point would possibly break code that relied on documented library behavior. That's not a responsible thing to do.
In every other language I've used, a time value of 0 is used when a datetime only contains a date and doesn't have a specific time. The existing behavior would make sense in that context. I know Python also has a separate date object, are the two interchangeable enough that you could mix and match without problems?
I came across a similar issue when using rails the other day, where I gave my model a boolean field that had presence validation.
The presence validation of the boolean field fails if the bool is set to false, had me confused for a while, but It wasn't a big enough issue for me to research/report.
It seems there are two choices:<p>1. Before applying a numerical value to a Boolean test, ask whether it can ever be zero when that's not the intent of the test.<p>2. Create a new rule that forbids testing numerical values as though they're Booleans, and break nearly every program in existence.<p>Hmm ... wait ... I'm thinking it over.
Creeping semi-booleans make me very uncomfortable. But what's the alternative? A-values and I-values? A "μ" for questions unanswerable in the type system? Just punt and let Javascriptisms take over the world?
This is how languages die. I wasn't aware that Python had become such a bureaucracy.<p>The current behavior is insane - just fix it! No need for days of discussion on the mailing list or three-point non regression plans.