~pythonregexp2.7/python/issue2636-09-01+10

« back to all changes in this revision

Viewing changes to Modules/_functoolsmodule.c

  • Committer: Jeffrey C. "The TimeHorse" Jacobs
  • Date: 2008-09-22 21:39:45 UTC
  • mfrom: (39055.1.33 Regexp-2.7)
  • Revision ID: darklord@timehorse.com-20080922213945-23717m5eiqpamcyn
Merged in changes from the Single-Loop Engine branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
   All rights reserved.
10
10
*/
11
11
 
 
12
/* reduce() *************************************************************/
 
13
 
 
14
static PyObject *
 
15
functools_reduce(PyObject *self, PyObject *args)
 
16
{
 
17
        PyObject *seq, *func, *result = NULL, *it;
 
18
 
 
19
        if (!PyArg_UnpackTuple(args, "reduce", 2, 3, &func, &seq, &result))
 
20
                return NULL;
 
21
        if (result != NULL)
 
22
                Py_INCREF(result);
 
23
 
 
24
        it = PyObject_GetIter(seq);
 
25
        if (it == NULL) {
 
26
                PyErr_SetString(PyExc_TypeError,
 
27
                    "reduce() arg 2 must support iteration");
 
28
                Py_XDECREF(result);
 
29
                return NULL;
 
30
        }
 
31
 
 
32
        if ((args = PyTuple_New(2)) == NULL)
 
33
                goto Fail;
 
34
 
 
35
        for (;;) {
 
36
                PyObject *op2;
 
37
 
 
38
                if (args->ob_refcnt > 1) {
 
39
                        Py_DECREF(args);
 
40
                        if ((args = PyTuple_New(2)) == NULL)
 
41
                                goto Fail;
 
42
                }
 
43
 
 
44
                op2 = PyIter_Next(it);
 
45
                if (op2 == NULL) {
 
46
                        if (PyErr_Occurred())
 
47
                                goto Fail;
 
48
                        break;
 
49
                }
 
50
 
 
51
                if (result == NULL)
 
52
                        result = op2;
 
53
                else {
 
54
                        PyTuple_SetItem(args, 0, result);
 
55
                        PyTuple_SetItem(args, 1, op2);
 
56
                        if ((result = PyEval_CallObject(func, args)) == NULL)
 
57
                                goto Fail;
 
58
                }
 
59
        }
 
60
 
 
61
        Py_DECREF(args);
 
62
 
 
63
        if (result == NULL)
 
64
                PyErr_SetString(PyExc_TypeError,
 
65
                           "reduce() of empty sequence with no initial value");
 
66
 
 
67
        Py_DECREF(it);
 
68
        return result;
 
69
 
 
70
Fail:
 
71
        Py_XDECREF(args);
 
72
        Py_XDECREF(result);
 
73
        Py_DECREF(it);
 
74
        return NULL;
 
75
}
 
76
 
 
77
PyDoc_STRVAR(reduce_doc,
 
78
"reduce(function, sequence[, initial]) -> value\n\
 
79
\n\
 
80
Apply a function of two arguments cumulatively to the items of a sequence,\n\
 
81
from left to right, so as to reduce the sequence to a single value.\n\
 
82
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates\n\
 
83
((((1+2)+3)+4)+5).  If initial is present, it is placed before the items\n\
 
84
of the sequence in the calculation, and serves as a default when the\n\
 
85
sequence is empty.");
 
86
 
 
87
 
 
88
 
 
89
 
12
90
/* partial object **********************************************************/
13
91
 
14
92
typedef struct {
247
325
"Tools that operate on functions.");
248
326
 
249
327
static PyMethodDef module_methods[] = {
 
328
        {"reduce",      functools_reduce,     METH_VARARGS, reduce_doc},
250
329
        {NULL,          NULL}           /* sentinel */
251
330
};
252
331