summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2012-10-04 17:53:29 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2012-10-04 17:53:29 (GMT)
commitee329318db90d59a81b8d69a2ad8e32c0aa59cd9 (patch)
tree04fa62ef1d45d8f2533bd3f752b7e75e4f5a1910 /Lib
parent3934b61a1606161e38d53628a8dc7bde19d8767b (diff)
downloadcpython-ee329318db90d59a81b8d69a2ad8e32c0aa59cd9.zip
cpython-ee329318db90d59a81b8d69a2ad8e32c0aa59cd9.tar.gz
cpython-ee329318db90d59a81b8d69a2ad8e32c0aa59cd9.tar.bz2
Issue #16089: Allow ElementTree.TreeBuilder to work again with a non-Element element_factory (fixes a regression in SimpleTAL).
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_xml_etree.py44
-rw-r--r--Lib/xml/etree/ElementTree.py4
2 files changed, 45 insertions, 3 deletions
diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py
index 97d64fc..9cebc3c 100644
--- a/Lib/test/test_xml_etree.py
+++ b/Lib/test/test_xml_etree.py
@@ -1893,10 +1893,23 @@ class TreeBuilderTest(unittest.TestCase):
sample1 = ('<!DOCTYPE html PUBLIC'
' "-//W3C//DTD XHTML 1.0 Transitional//EN"'
' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
- '<html>text</html>')
+ '<html>text<div>subtext</div>tail</html>')
sample2 = '''<toplevel>sometext</toplevel>'''
+ def _check_sample1_element(self, e):
+ self.assertEqual(e.tag, 'html')
+ self.assertEqual(e.text, 'text')
+ self.assertEqual(e.tail, None)
+ self.assertEqual(e.attrib, {})
+ children = list(e)
+ self.assertEqual(len(children), 1)
+ child = children[0]
+ self.assertEqual(child.tag, 'div')
+ self.assertEqual(child.text, 'subtext')
+ self.assertEqual(child.tail, 'tail')
+ self.assertEqual(child.attrib, {})
+
def test_dummy_builder(self):
class BaseDummyBuilder:
def close(self):
@@ -1929,7 +1942,7 @@ class TreeBuilderTest(unittest.TestCase):
parser.feed(self.sample1)
e = parser.close()
- self.assertEqual(e.tag, 'html')
+ self._check_sample1_element(e)
def test_element_factory(self):
lst = []
@@ -1945,6 +1958,33 @@ class TreeBuilderTest(unittest.TestCase):
self.assertEqual(lst, ['toplevel'])
+ def _check_element_factory_class(self, cls):
+ tb = ET.TreeBuilder(element_factory=cls)
+
+ parser = ET.XMLParser(target=tb)
+ parser.feed(self.sample1)
+ e = parser.close()
+ self.assertIsInstance(e, cls)
+ self._check_sample1_element(e)
+
+ def test_element_factory_subclass(self):
+ class MyElement(ET.Element):
+ pass
+ self._check_element_factory_class(MyElement)
+
+ def test_element_factory_pure_python_subclass(self):
+ # Mimick SimpleTAL's behaviour (issue #16089): both versions of
+ # TreeBuilder should be able to cope with a subclass of the
+ # pure Python Element class.
+ base = ET._Element
+ # Not from a C extension
+ self.assertEqual(base.__module__, 'xml.etree.ElementTree')
+ # Force some multiple inheritance with a C class to make things
+ # more interesting.
+ class MyElement(base, ValueError):
+ pass
+ self._check_element_factory_class(MyElement)
+
def test_doctype(self):
class DoctypeParser:
_doctype = None
diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py
index b9d8df6..9553c51 100644
--- a/Lib/xml/etree/ElementTree.py
+++ b/Lib/xml/etree/ElementTree.py
@@ -303,7 +303,9 @@ class Element:
self._children.insert(index, element)
def _assert_is_element(self, e):
- if not isinstance(e, Element):
+ # Need to refer to the actual Python implementation, not the
+ # shadowing C implementation.
+ if not isinstance(e, _Element):
raise TypeError('expected an Element, not %s' % type(e).__name__)
##