[issue16076] xml.etree.ElementTree.Element is no longer pickleable

Daniel Shahaf report at bugs.python.org
Fri Jan 11 12:07:02 CET 2013


Daniel Shahaf added the comment:

Ezio Melotti wrote on Fri, Jan 11, 2013 at 08:44:43 +0000:
> >>> ### one ref leaked for every child in __setstate__:
> >>> e2.__setstate__(p2)
> [76810 refs]
> >>> e2.__setstate__(p2)
> [76813 refs]
> >>> e2.__setstate__(p2)
> [76816 refs]
> 
> I'm not working on this anymore now, so someone more familiar with the
> code can take a look, see if my patch is correct, and fix the
> remaining leaks.
> 

Thank for narrowing it down so much.  Attached patch incorporates your
getstate fix and a fix for setstate.  It passes the -R 3:2 tests.

----------
Added file: http://bugs.python.org/file28691/memleak-v1.diff

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue16076>
_______________________________________
-------------- next part --------------
diff -r 6eae84170536 Modules/_elementtree.c
--- a/Modules/_elementtree.c    Fri Jan 11 10:49:43 2013 +0100
+++ b/Modules/_elementtree.c    Fri Jan 11 10:56:05 2013 +0000
@@ -859,8 +859,10 @@ element_getstate(ElementObject *self)
                                      PICKLED_ATTRIB, self->extra->attrib,
                                      PICKLED_TEXT, self->text,
                                      PICKLED_TAIL, self->tail);
-    if (instancedict)
+    if (instancedict) {
+        Py_DECREF(children);
         return instancedict;
+    }
     else {
         for (i = 0; i < PyList_GET_SIZE(children); i++)
             Py_DECREF(PyList_GET_ITEM(children, i));
@@ -884,25 +886,17 @@ element_setstate_from_attributes(Element
         PyErr_SetString(PyExc_TypeError, "tag may not be NULL");
         return NULL;
     }
-    if (!text) {
-        Py_INCREF(Py_None);
-        text = Py_None;
-    }
-    if (!tail) {
-        Py_INCREF(Py_None);
-        tail = Py_None;
-    }
 
     Py_CLEAR(self->tag);
     self->tag = tag;
     Py_INCREF(self->tag);
 
     Py_CLEAR(self->text);
-    self->text = text;
+    self->text = text ? text : Py_None;
     Py_INCREF(self->text);
 
     Py_CLEAR(self->tail);
-    self->tail = tail;
+    self->tail = tail ? tail : Py_None;
     Py_INCREF(self->tail);
 
     /* Handle ATTRIB and CHILDREN. */



More information about the Python-bugs-list mailing list