diff -r a8589d88deb4 Modules/_collectionsmodule.c --- a/Modules/_collectionsmodule.c Sun Mar 06 15:03:47 2016 +0200 +++ b/Modules/_collectionsmodule.c Sun Mar 06 16:47:55 2016 +0200 @@ -1742,6 +1742,12 @@ PyDoc_STRVAR(length_hint_doc, "Private m static PyObject * dequeiter_reduce(dequeiterobject *it) { + if (it->deque == NULL) { + return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter")); + } + if (it->counter == Py_SIZE(it->deque)) { + return Py_BuildValue("O(O)", Py_TYPE(it), it->deque); + } return Py_BuildValue("O(On)", Py_TYPE(it), it->deque, Py_SIZE(it->deque) - it->counter); } diff -r a8589d88deb4 Modules/arraymodule.c --- a/Modules/arraymodule.c Sun Mar 06 15:03:47 2016 +0200 +++ b/Modules/arraymodule.c Sun Mar 06 16:47:55 2016 +0200 @@ -2906,8 +2906,14 @@ static PyObject * array_arrayiterator___reduce___impl(arrayiterobject *self) /*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a]*/ { - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - self->ao, self->index); + PyObject *func = _PyObject_GetBuiltin("iter"); + if (self->ao == NULL) { + return Py_BuildValue("N(())", func); + } + if (self->index == 0) { + return Py_BuildValue("N(O)", func, self->ao); + } + return Py_BuildValue("N(O)n", func, self->ao, self->index); } /*[clinic input] diff -r a8589d88deb4 Modules/itertoolsmodule.c --- a/Modules/itertoolsmodule.c Sun Mar 06 15:03:47 2016 +0200 +++ b/Modules/itertoolsmodule.c Sun Mar 06 16:47:55 2016 +0200 @@ -960,10 +960,13 @@ cycle_reduce(cycleobject *lz) } Py_DECREF(res); } - return Py_BuildValue("O(N)(Oi)", Py_TYPE(lz), it, lz->saved, 1); + return Py_BuildValue("O(N)(OO)", Py_TYPE(lz), it, lz->saved, Py_True); } - return Py_BuildValue("O(O)(Oi)", Py_TYPE(lz), lz->it, lz->saved, - lz->firstpass); + if (!lz->firstpass && PyList_GET_SIZE(lz->saved) == 0) { + return Py_BuildValue("O(O)", Py_TYPE(lz), lz->it); + } + return Py_BuildValue("O(O)(OO)", Py_TYPE(lz), lz->it, lz->saved, + lz->firstpass ? Py_True : Py_False); } static PyObject * @@ -1046,7 +1049,7 @@ typedef struct { PyObject_HEAD PyObject *func; PyObject *it; - long start; + int start; } dropwhileobject; static PyTypeObject dropwhile_type; @@ -1113,7 +1116,7 @@ dropwhile_next(dropwhileobject *lz) item = iternext(it); if (item == NULL) return NULL; - if (lz->start == 1) + if (lz->start) return item; good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); @@ -1136,7 +1139,10 @@ 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); + if (!lz->start) { + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); + } + return Py_BuildValue("O(OO)O", Py_TYPE(lz), lz->func, lz->it, Py_True); } static PyObject * @@ -1214,7 +1220,7 @@ typedef struct { PyObject_HEAD PyObject *func; PyObject *it; - long stop; + int stop; } takewhileobject; static PyTypeObject takewhile_type; @@ -1300,7 +1306,10 @@ 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); + if (!lz->stop) { + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); + } + return Py_BuildValue("O(OO)O", Py_TYPE(lz), lz->func, lz->it, Py_True); } static PyObject * @@ -1532,16 +1541,7 @@ islice_reduce(isliceobject *lz) PyObject *stop; if (lz->it == NULL) { - PyObject *empty_list; - PyObject *empty_it; - empty_list = PyList_New(0); - if (empty_list == NULL) - return NULL; - empty_it = PyObject_GetIter(empty_list); - Py_DECREF(empty_list); - if (empty_it == NULL) - return NULL; - return Py_BuildValue("O(Nn)n", Py_TYPE(lz), empty_it, 0, 0); + return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter")); } if (lz->stop == -1) { stop = Py_None; @@ -1551,6 +1551,22 @@ islice_reduce(isliceobject *lz) if (stop == NULL) return NULL; } + if (lz->step == 1) { + if (lz->next == 0) { + return Py_BuildValue("O(ON)", Py_TYPE(lz), + lz->it, stop); + } + if (lz->cnt == 0) { + return Py_BuildValue("O(OnN)", Py_TYPE(lz), + lz->it, lz->next, stop); + } + return Py_BuildValue("O(OnN)n", Py_TYPE(lz), + lz->it, lz->next, stop, lz->cnt); + } + if (lz->cnt == 0) { + return Py_BuildValue("O(OnNn)", Py_TYPE(lz), + lz->it, lz->next, stop, lz->step); + } return Py_BuildValue("O(OnNn)n", Py_TYPE(lz), lz->it, lz->next, stop, lz->step, lz->cnt); @@ -3464,6 +3480,8 @@ accumulate_next(accumulateobject *lz) static PyObject * accumulate_reduce(accumulateobject *lz) { + PyObject *state; + if (lz->total == Py_None) { PyObject *it; @@ -3481,9 +3499,12 @@ accumulate_reduce(accumulateobject *lz) return NULL; return Py_BuildValue("O(NiO)", &islice_type, it, 1, Py_None); } - return Py_BuildValue("O(OO)O", Py_TYPE(lz), - lz->it, lz->binop?lz->binop:Py_None, - lz->total?lz->total:Py_None); + + state = lz->total ? lz->total : Py_None; + if (!lz->binop) { + return Py_BuildValue("O(O)O", Py_TYPE(lz), lz->it, state); + } + return Py_BuildValue("O(OO)O", Py_TYPE(lz), lz->it, lz->binop, state); } static PyObject * @@ -4049,8 +4070,12 @@ count_repr(countobject *lz) static PyObject * count_reduce(countobject *lz) { - if (lz->cnt == PY_SSIZE_T_MAX) + if (lz->cnt == PY_SSIZE_T_MAX) { return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step); + } + if (lz->cnt == 0) { + return Py_BuildValue("O()", Py_TYPE(lz)); + } return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt); } diff -r a8589d88deb4 Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Sun Mar 06 15:03:47 2016 +0200 +++ b/Objects/bytearrayobject.c Sun Mar 06 16:47:55 2016 +0200 @@ -2838,23 +2838,17 @@ static PyObject * } buf = PyByteArray_AS_STRING(self); + if (!Py_SIZE(self)) { + return Py_BuildValue("(O()N)", Py_TYPE(self), dict); + } if (proto < 3) { /* use str based reduction for backwards compatibility with Python 2.x */ - PyObject *latin1; - if (Py_SIZE(self)) - latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL); - else - latin1 = PyUnicode_FromString(""); + PyObject *latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL); return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict); } else { /* use more efficient byte based reduction */ - if (Py_SIZE(self)) { - return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict); - } - else { - return Py_BuildValue("(O()N)", Py_TYPE(self), dict); - } + return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict); } } @@ -3136,15 +3130,14 @@ PyDoc_STRVAR(length_hint_doc, static PyObject * bytearrayiter_reduce(bytesiterobject *it) { - if (it->it_seq != NULL) { - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - it->it_seq, it->it_index); - } else { - PyObject *u = PyUnicode_FromUnicode(NULL, 0); - if (u == NULL) - return NULL; - return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u); + PyObject *func = _PyObject_GetBuiltin("iter"); + if (it->it_seq == NULL) { + return Py_BuildValue("N(())", func); } + if (it->it_index == 0) { + return Py_BuildValue("N(O)", func, it->it_seq); + } + return Py_BuildValue("N(O)n", func, it->it_seq, it->it_index); } static PyObject * diff -r a8589d88deb4 Objects/bytesobject.c --- a/Objects/bytesobject.c Sun Mar 06 15:03:47 2016 +0200 +++ b/Objects/bytesobject.c Sun Mar 06 16:47:55 2016 +0200 @@ -3816,15 +3816,14 @@ PyDoc_STRVAR(length_hint_doc, static PyObject * striter_reduce(striterobject *it) { - if (it->it_seq != NULL) { - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - it->it_seq, it->it_index); - } else { - PyObject *u = PyUnicode_FromUnicode(NULL, 0); - if (u == NULL) - return NULL; - return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u); + PyObject *func = _PyObject_GetBuiltin("iter"); + if (it->it_seq == NULL) { + return Py_BuildValue("N(())", func); } + if (it->it_index == 0) { + return Py_BuildValue("N(O)", func, it->it_seq); + } + return Py_BuildValue("N(O)n", func, it->it_seq, it->it_index); } PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); diff -r a8589d88deb4 Objects/enumobject.c --- a/Objects/enumobject.c Sun Mar 06 15:03:47 2016 +0200 +++ b/Objects/enumobject.c Sun Mar 06 16:47:55 2016 +0200 @@ -161,10 +161,13 @@ enum_next(enumobject *en) static PyObject * enum_reduce(enumobject *en) { - if (en->en_longindex != NULL) + if (en->en_longindex != NULL) { return Py_BuildValue("O(OO)", Py_TYPE(en), en->en_sit, en->en_longindex); - else - return Py_BuildValue("O(On)", Py_TYPE(en), en->en_sit, en->en_index); + } + if (en->en_index == 0) { + return Py_BuildValue("O(O)", Py_TYPE(en), en->en_sit); + } + return Py_BuildValue("O(On)", Py_TYPE(en), en->en_sit, en->en_index); } PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); diff -r a8589d88deb4 Objects/iterobject.c --- a/Objects/iterobject.c Sun Mar 06 15:03:47 2016 +0200 +++ b/Objects/iterobject.c Sun Mar 06 16:47:55 2016 +0200 @@ -101,11 +101,14 @@ PyDoc_STRVAR(length_hint_doc, "Private m static PyObject * iter_reduce(seqiterobject *it) { - if (it->it_seq != NULL) - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - it->it_seq, it->it_index); - else - return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter")); + PyObject *func = _PyObject_GetBuiltin("iter"); + if (it->it_seq == NULL) { + return Py_BuildValue("N(())", func); + } + if (it->it_index == 0) { + return Py_BuildValue("N(O)", func, it->it_seq); + } + return Py_BuildValue("N(O)n", func, it->it_seq, it->it_index); } PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); diff -r a8589d88deb4 Objects/listobject.c --- a/Objects/listobject.c Sun Mar 06 15:03:47 2016 +0200 +++ b/Objects/listobject.c Sun Mar 06 16:47:55 2016 +0200 @@ -2674,7 +2674,7 @@ static void listiter_dealloc(listiterobj static int listiter_traverse(listiterobject *, visitproc, void *); static PyObject *listiter_next(listiterobject *); static PyObject *listiter_len(listiterobject *); -static PyObject *listiter_reduce_general(void *_it, int forward); +static PyObject *listiter_reduce_general(PyListObject *, Py_ssize_t, int); static PyObject *listiter_reduce(listiterobject *); static PyObject *listiter_setstate(listiterobject *, PyObject *state); @@ -2796,7 +2796,7 @@ listiter_len(listiterobject *it) static PyObject * listiter_reduce(listiterobject *it) { - return listiter_reduce_general(it, 1); + return listiter_reduce_general(it->it_seq, it->it_index, 1); } static PyObject * @@ -2935,7 +2935,7 @@ listreviter_len(listreviterobject *it) static PyObject * listreviter_reduce(listreviterobject *it) { - return listiter_reduce_general(it, 0); + return listiter_reduce_general(it->it_seq, it->it_index, 0); } static PyObject * @@ -2957,25 +2957,15 @@ listreviter_setstate(listreviterobject * /* common pickling support */ static PyObject * -listiter_reduce_general(void *_it, int forward) +listiter_reduce_general(PyListObject *seq, Py_ssize_t index, int forward) { - PyObject *list; - - /* the objects are not the same, index is of different types! */ - if (forward) { - listiterobject *it = (listiterobject *)_it; - if (it->it_seq) - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - it->it_seq, it->it_index); - } else { - listreviterobject *it = (listreviterobject *)_it; - if (it->it_seq) - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("reversed"), - it->it_seq, it->it_index); + PyObject *func; + if (!seq) { + return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter")); } - /* empty iterator, create an empty list */ - list = PyList_New(0); - if (list == NULL) - return NULL; - return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list); + func = _PyObject_GetBuiltin(forward ? "iter" : "reversed"); + if (index == (forward ? 0 : PyList_GET_SIZE(seq) - 1)) { + return Py_BuildValue("N(O)", func, seq); + } + return Py_BuildValue("N(O)n", func, seq, index); } diff -r a8589d88deb4 Objects/sliceobject.c --- a/Objects/sliceobject.c Sun Mar 06 15:03:47 2016 +0200 +++ b/Objects/sliceobject.c Sun Mar 06 16:47:55 2016 +0200 @@ -515,6 +515,12 @@ handling of normal slices."); static PyObject * slice_reduce(PySliceObject* self) { + if (self->step == Py_None) { + if (self->start == Py_None) { + return Py_BuildValue("O(O)", Py_TYPE(self), self->stop); + } + return Py_BuildValue("O(OO)", Py_TYPE(self), self->start, self->stop); + } return Py_BuildValue("O(OOO)", Py_TYPE(self), self->start, self->stop, self->step); } diff -r a8589d88deb4 Objects/tupleobject.c --- a/Objects/tupleobject.c Sun Mar 06 15:03:47 2016 +0200 +++ b/Objects/tupleobject.c Sun Mar 06 16:47:55 2016 +0200 @@ -980,11 +980,14 @@ PyDoc_STRVAR(length_hint_doc, "Private m static PyObject * tupleiter_reduce(tupleiterobject *it) { - if (it->it_seq) - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - it->it_seq, it->it_index); - else - return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter")); + PyObject *func = _PyObject_GetBuiltin("iter"); + if (it->it_seq == NULL) { + return Py_BuildValue("N(())", func); + } + if (it->it_index == 0) { + return Py_BuildValue("N(O)", func, it->it_seq); + } + return Py_BuildValue("N(O)n", func, it->it_seq, it->it_index); } static PyObject * diff -r a8589d88deb4 Objects/unicodeobject.c --- a/Objects/unicodeobject.c Sun Mar 06 15:03:47 2016 +0200 +++ b/Objects/unicodeobject.c Sun Mar 06 16:47:55 2016 +0200 @@ -15420,15 +15420,14 @@ PyDoc_STRVAR(length_hint_doc, "Private m static PyObject * unicodeiter_reduce(unicodeiterobject *it) { - if (it->it_seq != NULL) { - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - it->it_seq, it->it_index); - } else { - PyObject *u = PyUnicode_FromUnicode(NULL, 0); - if (u == NULL) - return NULL; - return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u); - } + PyObject *func = _PyObject_GetBuiltin("iter"); + if (it->it_seq == NULL) { + return Py_BuildValue("N(())", func); + } + if (it->it_index == 0) { + return Py_BuildValue("N(O)", func, it->it_seq); + } + return Py_BuildValue("N(O)n", func, it->it_seq, it->it_index); } PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");