Mercurial > cpython-lru_cache-weakref
diff Modules/_functoolsmodule.c @ 48204:b3abff17e2dd legacy-trunk
Copy reduce() to _functools so to have functools.reduce() not raise a warning
from usage under -3.
| author | Brett Cannon <bcannon@gmail.com> |
|---|---|
| date | Sat, 09 Aug 2008 23:30:55 +0000 |
| parents | 26384b8180c7 |
| children | e38335d4df91 184ca6293218 |
line wrap: on
line diff
--- a/Modules/_functoolsmodule.c Sat Aug 09 23:06:16 2008 +0000 +++ b/Modules/_functoolsmodule.c Sat Aug 09 23:30:55 2008 +0000 @@ -9,6 +9,84 @@ All rights reserved. */ +/* reduce() *************************************************************/ + +static PyObject * +functools_reduce(PyObject *self, PyObject *args) +{ + PyObject *seq, *func, *result = NULL, *it; + + if (!PyArg_UnpackTuple(args, "reduce", 2, 3, &func, &seq, &result)) + return NULL; + if (result != NULL) + Py_INCREF(result); + + it = PyObject_GetIter(seq); + if (it == NULL) { + PyErr_SetString(PyExc_TypeError, + "reduce() arg 2 must support iteration"); + Py_XDECREF(result); + return NULL; + } + + if ((args = PyTuple_New(2)) == NULL) + goto Fail; + + for (;;) { + PyObject *op2; + + if (args->ob_refcnt > 1) { + Py_DECREF(args); + if ((args = PyTuple_New(2)) == NULL) + goto Fail; + } + + op2 = PyIter_Next(it); + if (op2 == NULL) { + if (PyErr_Occurred()) + goto Fail; + break; + } + + if (result == NULL) + result = op2; + else { + PyTuple_SetItem(args, 0, result); + PyTuple_SetItem(args, 1, op2); + if ((result = PyEval_CallObject(func, args)) == NULL) + goto Fail; + } + } + + Py_DECREF(args); + + if (result == NULL) + PyErr_SetString(PyExc_TypeError, + "reduce() of empty sequence with no initial value"); + + Py_DECREF(it); + return result; + +Fail: + Py_XDECREF(args); + Py_XDECREF(result); + Py_DECREF(it); + return NULL; +} + +PyDoc_STRVAR(reduce_doc, +"reduce(function, sequence[, initial]) -> value\n\ +\n\ +Apply a function of two arguments cumulatively to the items of a sequence,\n\ +from left to right, so as to reduce the sequence to a single value.\n\ +For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates\n\ +((((1+2)+3)+4)+5). If initial is present, it is placed before the items\n\ +of the sequence in the calculation, and serves as a default when the\n\ +sequence is empty."); + + + + /* partial object **********************************************************/ typedef struct { @@ -247,6 +325,7 @@ "Tools that operate on functions."); static PyMethodDef module_methods[] = { + {"reduce", functools_reduce, METH_VARARGS, reduce_doc}, {NULL, NULL} /* sentinel */ };
