diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py index 270b9d6da8e7b9..7063e919b82dcd 100644 --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -1,4 +1,5 @@ # xml.etree test for cElementTree +import gc import io import struct from test import support @@ -203,6 +204,23 @@ def test_disallow_instantiation(self): iter_type = type(root.iter()) support.check_disallow_instantiation(self, iter_type) + def test_tree_builder_stack(self): + builder = cET.TreeBuilder() + for x in range(10): + builder.start("a", {}) + for x in range(10): + builder.end("a") + root = builder.close() + + # Find the internal TreeBuilder stack list using gc.get_referrers() + for ref in gc.get_referrers(root[0]): + if isinstance(ref, list): + # Check that the list doesn't contain NULL items (gh-146056) + repr(ref) + break + else: + self.fail("failed to find TreeBuilder stack list") + @unittest.skipUnless(cET, 'requires _elementtree') class TestAliasWorking(unittest.TestCase): diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index e0bc69c5fe22f8..b961a96832a392 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -2431,7 +2431,7 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) t->element_factory = NULL; t->comment_factory = NULL; t->pi_factory = NULL; - t->stack = PyList_New(20); + t->stack = PyList_New(0); if (!t->stack) { Py_DECREF(t->this); Py_DECREF(t->last); @@ -2856,9 +2856,9 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag) item = self->last; self->last = Py_NewRef(self->this); - Py_XSETREF(self->last_for_tail, self->last); + Py_XSETREF(self->last_for_tail, Py_NewRef(self->last)); self->index--; - self->this = Py_NewRef(PyList_GET_ITEM(self->stack, self->index)); + Py_SETREF(self->this, Py_NewRef(PyList_GET_ITEM(self->stack, self->index))); Py_DECREF(item); if (treebuilder_append_event(self, self->end_event_obj, self->last) < 0)