Index: Lib/test/test_datetime.py =================================================================== --- Lib/test/test_datetime.py (revision 81381) +++ Lib/test/test_datetime.py (working copy) @@ -225,6 +225,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) @@ -236,14 +248,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) # Division of int by timedelta doesn't make sense. # Division by zero doesn't make sense. @@ -489,7 +497,7 @@ self.assertRaises(ZeroDivisionError, truediv, t, zerotd) self.assertRaises(ZeroDivisionError, floordiv, t, zerotd) - self.assertRaises(TypeError, truediv, t, 2) + # self.assertRaises(TypeError, truediv, t, 2) # note: floor division of a timedelta by an integer *is* # currently permitted. Index: Modules/mathmodule.c =================================================================== --- Modules/mathmodule.c (revision 81381) +++ Modules/mathmodule.c (working copy) @@ -1356,26 +1356,25 @@ long x; PyObject *result, *odd_part, *two_valuation; + PyObject *r; /* result without trailing zeros */ + PyObject *ntz; /* number of trailing zeros */ + long n; + if (PyFloat_Check(arg)) { - PyObject *lx; double dx = PyFloat_AS_DOUBLE((PyFloatObject *)arg); if (!(Py_IS_FINITE(dx) && dx == floor(dx))) { PyErr_SetString(PyExc_ValueError, "factorial() only accepts integral values"); return NULL; } - lx = PyLong_FromDouble(dx); - if (lx == NULL) + n = (long) dx; + } else { + n = PyLong_AsLong(arg); + if (n == -1 && PyErr_Occurred()) return NULL; - x = PyLong_AsLong(lx); - Py_DECREF(lx); } - else - x = PyLong_AsLong(arg); - if (x == -1 && PyErr_Occurred()) - return NULL; - if (x < 0) { + if (n < 0) { PyErr_SetString(PyExc_ValueError, "factorial() not defined for negative values"); return NULL; Index: Modules/datetimemodule.c =================================================================== --- Modules/datetimemodule.c (revision 81381) +++ Modules/datetimemodule.c (working copy) @@ -1712,6 +1712,34 @@ } static PyObject * +divide_timedelta_float(PyDateTime_Delta *delta, double f) +{ + int days; + double seconds; + double us; + + /* 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; @@ -1877,6 +1905,17 @@ result = truedivide_timedelta_timedelta( (PyDateTime_Delta *)left, (PyDateTime_Delta *)right); + if (PyFloat_Check(right)) + result = divide_timedelta_float( + (PyDateTime_Delta *)left, + PyFloat_AS_DOUBLE(right)); + else if (PyLong_Check(right)) { + double f = PyLong_AsDouble(right); + if (f == -1 && PyErr_Occurred()) + return NULL; + result = divide_timedelta_float( + (PyDateTime_Delta *)left, f); + } } if (result == Py_NotImplemented)