bpo-34573: Simplify __reduce__() of set and dict iterators. (GH-9050)
Simplify the pickling of set and dictionary objects iterators by consuming the iterator into a list with PySequence_List.
This commit is contained in:
parent
027664a3d5
commit
6395844e6a
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue