remove the ability of datetime.time to be considered false (closes #13936)
This commit is contained in:
parent
265ae86414
commit
ee6bdc07d6
|
@ -1378,10 +1378,13 @@ Supported operations:
|
|||
|
||||
* 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:
|
||||
|
||||
|
|
|
@ -186,4 +186,7 @@ Porting to Python 3.5
|
|||
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.
|
||||
|
|
|
@ -1249,12 +1249,6 @@ class time:
|
|||
_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):
|
||||
|
|
|
@ -2270,13 +2270,14 @@ class TestTime(HarmlessMixedComparison, unittest.TestCase):
|
|||
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 @@ class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase):
|
|||
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,22 +2640,10 @@ class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase):
|
|||
self.assertTrue(t)
|
||||
|
||||
t = cls(5, tzinfo=FixedOffset(300, ""))
|
||||
self.assertFalse(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))
|
||||
t = cls(23, 59, tzinfo=FixedOffset(23*60 + 59, ""))
|
||||
self.assertTrue(t)
|
||||
|
||||
def test_replace(self):
|
||||
cls = self.theclass
|
||||
|
|
|
@ -23,6 +23,9 @@ Core and Builtins
|
|||
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'.
|
||||
|
||||
|
|
|
@ -3805,29 +3805,6 @@ time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
|
|||
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 @@ PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time
|
|||
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 @@ static PyTypeObject PyDateTime_TimeType = {
|
|||
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 */
|
||||
|
|
Loading…
Reference in New Issue