Bug report
Bug description:
The _elementtree C accelerator's Element.__init__ (element_init) calls create_extra, which allocates a new extra without freeing the previous one. Re-initializing an element that already has children or attributes therefore leaks them; the pure-Python Element.__init__ resets the children, so the two implementations diverge.
Repro (prints three live Elements on the C accelerator, [None, None, None] on pure Python):
import gc, weakref
from _elementtree import Element, SubElement
e = Element('a')
kids = [SubElement(e, 'b') for _ in range(3)]
refs = [weakref.ref(k) for k in kids]
del kids
Element.__init__(e, 'a')
gc.collect()
print([r() for r in refs])
Fix: clear the existing extra at the start of element_init (the file already has clear_extra), matching the pure-Python reset.
CPython versions tested on:
3.13, 3.14, CPython main branch
Operating systems tested on:
macOS
Linked PRs
Bug report
Bug description:
The
_elementtreeC accelerator'sElement.__init__(element_init) callscreate_extra, which allocates a newextrawithout freeing the previous one. Re-initializing an element that already has children or attributes therefore leaks them; the pure-PythonElement.__init__resets the children, so the two implementations diverge.Repro (prints three live Elements on the C accelerator,
[None, None, None]on pure Python):Fix: clear the existing
extraat the start ofelement_init(the file already hasclear_extra), matching the pure-Python reset.CPython versions tested on:
3.13, 3.14, CPython main branch
Operating systems tested on:
macOS
Linked PRs