diff options
Diffstat (limited to 'Modules/itertoolsmodule.c')
| -rw-r--r-- | Modules/itertoolsmodule.c | 387 | 
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 */  }; | 
