Re: [Python-Dev] [Python-checkins] cpython: Issue #14065: Added cyclic GC support to ET.Element

2012/3/30 eli.bendersky <python-checkins@python.org>:
http://hg.python.org/cpython/rev/0ca32013d77e changeset: 75997:0ca32013d77e parent: 75995:cf2e74e0b7d4 user: Eli Bendersky <eliben@gmail.com> date: Fri Mar 30 16:38:33 2012 +0300 summary: Issue #14065: Added cyclic GC support to ET.Element
files: Lib/test/test_xml_etree.py | 27 ++++++++++- Modules/_elementtree.c | 63 +++++++++++++++++++------ 2 files changed, 74 insertions(+), 16 deletions(-)
diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -14,9 +14,10 @@ # Don't re-import "xml.etree.ElementTree" module in the docstring, # except if the test is specific to the Python implementation.
-import sys +import gc import html import io +import sys import unittest
from test import support @@ -1846,6 +1847,30 @@ self.assertRaises(TypeError, e.extend, [ET.Element('bar'), 'foo']) self.assertRaises(TypeError, e.insert, 0, 'foo')
+ def test_cyclic_gc(self): + class ShowGC: + def __init__(self, flaglist): + self.flaglist = flaglist + def __del__(self): + self.flaglist.append(1)
I think a nicer way to check for cyclic collection is to take a weakref to an object, call the GC, then check to make sure the weakref is broken.
+ + # Test the shortest cycle: lst->element->lst + fl = [] + lst = [ShowGC(fl)] + lst.append(ET.Element('joe', attr=lst)) + del lst + gc.collect()
support.gc_collect() is preferable
+ self.assertEqual(fl, [1]) + + # A longer cycle: lst->e->e2->lst + fl = [] + e = ET.Element('joe') + lst = [ShowGC(fl), e] + e2 = ET.SubElement(e, 'foo', attr=lst) + del lst, e, e2 + gc.collect() + self.assertEqual(fl, [1])
-- Regards, Benjamin

On Fri, Mar 30, 2012 at 21:30, Benjamin Peterson <benjamin@python.org>wrote:
+ def test_cyclic_gc(self): + class ShowGC: + def __init__(self, flaglist): + self.flaglist = flaglist + def __del__(self): + self.flaglist.append(1)
I think a nicer way to check for cyclic collection is to take a weakref to an object, call the GC, then check to make sure the weakref is broken.
+ + # Test the shortest cycle: lst->element->lst + fl = [] + lst = [ShowGC(fl)] + lst.append(ET.Element('joe', attr=lst)) + del lst + gc.collect()
support.gc_collect() is preferable
+ self.assertEqual(fl, [1]) + + # A longer cycle: lst->e->e2->lst + fl = [] + e = ET.Element('joe') + lst = [ShowGC(fl), e] + e2 = ET.SubElement(e, 'foo', attr=lst) + del lst, e, e2 + gc.collect() + self.assertEqual(fl, [1])
Thanks for the insights, Benjamin. I'll explore these alternatives and will submit a fix. Eli
participants (2)
-
Benjamin Peterson
-
Eli Bendersky