summaryrefslogtreecommitdiff
path: root/Modules/itertoolsmodule.c
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@microsoft.com>2017-02-04 15:05:40 -0800
committerSteve Dower <steve.dower@microsoft.com>2017-02-04 15:05:40 -0800
commitb2fa705fd3887c326e811c418469c784353027f4 (patch)
treeb3428f73de91453edbfd4df1a5d4a212d182eb44 /Modules/itertoolsmodule.c
parent134e58fd3aaa2e91390041e143f3f0a21a60142b (diff)
parentb53654b6dbfce8318a7d4d1cdaddca7a7fec194b (diff)
downloadcpython-b2fa705fd3887c326e811c418469c784353027f4.tar.gz
Issue #29392: Prevent crash when passing invalid arguments into msvcrt module.
Diffstat (limited to 'Modules/itertoolsmodule.c')
-rw-r--r--Modules/itertoolsmodule.c387
1 files changed, 193 insertions, 194 deletions
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
index be0f498252..6bf04cbee3 100644
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -1,4 +1,5 @@
+#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "structmember.h"
@@ -7,7 +8,7 @@
*/
-/* groupby object ***********************************************************/
+/* groupby object ************************************************************/
typedef struct {
PyObject_HEAD
@@ -74,7 +75,7 @@ groupby_traverse(groupbyobject *gbo, visitproc visit, void *arg)
static PyObject *
groupby_next(groupbyobject *gbo)
{
- PyObject *newvalue, *newkey, *r, *grouper, *tmp;
+ PyObject *newvalue, *newkey, *r, *grouper;
/* skip to next iteration group */
for (;;) {
@@ -85,8 +86,7 @@ groupby_next(groupbyobject *gbo)
else {
int rcmp;
- rcmp = PyObject_RichCompareBool(gbo->tgtkey,
- gbo->currkey, Py_EQ);
+ rcmp = PyObject_RichCompareBool(gbo->tgtkey, gbo->currkey, Py_EQ);
if (rcmp == -1)
return NULL;
else if (rcmp == 0)
@@ -101,27 +101,19 @@ groupby_next(groupbyobject *gbo)
newkey = newvalue;
Py_INCREF(newvalue);
} else {
- newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc,
- newvalue, NULL);
+ newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, newvalue, NULL);
if (newkey == NULL) {
Py_DECREF(newvalue);
return NULL;
}
}
- tmp = gbo->currkey;
- gbo->currkey = newkey;
- Py_XDECREF(tmp);
-
- tmp = gbo->currvalue;
- gbo->currvalue = newvalue;
- Py_XDECREF(tmp);
+ Py_XSETREF(gbo->currkey, newkey);
+ Py_XSETREF(gbo->currvalue, newvalue);
}
Py_INCREF(gbo->currkey);
- tmp = gbo->tgtkey;
- gbo->tgtkey = gbo->currkey;
- Py_XDECREF(tmp);
+ Py_XSETREF(gbo->tgtkey, gbo->currkey);
grouper = _grouper_create(gbo, gbo->tgtkey);
if (grouper == NULL)
@@ -178,7 +170,7 @@ static PyMethodDef groupby_methods[] = {
reduce_doc},
{"__setstate__", (PyCFunction)groupby_setstate, METH_O,
setstate_doc},
- {NULL, NULL} /* sentinel */
+ {NULL, NULL} /* sentinel */
};
PyDoc_STRVAR(groupby_doc,
@@ -301,8 +293,7 @@ _grouper_next(_grouperobject *igo)
newkey = newvalue;
Py_INCREF(newvalue);
} else {
- newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc,
- newvalue, NULL);
+ newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, newvalue, NULL);
if (newkey == NULL) {
Py_DECREF(newvalue);
return NULL;
@@ -330,8 +321,7 @@ _grouper_next(_grouperobject *igo)
static PyObject *
_grouper_reduce(_grouperobject *lz)
{
- return Py_BuildValue("O(OO)", Py_TYPE(lz),
- lz->parent, lz->tgtkey);
+ return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->parent, lz->tgtkey);
}
static PyMethodDef _grouper_methods[] = {
@@ -364,7 +354,7 @@ static PyTypeObject _grouper_type = {
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
- (traverseproc)_grouper_traverse,/* tp_traverse */
+ (traverseproc)_grouper_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
@@ -385,8 +375,7 @@ static PyTypeObject _grouper_type = {
};
-
-/* tee object and with supporting function and objects ***************/
+/* tee object and with supporting function and objects ***********************/
/* The teedataobject pre-allocates space for LINKCELLS number of objects.
To help the object fit neatly inside cache lines (space for 16 to 32
@@ -401,7 +390,7 @@ static PyTypeObject _grouper_type = {
typedef struct {
PyObject_HEAD
PyObject *it;
- int numread; /* 0 <= numread <= LINKCELLS */
+ int numread; /* 0 <= numread <= LINKCELLS */
PyObject *nextlink;
PyObject *(values[LINKCELLS]);
} teedataobject;
@@ -409,7 +398,7 @@ typedef struct {
typedef struct {
PyObject_HEAD
teedataobject *dataobj;
- int index; /* 0 <= index <= LINKCELLS */
+ int index; /* 0 <= index <= LINKCELLS */
PyObject *weakreflist;
} teeobject;
@@ -466,6 +455,7 @@ static int
teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg)
{
int i;
+
Py_VISIT(tdo->it);
for (i = 0; i < tdo->numread; i++)
Py_VISIT(tdo->values[i]);
@@ -515,6 +505,7 @@ teedataobject_reduce(teedataobject *tdo)
int i;
/* create a temporary list of already iterated values */
PyObject *values = PyList_New(tdo->numread);
+
if (!values)
return NULL;
for (i=0 ; i<tdo->numread ; i++) {
@@ -582,7 +573,7 @@ static PyMethodDef teedataobject_methods[] = {
PyDoc_STRVAR(teedataobject_doc, "Data container common to multiple tee objects.");
static PyTypeObject teedataobject_type = {
- PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */
+ PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */
"itertools._tee_dataobject", /* tp_name */
sizeof(teedataobject), /* tp_basicsize */
0, /* tp_itemsize */
@@ -602,7 +593,7 @@ static PyTypeObject teedataobject_type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
teedataobject_doc, /* tp_doc */
(traverseproc)teedataobject_traverse, /* tp_traverse */
(inquiry)teedataobject_clear, /* tp_clear */
@@ -762,9 +753,9 @@ PyDoc_STRVAR(teeobject_doc,
"Iterator wrapped to make it copyable");
static PyMethodDef tee_methods[] = {
- {"__copy__", (PyCFunction)tee_copy, METH_NOARGS, teecopy_doc},
- {"__reduce__", (PyCFunction)tee_reduce, METH_NOARGS, reduce_doc},
- {"__setstate__", (PyCFunction)tee_setstate, METH_O, setstate_doc},
+ {"__copy__", (PyCFunction)tee_copy, METH_NOARGS, teecopy_doc},
+ {"__reduce__", (PyCFunction)tee_reduce, METH_NOARGS, reduce_doc},
+ {"__setstate__", (PyCFunction)tee_setstate, METH_O, setstate_doc},
{NULL, NULL} /* sentinel */
};
@@ -794,7 +785,7 @@ static PyTypeObject tee_type = {
(traverseproc)tee_traverse, /* tp_traverse */
(inquiry)tee_clear, /* tp_clear */
0, /* tp_richcompare */
- offsetof(teeobject, weakreflist), /* tp_weaklistoffset */
+ offsetof(teeobject, weakreflist), /* tp_weaklistoffset */
PyObject_SelfIter, /* tp_iter */
(iternextfunc)tee_next, /* tp_iternext */
tee_methods, /* tp_methods */
@@ -860,12 +851,13 @@ PyDoc_STRVAR(tee_doc,
"tee(iterable, n=2) --> tuple of n independent iterators.");
-/* cycle object **********************************************************/
+/* cycle object **************************************************************/
typedef struct {
PyObject_HEAD
PyObject *it;
PyObject *saved;
+ Py_ssize_t index;
int firstpass;
} cycleobject;
@@ -905,6 +897,7 @@ cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
}
lz->it = it;
lz->saved = saved;
+ lz->index = 0;
lz->firstpass = 0;
return (PyObject *)lz;
@@ -914,15 +907,16 @@ static void
cycle_dealloc(cycleobject *lz)
{
PyObject_GC_UnTrack(lz);
- Py_XDECREF(lz->saved);
Py_XDECREF(lz->it);
+ Py_XDECREF(lz->saved);
Py_TYPE(lz)->tp_free(lz);
}
static int
cycle_traverse(cycleobject *lz, visitproc visit, void *arg)
{
- Py_VISIT(lz->it);
+ if (lz->it)
+ Py_VISIT(lz->it);
Py_VISIT(lz->saved);
return 0;
}
@@ -931,45 +925,56 @@ static PyObject *
cycle_next(cycleobject *lz)
{
PyObject *item;
- PyObject *it;
- PyObject *tmp;
- while (1) {
+ if (lz->it != NULL) {
item = PyIter_Next(lz->it);
if (item != NULL) {
- if (!lz->firstpass && PyList_Append(lz->saved, item)) {
+ if (lz->firstpass)
+ return item;
+ if (PyList_Append(lz->saved, item)) {
Py_DECREF(item);
return NULL;
}
return item;
}
- if (PyErr_Occurred()) {
- if (PyErr_ExceptionMatches(PyExc_StopIteration))
- PyErr_Clear();
- else
- return NULL;
- }
- if (PyList_Size(lz->saved) == 0)
+ /* Note: StopIteration is already cleared by PyIter_Next() */
+ if (PyErr_Occurred())
return NULL;
- it = PyObject_GetIter(lz->saved);
- if (it == NULL)
- return NULL;
- tmp = lz->it;
- lz->it = it;
- lz->firstpass = 1;
- Py_DECREF(tmp);
+ Py_CLEAR(lz->it);
}
+ if (Py_SIZE(lz->saved) == 0)
+ return NULL;
+ item = PyList_GET_ITEM(lz->saved, lz->index);
+ lz->index++;
+ if (lz->index >= Py_SIZE(lz->saved))
+ lz->index = 0;
+ Py_INCREF(item);
+ return item;
}
static PyObject *
cycle_reduce(cycleobject *lz)
{
- /* Create a new cycle with the iterator tuple, then set
- * the saved state on it.
- */
- return Py_BuildValue("O(O)(Oi)", Py_TYPE(lz),
- lz->it, lz->saved, lz->firstpass);
+ /* Create a new cycle with the iterator tuple, then set the saved state */
+ if (lz->it == NULL) {
+ PyObject *it = PyObject_GetIter(lz->saved);
+ if (it == NULL)
+ return NULL;
+ if (lz->index != 0) {
+ _Py_IDENTIFIER(__setstate__);
+ PyObject *res = _PyObject_CallMethodId(it, &PyId___setstate__,
+ "n", lz->index);
+ if (res == NULL) {
+ Py_DECREF(it);
+ return NULL;
+ }
+ Py_DECREF(res);
+ }
+ return Py_BuildValue("O(N)(Oi)", Py_TYPE(lz), it, lz->saved, 1);
}
+ return Py_BuildValue("O(O)(Oi)", Py_TYPE(lz), lz->it, lz->saved,
+ lz->firstpass);
+}
static PyObject *
cycle_setstate(cycleobject *lz, PyObject *state)
@@ -983,9 +988,10 @@ cycle_setstate(cycleobject *lz, PyObject *state)
if (!PyArg_ParseTuple(state, "O!i", &PyList_Type, &saved, &firstpass)) {
return NULL;
}
- Py_XINCREF(saved);
+ Py_INCREF(saved);
Py_XSETREF(lz->saved, saved);
lz->firstpass = firstpass != 0;
+ lz->index = 0;
Py_RETURN_NONE;
}
@@ -1054,7 +1060,7 @@ typedef struct {
PyObject_HEAD
PyObject *func;
PyObject *it;
- long start;
+ long start;
} dropwhileobject;
static PyTypeObject dropwhile_type;
@@ -1144,8 +1150,7 @@ dropwhile_next(dropwhileobject *lz)
static PyObject *
dropwhile_reduce(dropwhileobject *lz)
{
- return Py_BuildValue("O(OO)l", Py_TYPE(lz),
- lz->func, lz->it, lz->start);
+ return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->start);
}
static PyObject *
@@ -1196,13 +1201,13 @@ static PyTypeObject dropwhile_type = {
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
dropwhile_doc, /* tp_doc */
- (traverseproc)dropwhile_traverse, /* tp_traverse */
+ (traverseproc)dropwhile_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
PyObject_SelfIter, /* tp_iter */
(iternextfunc)dropwhile_next, /* tp_iternext */
- dropwhile_methods, /* tp_methods */
+ dropwhile_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
@@ -1223,7 +1228,7 @@ typedef struct {
PyObject_HEAD
PyObject *func;
PyObject *it;
- long stop;
+ long stop;
} takewhileobject;
static PyTypeObject takewhile_type;
@@ -1298,7 +1303,7 @@ takewhile_next(takewhileobject *lz)
}
ok = PyObject_IsTrue(good);
Py_DECREF(good);
- if (ok == 1)
+ if (ok > 0)
return item;
Py_DECREF(item);
if (ok == 0)
@@ -1309,14 +1314,14 @@ takewhile_next(takewhileobject *lz)
static PyObject *
takewhile_reduce(takewhileobject *lz)
{
- return Py_BuildValue("O(OO)l", Py_TYPE(lz),
- lz->func, lz->it, lz->stop);
+ return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->stop);
}
static PyObject *
takewhile_reduce_setstate(takewhileobject *lz, PyObject *state)
{
int stop = PyObject_IsTrue(state);
+
if (stop < 0)
return NULL;
lz->stop = stop;
@@ -1360,7 +1365,7 @@ static PyTypeObject takewhile_type = {
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
takewhile_doc, /* tp_doc */
- (traverseproc)takewhile_traverse, /* tp_traverse */
+ (traverseproc)takewhile_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
@@ -1381,7 +1386,7 @@ static PyTypeObject takewhile_type = {
};
-/* islice object ************************************************************/
+/* islice object *************************************************************/
typedef struct {
PyObject_HEAD
@@ -1417,7 +1422,8 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (PyErr_Occurred())
PyErr_Clear();
PyErr_SetString(PyExc_ValueError,
- "Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize.");
+ "Stop argument for islice() must be None or "
+ "an integer: 0 <= x <= sys.maxsize.");
return NULL;
}
}
@@ -1432,14 +1438,16 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (PyErr_Occurred())
PyErr_Clear();
PyErr_SetString(PyExc_ValueError,
- "Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize.");
+ "Stop argument for islice() must be None or "
+ "an integer: 0 <= x <= sys.maxsize.");
return NULL;
}
}
}
if (start<0 || stop<-1) {
PyErr_SetString(PyExc_ValueError,
- "Indices for islice() must be None or an integer: 0 <= x <= sys.maxsize.");
+ "Indices for islice() must be None or "
+ "an integer: 0 <= x <= sys.maxsize.");
return NULL;
}
@@ -1536,6 +1544,7 @@ islice_reduce(isliceobject *lz)
* then 'setstate' with the next and count
*/
PyObject *stop;
+
if (lz->it == NULL) {
PyObject *empty_list;
PyObject *empty_it;
@@ -1565,6 +1574,7 @@ static PyObject *
islice_setstate(isliceobject *lz, PyObject *state)
{
Py_ssize_t cnt = PyLong_AsSsize_t(state);
+
if (cnt == -1 && PyErr_Occurred())
return NULL;
lz->cnt = cnt;
@@ -1779,7 +1789,7 @@ static PyTypeObject starmap_type = {
};
-/* chain object ************************************************************/
+/* chain object **************************************************************/
typedef struct {
PyObject_HEAD
@@ -1855,32 +1865,32 @@ chain_next(chainobject *lz)
PyObject *item;
if (lz->source == NULL)
- return NULL; /* already stopped */
+ return NULL; /* already stopped */
if (lz->active == NULL) {
PyObject *iterable = PyIter_Next(lz->source);
if (iterable == NULL) {
Py_CLEAR(lz->source);
- return NULL; /* no more input sources */
+ return NULL; /* no more input sources */
}
lz->active = PyObject_GetIter(iterable);
Py_DECREF(iterable);
if (lz->active == NULL) {
Py_CLEAR(lz->source);
- return NULL; /* input not iterable */
+ return NULL; /* input not iterable */
}
}
- item = PyIter_Next(lz->active);
+ item = (*Py_TYPE(lz->active)->tp_iternext)(lz->active);
if (item != NULL)
return item;
if (PyErr_Occurred()) {
if (PyErr_ExceptionMatches(PyExc_StopIteration))
PyErr_Clear();
else
- return NULL; /* input raised an exception */
+ return NULL; /* input raised an exception */
}
Py_CLEAR(lz->active);
- return chain_next(lz); /* recurse and use next active */
+ return chain_next(lz); /* recurse and use next active */
}
static PyObject *
@@ -1940,13 +1950,13 @@ Alternate chain() constructor taking a single iterable argument\n\
that evaluates lazily.");
static PyMethodDef chain_methods[] = {
- {"from_iterable", (PyCFunction) chain_new_from_iterable, METH_O | METH_CLASS,
- chain_from_iterable_doc},
+ {"from_iterable", (PyCFunction) chain_new_from_iterable, METH_O | METH_CLASS,
+ chain_from_iterable_doc},
{"__reduce__", (PyCFunction)chain_reduce, METH_NOARGS,
reduce_doc},
{"__setstate__", (PyCFunction)chain_setstate, METH_O,
setstate_doc},
- {NULL, NULL} /* sentinel */
+ {NULL, NULL} /* sentinel */
};
static PyTypeObject chain_type = {
@@ -1998,10 +2008,10 @@ static PyTypeObject chain_type = {
typedef struct {
PyObject_HEAD
- PyObject *pools; /* tuple of pool tuples */
- Py_ssize_t *indices; /* one index per pool */
- PyObject *result; /* most recently returned result tuple */
- int stopped; /* set to 1 when the product iterator is exhausted */
+ PyObject *pools; /* tuple of pool tuples */
+ Py_ssize_t *indices; /* one index per pool */
+ PyObject *result; /* most recently returned result tuple */
+ int stopped; /* set to 1 when the iterator is exhausted */
} productobject;
static PyTypeObject product_type;
@@ -2020,7 +2030,8 @@ product_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
PyObject *tmpargs = PyTuple_New(0);
if (tmpargs == NULL)
return NULL;
- if (!PyArg_ParseTupleAndKeywords(tmpargs, kwds, "|n:product", kwlist, &repeat)) {
+ if (!PyArg_ParseTupleAndKeywords(tmpargs, kwds, "|n:product",
+ kwlist, &repeat)) {
Py_DECREF(tmpargs);
return NULL;
}
@@ -2309,7 +2320,7 @@ product((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ...");
static PyTypeObject product_type = {
PyVarObject_HEAD_INIT(NULL, 0)
"itertools.product", /* tp_name */
- sizeof(productobject), /* tp_basicsize */
+ sizeof(productobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)product_dealloc, /* tp_dealloc */
@@ -2351,15 +2362,15 @@ static PyTypeObject product_type = {
};
-/* combinations object ************************************************************/
+/* combinations object *******************************************************/
typedef struct {
PyObject_HEAD
- PyObject *pool; /* input converted to a tuple */
- Py_ssize_t *indices; /* one index per result element */
- PyObject *result; /* most recently returned result tuple */
- Py_ssize_t r; /* size of result tuple */
- int stopped; /* set to 1 when the combinations iterator is exhausted */
+ PyObject *pool; /* input converted to a tuple */
+ Py_ssize_t *indices; /* one index per result element */
+ PyObject *result; /* most recently returned result tuple */
+ Py_ssize_t r; /* size of result tuple */
+ int stopped; /* set to 1 when the iterator is exhausted */
} combinationsobject;
static PyTypeObject combinations_type;
@@ -2569,17 +2580,16 @@ combinations_setstate(combinationsobject *lz, PyObject *state)
Py_ssize_t i;
Py_ssize_t n = PyTuple_GET_SIZE(lz->pool);
- if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r)
- {
+ if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r) {
PyErr_SetString(PyExc_ValueError, "invalid arguments");
return NULL;
}
- for (i=0; i<lz->r; i++)
- {
+ for (i=0; i<lz->r; i++) {
Py_ssize_t max;
PyObject* indexObject = PyTuple_GET_ITEM(state, i);
Py_ssize_t index = PyLong_AsSsize_t(indexObject);
+
if (index == -1 && PyErr_Occurred())
return NULL; /* not an integer */
max = i + n - lz->r;
@@ -2665,7 +2675,7 @@ static PyTypeObject combinations_type = {
};
-/* combinations with replacement object *******************************************/
+/* combinations with replacement object **************************************/
/* Equivalent to:
@@ -2695,11 +2705,11 @@ static PyTypeObject combinations_type = {
*/
typedef struct {
PyObject_HEAD
- PyObject *pool; /* input converted to a tuple */
+ PyObject *pool; /* input converted to a tuple */
Py_ssize_t *indices; /* one index per result element */
PyObject *result; /* most recently returned result tuple */
- Py_ssize_t r; /* size of result tuple */
- int stopped; /* set to 1 when the cwr iterator is exhausted */
+ Py_ssize_t r; /* size of result tuple */
+ int stopped; /* set to 1 when the cwr iterator is exhausted */
} cwrobject;
static PyTypeObject cwr_type;
@@ -2716,8 +2726,9 @@ cwr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Py_ssize_t i;
static char *kwargs[] = {"iterable", "r", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:combinations_with_replacement", kwargs,
- &iterable, &r))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds,
+ "On:combinations_with_replacement",
+ kwargs, &iterable, &r))
return NULL;
pool = PySequence_Tuple(iterable);
@@ -2882,8 +2893,7 @@ cwr_reduce(cwrobject *lz)
indices = PyTuple_New(lz->r);
if (!indices)
return NULL;
- for (i=0; i<lz->r; i++)
- {
+ for (i=0; i<lz->r; i++) {
PyObject* index = PyLong_FromSsize_t(lz->indices[i]);
if (!index) {
Py_DECREF(indices);
@@ -2909,10 +2919,10 @@ cwr_setstate(cwrobject *lz, PyObject *state)
}
n = PyTuple_GET_SIZE(lz->pool);
- for (i=0; i<lz->r; i++)
- {
+ for (i=0; i<lz->r; i++) {
PyObject* indexObject = PyTuple_GET_ITEM(state, i);
Py_ssize_t index = PyLong_AsSsize_t(indexObject);
+
if (index < 0 && PyErr_Occurred())
return NULL; /* not an integer */
/* clamp the index */
@@ -2996,7 +3006,7 @@ static PyTypeObject cwr_type = {
};
-/* permutations object ************************************************************
+/* permutations object ********************************************************
def permutations(iterable, r=None):
'permutations(range(3), 2) --> (0,1) (0,2) (1,0) (1,2) (2,0) (2,1)'
@@ -3023,12 +3033,12 @@ def permutations(iterable, r=None):
typedef struct {
PyObject_HEAD
- PyObject *pool; /* input converted to a tuple */
- Py_ssize_t *indices; /* one index per element in the pool */
- Py_ssize_t *cycles; /* one rollover counter per element in the result */
- PyObject *result; /* most recently returned result tuple */
- Py_ssize_t r; /* size of result tuple */
- int stopped; /* set to 1 when the permutations iterator is exhausted */
+ PyObject *pool; /* input converted to a tuple */
+ Py_ssize_t *indices; /* one index per element in the pool */
+ Py_ssize_t *cycles; /* one rollover counter per element in the result */
+ PyObject *result; /* most recently returned result tuple */
+ Py_ssize_t r; /* size of result tuple */
+ int stopped; /* set to 1 when the iterator is exhausted */
} permutationsobject;
static PyTypeObject permutations_type;
@@ -3243,7 +3253,7 @@ permutations_reduce(permutationsobject *po)
indices = PyTuple_New(n);
if (indices == NULL)
goto err;
- for (i=0; i<n; i++){
+ for (i=0; i<n; i++) {
PyObject* index = PyLong_FromSsize_t(po->indices[i]);
if (!index)
goto err;
@@ -3253,8 +3263,7 @@ permutations_reduce(permutationsobject *po)
cycles = PyTuple_New(po->r);
if (cycles == NULL)
goto err;
- for (i=0; i<po->r; i++)
- {
+ for (i=0 ; i<po->r ; i++) {
PyObject* index = PyLong_FromSsize_t(po->cycles[i]);
if (!index)
goto err;
@@ -3287,15 +3296,12 @@ permutations_setstate(permutationsobject *po, PyObject *state)
}
n = PyTuple_GET_SIZE(po->pool);
- if (PyTuple_GET_SIZE(indices) != n ||
- PyTuple_GET_SIZE(cycles) != po->r)
- {
+ if (PyTuple_GET_SIZE(indices) != n || PyTuple_GET_SIZE(cycles) != po->r) {
PyErr_SetString(PyExc_ValueError, "invalid arguments");
return NULL;
}
- for (i=0; i<n; i++)
- {
+ for (i=0; i<n; i++) {
PyObject* indexObject = PyTuple_GET_ITEM(indices, i);
Py_ssize_t index = PyLong_AsSsize_t(indexObject);
if (index < 0 && PyErr_Occurred())
@@ -3308,8 +3314,7 @@ permutations_setstate(permutationsobject *po, PyObject *state)
po->indices[i] = index;
}
- for (i=0; i<po->r; i++)
- {
+ for (i=0; i<po->r; i++) {
PyObject* indexObject = PyTuple_GET_ITEM(cycles, i);
Py_ssize_t index = PyLong_AsSsize_t(indexObject);
if (index < 0 && PyErr_Occurred())
@@ -3350,11 +3355,11 @@ permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)");
static PyTypeObject permutations_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "itertools.permutations", /* tp_name */
+ "itertools.permutations", /* tp_name */
sizeof(permutationsobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
- (destructor)permutations_dealloc, /* tp_dealloc */
+ (destructor)permutations_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
@@ -3371,13 +3376,13 @@ static PyTypeObject permutations_type = {
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
- permutations_doc, /* tp_doc */
- (traverseproc)permutations_traverse, /* tp_traverse */
+ permutations_doc, /* tp_doc */
+ (traverseproc)permutations_traverse,/* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
PyObject_SelfIter, /* tp_iter */
- (iternextfunc)permutations_next, /* tp_iternext */
+ (iternextfunc)permutations_next, /* tp_iternext */
permuations_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
@@ -3388,11 +3393,11 @@ static PyTypeObject permutations_type = {
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
- permutations_new, /* tp_new */
+ permutations_new, /* tp_new */
PyObject_GC_Del, /* tp_free */
};
-/* accumulate object ************************************************************/
+/* accumulate object ********************************************************/
typedef struct {
PyObject_HEAD
@@ -3459,9 +3464,9 @@ accumulate_traverse(accumulateobject *lz, visitproc visit, void *arg)
static PyObject *
accumulate_next(accumulateobject *lz)
{
- PyObject *val, *oldtotal, *newtotal;
+ PyObject *val, *newtotal;
- val = PyIter_Next(lz->it);
+ val = (*Py_TYPE(lz->it)->tp_iternext)(lz->it);
if (val == NULL)
return NULL;
@@ -3479,11 +3484,8 @@ accumulate_next(accumulateobject *lz)
if (newtotal == NULL)
return NULL;
- oldtotal = lz->total;
- lz->total = newtotal;
- Py_DECREF(oldtotal);
-
Py_INCREF(newtotal);
+ Py_SETREF(lz->total, newtotal);
return newtotal;
}
@@ -3510,7 +3512,7 @@ accumulate_reduce(accumulateobject *lz)
return Py_BuildValue("O(OO)O", Py_TYPE(lz),
lz->it, lz->binop?lz->binop:Py_None,
lz->total?lz->total:Py_None);
- }
+}
static PyObject *
accumulate_setstate(accumulateobject *lz, PyObject *state)
@@ -3672,7 +3674,7 @@ compress_next(compressobject *lz)
ok = PyObject_IsTrue(selector);
Py_DECREF(selector);
- if (ok == 1)
+ if (ok > 0)
return datum;
Py_DECREF(datum);
if (ok < 0)
@@ -3685,7 +3687,7 @@ compress_reduce(compressobject *lz)
{
return Py_BuildValue("O(OO)", Py_TYPE(lz),
lz->data, lz->selectors);
- }
+}
static PyMethodDef compress_methods[] = {
{"__reduce__", (PyCFunction)compress_reduce, METH_NOARGS,
@@ -3704,44 +3706,44 @@ static PyTypeObject compress_type = {
PyVarObject_HEAD_INIT(NULL, 0)
"itertools.compress", /* tp_name */
sizeof(compressobject), /* tp_basicsize */
- 0, /* tp_itemsize */
+ 0, /* tp_itemsize */
/* methods */
(destructor)compress_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
- Py_TPFLAGS_BASETYPE, /* tp_flags */
- compress_doc, /* tp_doc */
- (traverseproc)compress_traverse, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- PyObject_SelfIter, /* tp_iter */
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ compress_doc, /* tp_doc */
+ (traverseproc)compress_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
(iternextfunc)compress_next, /* tp_iternext */
- compress_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- compress_new, /* tp_new */
- PyObject_GC_Del, /* tp_free */
+ compress_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ compress_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
};
@@ -3822,8 +3824,7 @@ filterfalse_next(filterfalseobject *lz)
ok = PyObject_IsTrue(item);
} else {
PyObject *good;
- good = PyObject_CallFunctionObjArgs(lz->func,
- item, NULL);
+ good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
if (good == NULL) {
Py_DECREF(item);
return NULL;
@@ -3842,9 +3843,8 @@ filterfalse_next(filterfalseobject *lz)
static PyObject *
filterfalse_reduce(filterfalseobject *lz)
{
- return Py_BuildValue("O(OO)", Py_TYPE(lz),
- lz->func, lz->it);
- }
+ return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it);
+}
static PyMethodDef filterfalse_methods[] = {
{"__reduce__", (PyCFunction)filterfalse_reduce, METH_NOARGS,
@@ -3864,7 +3864,7 @@ static PyTypeObject filterfalse_type = {
sizeof(filterfalseobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
- (destructor)filterfalse_dealloc, /* tp_dealloc */
+ (destructor)filterfalse_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
@@ -3882,7 +3882,7 @@ static PyTypeObject filterfalse_type = {
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
filterfalse_doc, /* tp_doc */
- (traverseproc)filterfalse_traverse, /* tp_traverse */
+ (traverseproc)filterfalse_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
@@ -4134,15 +4134,15 @@ static PyTypeObject count_type = {
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
- Py_TPFLAGS_BASETYPE, /* tp_flags */
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
count_doc, /* tp_doc */
- (traverseproc)count_traverse, /* tp_traverse */
+ (traverseproc)count_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
PyObject_SelfIter, /* tp_iter */
(iternextfunc)count_next, /* tp_iternext */
- count_methods, /* tp_methods */
+ count_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
@@ -4308,9 +4308,7 @@ static PyTypeObject repeat_type = {
PyObject_GC_Del, /* tp_free */
};
-/* ziplongest object ************************************************************/
-
-#include "Python.h"
+/* ziplongest object *********************************************************/
typedef struct {
PyObject_HEAD
@@ -4349,7 +4347,7 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
ittuple = PyTuple_New(tuplesize);
if (ittuple == NULL)
return NULL;
- for (i=0; i < tuplesize; ++i) {
+ for (i=0; i < tuplesize; i++) {
PyObject *item = PyTuple_GET_ITEM(args, i);
PyObject *it = PyObject_GetIter(item);
if (it == NULL) {
@@ -4490,6 +4488,7 @@ zip_longest_reduce(ziplongestobject *lz)
*/
int i;
PyObject *args = PyTuple_New(PyTuple_GET_SIZE(lz->ittuple));
+
if (args == NULL)
return NULL;
for (i=0; i<PyTuple_GET_SIZE(lz->ittuple); i++) {
@@ -4540,7 +4539,7 @@ static PyTypeObject ziplongest_type = {
sizeof(ziplongestobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
- (destructor)zip_longest_dealloc, /* tp_dealloc */
+ (destructor)zip_longest_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
@@ -4557,8 +4556,8 @@ static PyTypeObject ziplongest_type = {
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
- zip_longest_doc, /* tp_doc */
- (traverseproc)zip_longest_traverse, /* tp_traverse */
+ zip_longest_doc, /* tp_doc */
+ (traverseproc)zip_longest_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
@@ -4574,7 +4573,7 @@ static PyTypeObject ziplongest_type = {
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
- zip_longest_new, /* tp_new */
+ zip_longest_new, /* tp_new */
PyObject_GC_Del, /* tp_free */
};