Skip to content

Commit

Permalink
bpo-34573: Simplify __reduce__() of set and dict iterators. (pythonGH…
Browse files Browse the repository at this point in the history
…-9050)

Simplify the pickling of set and dictionary objects iterators by consuming
the iterator into a list with PySequence_List.
  • Loading branch information
sir-sigurd authored and pablogsal committed Oct 20, 2018
1 parent 027664a commit 6395844
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 59 deletions.
38 changes: 4 additions & 34 deletions Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -3663,44 +3663,14 @@ PyTypeObject PyDictIterItem_Type = {
static PyObject *
dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored))
{
PyObject *list;
dictiterobject tmp;

list = PyList_New(0);
if (!list)
return NULL;

/* copy the itertor state */
tmp = *di;
/* copy the iterator state */
dictiterobject tmp = *di;
Py_XINCREF(tmp.di_dict);

/* iterate the temporary into a list */
for(;;) {
PyObject *element = 0;
if (Py_TYPE(di) == &PyDictIterItem_Type)
element = dictiter_iternextitem(&tmp);
else if (Py_TYPE(di) == &PyDictIterKey_Type)
element = dictiter_iternextkey(&tmp);
else if (Py_TYPE(di) == &PyDictIterValue_Type)
element = dictiter_iternextvalue(&tmp);
else
Py_UNREACHABLE();
if (element) {
if (PyList_Append(list, element)) {
Py_DECREF(element);
Py_DECREF(list);
Py_XDECREF(tmp.di_dict);
return NULL;
}
Py_DECREF(element);
} else
break;
}
PyObject *list = PySequence_List((PyObject*)&tmp);
Py_XDECREF(tmp.di_dict);
/* check for error */
if (tmp.di_dict != NULL) {
/* we have an error */
Py_DECREF(list);
if (list == NULL) {
return NULL;
}
return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Expand Down
28 changes: 3 additions & 25 deletions Objects/setobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -843,36 +843,14 @@ static PyObject *setiter_iternext(setiterobject *si);
static PyObject *
setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
{
PyObject *list;
setiterobject tmp;

list = PyList_New(0);
if (!list)
return NULL;

/* copy the iterator state */
tmp = *si;
setiterobject tmp = *si;
Py_XINCREF(tmp.si_set);

/* iterate the temporary into a list */
for(;;) {
PyObject *element = setiter_iternext(&tmp);
if (element) {
if (PyList_Append(list, element)) {
Py_DECREF(element);
Py_DECREF(list);
Py_XDECREF(tmp.si_set);
return NULL;
}
Py_DECREF(element);
} else
break;
}
PyObject *list = PySequence_List((PyObject*)&tmp);
Py_XDECREF(tmp.si_set);
/* check for error */
if (tmp.si_set != NULL) {
/* we have an error */
Py_DECREF(list);
if (list == NULL) {
return NULL;
}
return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Expand Down

0 comments on commit 6395844

Please sign in to comment.