mirror of
https://github.com/python/cpython.git
synced 2025-09-27 10:50:04 +00:00
remove the ability of datetime.time to be considered false (closes #13936)
This commit is contained in:
parent
265ae86414
commit
ee6bdc07d6
6 changed files with 20 additions and 64 deletions
|
@ -1378,10 +1378,13 @@ Supported operations:
|
||||||
|
|
||||||
* efficient pickling
|
* efficient pickling
|
||||||
|
|
||||||
* in Boolean contexts, a :class:`.time` object is considered to be true if and
|
In boolean contexts, a :class:`.time` object is always considered to be true.
|
||||||
only if, after converting it to minutes and subtracting :meth:`utcoffset` (or
|
|
||||||
``0`` if that's ``None``), the result is non-zero.
|
|
||||||
|
|
||||||
|
.. 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:
|
Instance methods:
|
||||||
|
|
||||||
|
|
|
@ -186,4 +186,7 @@ Porting to Python 3.5
|
||||||
This section lists previously described changes and other bugfixes
|
This section lists previously described changes and other bugfixes
|
||||||
that may require changes to your code.
|
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)
|
_check_tzinfo_arg(tzinfo)
|
||||||
return time(hour, minute, second, microsecond, 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.
|
# Pickle support.
|
||||||
|
|
||||||
def _getstate(self):
|
def _getstate(self):
|
||||||
|
|
|
@ -2270,13 +2270,14 @@ class TestTime(HarmlessMixedComparison, unittest.TestCase):
|
||||||
self.assertEqual(orig, derived)
|
self.assertEqual(orig, derived)
|
||||||
|
|
||||||
def test_bool(self):
|
def test_bool(self):
|
||||||
|
# time is always True.
|
||||||
cls = self.theclass
|
cls = self.theclass
|
||||||
self.assertTrue(cls(1))
|
self.assertTrue(cls(1))
|
||||||
self.assertTrue(cls(0, 1))
|
self.assertTrue(cls(0, 1))
|
||||||
self.assertTrue(cls(0, 0, 1))
|
self.assertTrue(cls(0, 0, 1))
|
||||||
self.assertTrue(cls(0, 0, 0, 1))
|
self.assertTrue(cls(0, 0, 0, 1))
|
||||||
self.assertFalse(cls(0))
|
self.assertTrue(cls(0))
|
||||||
self.assertFalse(cls())
|
self.assertTrue(cls())
|
||||||
|
|
||||||
def test_replace(self):
|
def test_replace(self):
|
||||||
cls = self.theclass
|
cls = self.theclass
|
||||||
|
@ -2629,7 +2630,7 @@ class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase):
|
||||||
self.assertEqual(derived.tzname(), 'cookie')
|
self.assertEqual(derived.tzname(), 'cookie')
|
||||||
|
|
||||||
def test_more_bool(self):
|
def test_more_bool(self):
|
||||||
# Test cases with non-None tzinfo.
|
# time is always True.
|
||||||
cls = self.theclass
|
cls = self.theclass
|
||||||
|
|
||||||
t = cls(0, tzinfo=FixedOffset(-300, ""))
|
t = cls(0, tzinfo=FixedOffset(-300, ""))
|
||||||
|
@ -2639,22 +2640,10 @@ class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase):
|
||||||
self.assertTrue(t)
|
self.assertTrue(t)
|
||||||
|
|
||||||
t = cls(5, tzinfo=FixedOffset(300, ""))
|
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)
|
self.assertTrue(t)
|
||||||
|
|
||||||
# But this should yield a value error -- the utcoffset is bogus.
|
t = cls(23, 59, tzinfo=FixedOffset(23*60 + 59, ""))
|
||||||
t = cls(0, tzinfo=FixedOffset(24*60, ""))
|
self.assertTrue(t)
|
||||||
self.assertRaises(ValueError, lambda: bool(t))
|
|
||||||
|
|
||||||
# Likewise.
|
|
||||||
t = cls(0, tzinfo=FixedOffset(-24*60, ""))
|
|
||||||
self.assertRaises(ValueError, lambda: bool(t))
|
|
||||||
|
|
||||||
def test_replace(self):
|
def test_replace(self):
|
||||||
cls = self.theclass
|
cls = self.theclass
|
||||||
|
|
|
@ -23,6 +23,9 @@ Core and Builtins
|
||||||
Library
|
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.
|
- Issue 18931: selectors module now supports /dev/poll on Solaris.
|
||||||
Patch by Giampaolo Rodola'.
|
Patch by Giampaolo Rodola'.
|
||||||
|
|
||||||
|
|
|
@ -3805,29 +3805,6 @@ time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
|
||||||
return clone;
|
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__. */
|
/* Pickle support, a simple use of __reduce__. */
|
||||||
|
|
||||||
/* Let basestate be the non-tzinfo data string.
|
/* 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\
|
All arguments are optional. tzinfo may be None, or an instance of\n\
|
||||||
a tzinfo subclass. The remaining arguments may be ints.\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 = {
|
static PyTypeObject PyDateTime_TimeType = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
"datetime.time", /* tp_name */
|
"datetime.time", /* tp_name */
|
||||||
|
@ -3919,7 +3883,7 @@ static PyTypeObject PyDateTime_TimeType = {
|
||||||
0, /* tp_setattr */
|
0, /* tp_setattr */
|
||||||
0, /* tp_reserved */
|
0, /* tp_reserved */
|
||||||
(reprfunc)time_repr, /* tp_repr */
|
(reprfunc)time_repr, /* tp_repr */
|
||||||
&time_as_number, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
0, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
(hashfunc)time_hash, /* tp_hash */
|
(hashfunc)time_hash, /* tp_hash */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue