changeset: 89892:89aa669dcc61 user: Benjamin Peterson date: Thu Mar 20 18:00:35 2014 -0500 files: Doc/library/datetime.rst Doc/whatsnew/3.5.rst Lib/datetime.py Lib/test/datetimetester.py Misc/NEWS Modules/_datetimemodule.c description: remove the ability of datetime.time to be considered false (closes #13936) diff -r cbb18e801505 -r 89aa669dcc61 Doc/library/datetime.rst --- a/Doc/library/datetime.rst Thu Mar 20 21:44:53 2014 +0100 +++ b/Doc/library/datetime.rst Thu Mar 20 18:00:35 2014 -0500 @@ -1378,10 +1378,13 @@ * efficient pickling -* in Boolean contexts, a :class:`.time` object is considered to be true if and - only if, after converting it to minutes and subtracting :meth:`utcoffset` (or - ``0`` if that's ``None``), the result is non-zero. - +In boolean contexts, a :class:`.time` object is always considered to be true. + +.. versionchanged:: 3.5 + Before Python 3.5, a :class:`.time` object was considered to be false if it + represented midnight in UTC. This behavior was considered obscure and + error-prone and has been removed in Python 3.5. See :issue:`13936` for full + details. Instance methods: diff -r cbb18e801505 -r 89aa669dcc61 Doc/whatsnew/3.5.rst --- a/Doc/whatsnew/3.5.rst Thu Mar 20 21:44:53 2014 +0100 +++ b/Doc/whatsnew/3.5.rst Thu Mar 20 18:00:35 2014 -0500 @@ -186,4 +186,7 @@ This section lists previously described changes and other bugfixes that may require changes to your code. -* Nothing yet. +* Before Python 3.5, a :class:`datetime.time` object was considered to be false + if it represented midnight in UTC. This behavior was considered obscure and + error-prone and has been removed in Python 3.5. See :issue:`13936` for full + details. diff -r cbb18e801505 -r 89aa669dcc61 Lib/datetime.py --- a/Lib/datetime.py Thu Mar 20 21:44:53 2014 +0100 +++ b/Lib/datetime.py Thu Mar 20 18:00:35 2014 -0500 @@ -1249,12 +1249,6 @@ _check_tzinfo_arg(tzinfo) return time(hour, minute, second, microsecond, tzinfo) - def __bool__(self): - if self.second or self.microsecond: - return True - offset = self.utcoffset() or timedelta(0) - return timedelta(hours=self.hour, minutes=self.minute) != offset - # Pickle support. def _getstate(self): diff -r cbb18e801505 -r 89aa669dcc61 Lib/test/datetimetester.py --- a/Lib/test/datetimetester.py Thu Mar 20 21:44:53 2014 +0100 +++ b/Lib/test/datetimetester.py Thu Mar 20 18:00:35 2014 -0500 @@ -2270,13 +2270,14 @@ self.assertEqual(orig, derived) def test_bool(self): + # time is always True. cls = self.theclass self.assertTrue(cls(1)) self.assertTrue(cls(0, 1)) self.assertTrue(cls(0, 0, 1)) self.assertTrue(cls(0, 0, 0, 1)) - self.assertFalse(cls(0)) - self.assertFalse(cls()) + self.assertTrue(cls(0)) + self.assertTrue(cls()) def test_replace(self): cls = self.theclass @@ -2629,7 +2630,7 @@ self.assertEqual(derived.tzname(), 'cookie') def test_more_bool(self): - # Test cases with non-None tzinfo. + # time is always True. cls = self.theclass t = cls(0, tzinfo=FixedOffset(-300, "")) @@ -2639,23 +2640,11 @@ self.assertTrue(t) t = cls(5, tzinfo=FixedOffset(300, "")) - self.assertFalse(t) + self.assertTrue(t) t = cls(23, 59, tzinfo=FixedOffset(23*60 + 59, "")) - self.assertFalse(t) - - # Mostly ensuring this doesn't overflow internally. - t = cls(0, tzinfo=FixedOffset(23*60 + 59, "")) self.assertTrue(t) - # But this should yield a value error -- the utcoffset is bogus. - t = cls(0, tzinfo=FixedOffset(24*60, "")) - self.assertRaises(ValueError, lambda: bool(t)) - - # Likewise. - t = cls(0, tzinfo=FixedOffset(-24*60, "")) - self.assertRaises(ValueError, lambda: bool(t)) - def test_replace(self): cls = self.theclass z100 = FixedOffset(100, "+100") diff -r cbb18e801505 -r 89aa669dcc61 Misc/NEWS --- a/Misc/NEWS Thu Mar 20 21:44:53 2014 +0100 +++ b/Misc/NEWS Thu Mar 20 18:00:35 2014 -0500 @@ -23,6 +23,9 @@ Library ------- +- Issue #13936: Remove the ability of datetime.time instances to be considered + false in boolean contexts. + - Issue 18931: selectors module now supports /dev/poll on Solaris. Patch by Giampaolo Rodola'. diff -r cbb18e801505 -r 89aa669dcc61 Modules/_datetimemodule.c --- a/Modules/_datetimemodule.c Thu Mar 20 21:44:53 2014 +0100 +++ b/Modules/_datetimemodule.c Thu Mar 20 18:00:35 2014 -0500 @@ -3805,29 +3805,6 @@ return clone; } -static int -time_bool(PyObject *self) -{ - PyObject *offset, *tzinfo; - int offsecs = 0; - - if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) { - /* Since utcoffset is in whole minutes, nothing can - * alter the conclusion that this is nonzero. - */ - return 1; - } - tzinfo = GET_TIME_TZINFO(self); - if (tzinfo != Py_None) { - offset = call_utcoffset(tzinfo, Py_None); - if (offset == NULL) - return -1; - offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset); - Py_DECREF(offset); - } - return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0; -} - /* Pickle support, a simple use of __reduce__. */ /* Let basestate be the non-tzinfo data string. @@ -3895,19 +3872,6 @@ All arguments are optional. tzinfo may be None, or an instance of\n\ a tzinfo subclass. The remaining arguments may be ints.\n"); -static PyNumberMethods time_as_number = { - 0, /* nb_add */ - 0, /* nb_subtract */ - 0, /* nb_multiply */ - 0, /* nb_remainder */ - 0, /* nb_divmod */ - 0, /* nb_power */ - 0, /* nb_negative */ - 0, /* nb_positive */ - 0, /* nb_absolute */ - (inquiry)time_bool, /* nb_bool */ -}; - static PyTypeObject PyDateTime_TimeType = { PyVarObject_HEAD_INIT(NULL, 0) "datetime.time", /* tp_name */ @@ -3919,7 +3883,7 @@ 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc)time_repr, /* tp_repr */ - &time_as_number, /* tp_as_number */ + 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc)time_hash, /* tp_hash */