diff -r 136adbcefa5f Modules/_collectionsmodule.c --- a/Modules/_collectionsmodule.c Sun Jan 03 18:00:31 2016 -0800 +++ b/Modules/_collectionsmodule.c Tue Jan 05 19:27:20 2016 +0200 @@ -1293,7 +1293,7 @@ deque_traverse(dequeobject *deque, visit static PyObject * deque_reduce(dequeobject *deque) { - PyObject *dict, *result, *aslist; + PyObject *dict, *result, *aslist, *args; _Py_IDENTIFIER(__dict__); dict = _PyObject_GetAttrId((PyObject *)deque, &PyId___dict__); @@ -1304,19 +1304,26 @@ deque_reduce(dequeobject *deque) Py_XDECREF(dict); return NULL; } - if (dict == NULL) { - if (deque->maxlen < 0) - result = Py_BuildValue("O(O)", Py_TYPE(deque), aslist); + if (deque->maxlen < 0) + if (PyList_GET_SIZE(aslist) == 0) + args = PyTuple_New(0); else - result = Py_BuildValue("O(On)", Py_TYPE(deque), aslist, deque->maxlen); - } else { - if (deque->maxlen < 0) - result = Py_BuildValue("O(OO)O", Py_TYPE(deque), aslist, Py_None, dict); + args = PyTuple_Pack(1, aslist); + else + if (PyList_GET_SIZE(aslist) == 0) + args = Py_BuildValue("()n", deque->maxlen); else - result = Py_BuildValue("O(On)O", Py_TYPE(deque), aslist, deque->maxlen, dict); + args = Py_BuildValue("On", aslist, deque->maxlen); + Py_DECREF(aslist); + if (args == NULL) { + Py_XDECREF(dict); + return NULL; } + if (dict == NULL) + result = Py_BuildValue("ON", Py_TYPE(deque), args); + else + result = Py_BuildValue("ONO", Py_TYPE(deque), args, dict); Py_XDECREF(dict); - Py_DECREF(aslist); return result; } @@ -1739,6 +1746,10 @@ 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 136adbcefa5f Modules/arraymodule.c --- a/Modules/arraymodule.c Sun Jan 03 18:00:31 2016 -0800 +++ b/Modules/arraymodule.c Tue Jan 05 19:27:20 2016 +0200 @@ -2906,8 +2906,12 @@ 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 136adbcefa5f Modules/itertoolsmodule.c --- a/Modules/itertoolsmodule.c Sun Jan 03 18:00:31 2016 -0800 +++ b/Modules/itertoolsmodule.c Tue Jan 05 19:27:20 2016 +0200 @@ -960,10 +960,12 @@ 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 +1048,7 @@ typedef struct { PyObject_HEAD PyObject *func; PyObject *it; - long start; + int start; } dropwhileobject; static PyTypeObject dropwhile_type; @@ -1113,7 +1115,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 +1138,9 @@ 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 +1218,7 @@ typedef struct { PyObject_HEAD PyObject *func; PyObject *it; - long stop; + int stop; } takewhileobject; static PyTypeObject takewhile_type; @@ -1300,7 +1304,9 @@ 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 * @@ -1531,18 +1537,8 @@ 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); - } + if (lz->it == NULL) + return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter")); if (lz->stop == -1) { stop = Py_None; Py_INCREF(stop); @@ -1551,6 +1547,19 @@ 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,9 +3473,10 @@ accumulate_next(accumulateobject *lz) static PyObject * 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); + PyObject *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 * @@ -4034,6 +4044,8 @@ count_reduce(countobject *lz) { 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 136adbcefa5f Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Sun Jan 03 18:00:31 2016 -0800 +++ b/Objects/bytearrayobject.c Tue Jan 05 19:27:20 2016 +0200 @@ -2838,23 +2838,16 @@ 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 +3129,12 @@ 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 136adbcefa5f Objects/bytesobject.c --- a/Objects/bytesobject.c Sun Jan 03 18:00:31 2016 -0800 +++ b/Objects/bytesobject.c Tue Jan 05 19:27:20 2016 +0200 @@ -3816,15 +3816,12 @@ 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 136adbcefa5f Objects/enumobject.c --- a/Objects/enumobject.c Sun Jan 03 18:00:31 2016 -0800 +++ b/Objects/enumobject.c Tue Jan 05 19:27:20 2016 +0200 @@ -163,6 +163,8 @@ enum_reduce(enumobject *en) { if (en->en_longindex != NULL) return Py_BuildValue("O(OO)", Py_TYPE(en), en->en_sit, en->en_longindex); + else if (en->en_index == 0) + return Py_BuildValue("O(O)", Py_TYPE(en), en->en_sit); else return Py_BuildValue("O(On)", Py_TYPE(en), en->en_sit, en->en_index); } diff -r 136adbcefa5f Objects/iterobject.c --- a/Objects/iterobject.c Sun Jan 03 18:00:31 2016 -0800 +++ b/Objects/iterobject.c Tue Jan 05 19:27:20 2016 +0200 @@ -101,11 +101,12 @@ 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 136adbcefa5f Objects/listobject.c --- a/Objects/listobject.c Sun Jan 03 18:00:31 2016 -0800 +++ b/Objects/listobject.c Tue Jan 05 19:27:20 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,13 @@ 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); - } - /* empty iterator, create an empty list */ - list = PyList_New(0); - if (list == NULL) - return NULL; - return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list); + PyObject *func; + if (!seq) + return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter")); + 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 136adbcefa5f Objects/sliceobject.c --- a/Objects/sliceobject.c Sun Jan 03 18:00:31 2016 -0800 +++ b/Objects/sliceobject.c Tue Jan 05 19:27:20 2016 +0200 @@ -515,6 +515,11 @@ 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 136adbcefa5f Objects/tupleobject.c --- a/Objects/tupleobject.c Sun Jan 03 18:00:31 2016 -0800 +++ b/Objects/tupleobject.c Tue Jan 05 19:27:20 2016 +0200 @@ -980,11 +980,12 @@ 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 136adbcefa5f Objects/unicodeobject.c --- a/Objects/unicodeobject.c Sun Jan 03 18:00:31 2016 -0800 +++ b/Objects/unicodeobject.c Tue Jan 05 19:27:20 2016 +0200 @@ -15414,15 +15414,12 @@ 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.");