diff options
author | Mark Dickinson <dickinsm@gmail.com> | 2010-04-20 22:32:49 (GMT) |
---|---|---|
committer | Mark Dickinson <dickinsm@gmail.com> | 2010-04-20 22:32:49 (GMT) |
commit | 7c186e2a18bf174afd5cccc8c35b7167d05f7e2a (patch) | |
tree | 1ba75e9cb85d4ab1e0320d3636c1db90d5c8f97e /Modules/datetimemodule.c | |
parent | 50eb60e6bfedbdad2dda30fa5ce7fe3ce83f7748 (diff) | |
download | cpython-7c186e2a18bf174afd5cccc8c35b7167d05f7e2a.zip cpython-7c186e2a18bf174afd5cccc8c35b7167d05f7e2a.tar.gz cpython-7c186e2a18bf174afd5cccc8c35b7167d05f7e2a.tar.bz2 |
Issue #2706: Add support for dividing a timedelta by another timedelta.
Adds support for the three division operations:
- timedelta / timedelta -> float
- timedelta // timedelta -> int
- timedelta % timedelta -> timedelta
also adds support for divmod(timedelta, timedelta).
Patch by Victor Stinner, adapted for py3k and extended by Alexander
Belopolsky.
Diffstat (limited to 'Modules/datetimemodule.c')
-rw-r--r-- | Modules/datetimemodule.c | 150 |
1 files changed, 147 insertions, 3 deletions
diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c index c6efee0..2896486 100644 --- a/Modules/datetimemodule.c +++ b/Modules/datetimemodule.c @@ -1666,6 +1666,52 @@ divide_timedelta_int(PyDateTime_Delta *delta, PyObject *intobj) } static PyObject * +divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right) +{ + PyObject *pyus_left; + PyObject *pyus_right; + PyObject *result; + + pyus_left = delta_to_microseconds(left); + if (pyus_left == NULL) + return NULL; + + pyus_right = delta_to_microseconds(right); + if (pyus_right == NULL) { + Py_DECREF(pyus_left); + return NULL; + } + + result = PyNumber_FloorDivide(pyus_left, pyus_right); + Py_DECREF(pyus_left); + Py_DECREF(pyus_right); + return result; +} + +static PyObject * +truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right) +{ + PyObject *pyus_left; + PyObject *pyus_right; + PyObject *result; + + pyus_left = delta_to_microseconds(left); + if (pyus_left == NULL) + return NULL; + + pyus_right = delta_to_microseconds(right); + if (pyus_right == NULL) { + Py_DECREF(pyus_left); + return NULL; + } + + result = PyNumber_TrueDivide(pyus_left, pyus_right); + Py_DECREF(pyus_left); + Py_DECREF(pyus_right); + return result; +} + +static PyObject * delta_add(PyObject *left, PyObject *right) { PyObject *result = Py_NotImplemented; @@ -1810,6 +1856,27 @@ delta_divide(PyObject *left, PyObject *right) result = divide_timedelta_int( (PyDateTime_Delta *)left, right); + else if (PyDelta_Check(right)) + result = divide_timedelta_timedelta( + (PyDateTime_Delta *)left, + (PyDateTime_Delta *)right); + } + + if (result == Py_NotImplemented) + Py_INCREF(result); + return result; +} + +static PyObject * +delta_truedivide(PyObject *left, PyObject *right) +{ + PyObject *result = Py_NotImplemented; + + if (PyDelta_Check(left)) { + if (PyDelta_Check(right)) + result = truedivide_timedelta_timedelta( + (PyDateTime_Delta *)left, + (PyDateTime_Delta *)right); } if (result == Py_NotImplemented) @@ -1817,6 +1884,83 @@ delta_divide(PyObject *left, PyObject *right) return result; } +static PyObject * +delta_remainder(PyObject *left, PyObject *right) +{ + PyObject *pyus_left; + PyObject *pyus_right; + PyObject *pyus_remainder; + PyObject *remainder; + + if (!PyDelta_Check(left) || !PyDelta_Check(right)) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + + pyus_left = delta_to_microseconds((PyDateTime_Delta *)left); + if (pyus_left == NULL) + return NULL; + + pyus_right = delta_to_microseconds((PyDateTime_Delta *)right); + if (pyus_right == NULL) { + Py_DECREF(pyus_left); + return NULL; + } + + pyus_remainder = PyNumber_Remainder(pyus_left, pyus_right); + Py_DECREF(pyus_left); + Py_DECREF(pyus_right); + if (pyus_remainder == NULL) + return NULL; + + remainder = microseconds_to_delta(pyus_remainder); + if (remainder == NULL) { + Py_DECREF(divmod); + return NULL; + } + + return remainder; +} + +static PyObject * +delta_divmod(PyObject *left, PyObject *right) +{ + PyObject *pyus_left; + PyObject *pyus_right; + PyObject *divmod; + PyObject *microseconds, *delta; + + if (!PyDelta_Check(left) || !PyDelta_Check(right)) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + + pyus_left = delta_to_microseconds((PyDateTime_Delta *)left); + if (pyus_left == NULL) + return NULL; + + pyus_right = delta_to_microseconds((PyDateTime_Delta *)right); + if (pyus_right == NULL) { + Py_DECREF(pyus_left); + return NULL; + } + + divmod = PyNumber_Divmod(pyus_left, pyus_right); + Py_DECREF(pyus_left); + Py_DECREF(pyus_right); + if (divmod == NULL) + return NULL; + + microseconds = PyTuple_GetItem(divmod, 1); + delta = microseconds_to_delta(microseconds); + if (delta == NULL) { + Py_DECREF(divmod); + return NULL; + } + PyTuple_SetItem(divmod, 1, delta); + return divmod; +} + /* Fold in the value of the tag ("seconds", "weeks", etc) component of a * timedelta constructor. sofar is the # of microseconds accounted for * so far, and there are factor microseconds per current unit, the number @@ -2108,8 +2252,8 @@ static PyNumberMethods delta_as_number = { delta_add, /* nb_add */ delta_subtract, /* nb_subtract */ delta_multiply, /* nb_multiply */ - 0, /* nb_remainder */ - 0, /* nb_divmod */ + delta_remainder, /* nb_remainder */ + delta_divmod, /* nb_divmod */ 0, /* nb_power */ (unaryfunc)delta_negative, /* nb_negative */ (unaryfunc)delta_positive, /* nb_positive */ @@ -2135,7 +2279,7 @@ static PyNumberMethods delta_as_number = { 0, /*nb_inplace_xor*/ 0, /*nb_inplace_or*/ delta_divide, /* nb_floor_divide */ - 0, /* nb_true_divide */ + delta_truedivide, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ }; |