Index: Modules/datetimemodule.c =================================================================== --- Modules/datetimemodule.c (revision 57877) +++ Modules/datetimemodule.c (working copy) @@ -1628,6 +1628,47 @@ } static PyObject * +divide_timedelta_float(PyDateTime_Delta *delta, PyObject *denom) +{ + int days; + double seconds; + double us; + double f; + + if (PyFloat_Check(denom)) { + f = PyFloat_AS_DOUBLE(denom); + } else if (PyInt_Check(denom)) { + f = (double)PyInt_AsLong(denom); + } else if (PyLong_Check(denom)) { + f = (double)PyLong_AsLong(denom); + } else { + PyErr_SetString(PyExc_TypeError, + "Invalid denominator for timedelta division."); + return NULL; + } + + /* convert to seconds */ + seconds = GET_TD_DAYS(delta) * (24 * 3600) + + (double)GET_TD_SECONDS(delta) + + (double)GET_TD_MICROSECONDS(delta) / 1e6; + + /* arithmetic is now trivial */ + seconds /= f; + + /* convert back to days, seconds and us, checking for range error */ + days = (int)(seconds / (24 * 3600)); + if (check_delta_day_range(days) < 0) + return NULL; + + seconds = seconds - days * (24 * 3600); + us = (seconds - (int)seconds) * 1e6; + /* round us to nearest whole number */ + us = (int)(us + 0.5); + + return new_delta(days, (int)seconds, (int)us, 1); +} + +static PyObject * delta_add(PyObject *left, PyObject *right) { PyObject *result = Py_NotImplemented; @@ -1776,10 +1817,14 @@ if (PyDelta_Check(left)) { /* delta * ??? */ - if (PyInt_Check(right) || PyLong_Check(right)) + if (PyFloat_Check(right)) + result = divide_timedelta_float( + (PyDateTime_Delta *)left, + right); + else if (PyInt_Check(right) || PyLong_Check(right)) result = divide_timedelta_int( - (PyDateTime_Delta *)left, - right); + (PyDateTime_Delta *)left, + right); } if (result == Py_NotImplemented) @@ -2119,7 +2164,7 @@ 0, /*nb_inplace_xor*/ 0, /*nb_inplace_or*/ delta_divide, /* nb_floor_divide */ - 0, /* nb_true_divide */ + delta_divide, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ }; Index: Lib/test/test_datetime.py =================================================================== --- Lib/test/test_datetime.py (revision 57877) +++ Lib/test/test_datetime.py (working copy) @@ -234,6 +234,18 @@ eq(c//1000, td(0, 0, 1)) eq(a//10, td(0, 7*24*360)) eq(a//3600000, td(0, 0, 7*24*1000)) + eq(a//7.0, td(1)) + eq(b//10.0, td(0, 6)) + eq(c//1000.0, td(0, 0, 1)) + eq(a//10.0, td(0, 7*24*360)) + eq(a//3600000.0, td(0, 0, 7*24*1000)) + eq(a/0.5, td(14)) + eq(b/0.5, td(0, 120)) + eq(a/7, td(1)) + eq(b/10, td(0, 6)) + eq(c/1000, td(0, 0, 1)) + eq(a/10, td(0, 7*24*360)) + eq(a/3600000, td(0, 0, 7*24*1000)) def test_disallowed_computations(self): a = timedelta(42) @@ -245,14 +257,10 @@ self.assertRaises(TypeError, lambda: i+a) self.assertRaises(TypeError, lambda: i-a) - # Mul/div by float isn't supported. + # Mul by float isn't supported. x = 2.3 self.assertRaises(TypeError, lambda: a*x) self.assertRaises(TypeError, lambda: x*a) - self.assertRaises(TypeError, lambda: a/x) - self.assertRaises(TypeError, lambda: x/a) - self.assertRaises(TypeError, lambda: a // x) - self.assertRaises(TypeError, lambda: x // a) # Divison of int by timedelta doesn't make sense. # Division by zero doesn't make sense.