diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2015-12-21 09:09:48 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2015-12-21 09:09:48 (GMT) |
commit | 66c08d90f6d7e5889a19891a0ef994354b14f172 (patch) | |
tree | 53ef527e4ce8cba37f0f0d753f666cafdbfd0cdf /Lib | |
parent | 0744641668ebf975fa41707ed7eb467c9cac2f67 (diff) | |
download | cpython-66c08d90f6d7e5889a19891a0ef994354b14f172.zip cpython-66c08d90f6d7e5889a19891a0ef994354b14f172.tar.gz cpython-66c08d90f6d7e5889a19891a0ef994354b14f172.tar.bz2 |
Issue #25902: Fixed various refcount issues in ElementTree iteration.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_xml_etree.py | 51 | ||||
-rw-r--r-- | Lib/xml/etree/ElementTree.py | 10 |
2 files changed, 57 insertions, 4 deletions
diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 57d8e4d..358484d 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -1666,6 +1666,57 @@ class BugsTest(unittest.TestCase): ET.register_namespace('test10777', 'http://myuri/') ET.register_namespace('test10777', 'http://myuri/') + def test_lost_text(self): + # Issue #25902: Borrowed text can disappear + class Text: + def __bool__(self): + e.text = 'changed' + return True + + e = ET.Element('tag') + e.text = Text() + i = e.itertext() + t = next(i) + self.assertIsInstance(t, Text) + self.assertIsInstance(e.text, str) + self.assertEqual(e.text, 'changed') + + def test_lost_tail(self): + # Issue #25902: Borrowed tail can disappear + class Text: + def __bool__(self): + e[0].tail = 'changed' + return True + + e = ET.Element('root') + e.append(ET.Element('tag')) + e[0].tail = Text() + i = e.itertext() + t = next(i) + self.assertIsInstance(t, Text) + self.assertIsInstance(e[0].tail, str) + self.assertEqual(e[0].tail, 'changed') + + def test_lost_elem(self): + # Issue #25902: Borrowed element can disappear + class Tag: + def __eq__(self, other): + e[0] = ET.Element('changed') + next(i) + return True + + e = ET.Element('root') + e.append(ET.Element(Tag())) + e.append(ET.Element('tag')) + i = e.iter('tag') + try: + t = next(i) + except ValueError: + self.skipTest('generators are not reentrant') + self.assertIsInstance(t.tag, Tag) + self.assertIsInstance(e[0].tag, str) + self.assertEqual(e[0].tag, 'changed') + # -------------------------------------------------------------------- diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index 62b5d3a..b4e110d 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -428,12 +428,14 @@ class Element: tag = self.tag if not isinstance(tag, str) and tag is not None: return - if self.text: - yield self.text + t = self.text + if t: + yield t for e in self: yield from e.itertext() - if e.tail: - yield e.tail + t = e.tail + if t: + yield t def SubElement(parent, tag, attrib={}, **extra): |