--- /dev/null
+From e5c5cd22d918cd3b196e109a7829dad02d9ef42e Mon Sep 17 00:00:00 2001
+From: Stefan Behnel <stefan_ml@behnel.de>
+Date: Tue, 26 May 2020 11:20:18 +0200
+Subject: [PATCH 1/2] Move some ElementTree compatibility tests over to the
+ etree-only tests since the features were removed in Py3.9.
+
+---
+ src/lxml/tests/test_elementtree.py | 254 +----------------------------
+ src/lxml/tests/test_etree.py | 246 ++++++++++++++++++++++++++++
+ 2 files changed, 252 insertions(+), 248 deletions(-)
+
+diff --git a/src/lxml/tests/test_elementtree.py b/src/lxml/tests/test_elementtree.py
+index 78d8964d..ec765ee0 100644
+--- a/src/lxml/tests/test_elementtree.py
++++ b/src/lxml/tests/test_elementtree.py
+@@ -130,7 +130,8 @@ class _ETreeTestCaseBase(HelperTestCase):
+ check_method(element.extend)
+ check_method(element.insert)
+ check_method(element.remove)
+- check_method(element.getchildren)
++ # Removed in Py3.9
++ #check_method(element.getchildren)
+ check_method(element.find)
+ check_method(element.iterfind)
+ check_method(element.findall)
+@@ -142,7 +143,8 @@ class _ETreeTestCaseBase(HelperTestCase):
+ check_method(element.items)
+ check_method(element.iter)
+ check_method(element.itertext)
+- check_method(element.getiterator)
++ # Removed in Py3.9
++ #check_method(element.getiterator)
+
+ # These methods return an iterable. See bug 6472.
+
+@@ -1933,28 +1935,6 @@ class _ETreeTestCaseBase(HelperTestCase):
+ a.remove(el)
+ self.assertLess(len(a), 3)
+
+- def test_getchildren(self):
+- Element = self.etree.Element
+- SubElement = self.etree.SubElement
+-
+- a = Element('a')
+- b = SubElement(a, 'b')
+- c = SubElement(a, 'c')
+- d = SubElement(b, 'd')
+- e = SubElement(c, 'e')
+- self.assertXML(
+- _bytes('<a><b><d></d></b><c><e></e></c></a>'),
+- a)
+- self.assertEqual(
+- [b, c],
+- a.getchildren())
+- self.assertEqual(
+- [d],
+- b.getchildren())
+- self.assertEqual(
+- [],
+- d.getchildren())
+-
+ def test_makeelement(self):
+ Element = self.etree.Element
+
+@@ -2010,184 +1990,6 @@ class _ETreeTestCaseBase(HelperTestCase):
+ [None] * 5,
+ [el.tail for el in a.iter()])
+
+- def test_getiterator(self):
+- Element = self.etree.Element
+- SubElement = self.etree.SubElement
+-
+- a = Element('a')
+- b = SubElement(a, 'b')
+- c = SubElement(a, 'c')
+- d = SubElement(b, 'd')
+- e = SubElement(c, 'e')
+-
+- self.assertEqual(
+- [a, b, d, c, e],
+- list(a.getiterator()))
+- self.assertEqual(
+- [d],
+- list(d.getiterator()))
+-
+- def test_getiterator_empty(self):
+- Element = self.etree.Element
+- SubElement = self.etree.SubElement
+-
+- a = Element('a')
+- b = SubElement(a, 'b')
+- c = SubElement(a, 'c')
+- d = SubElement(b, 'd')
+- e = SubElement(c, 'e')
+-
+- self.assertEqual(
+- [],
+- list(a.getiterator('none')))
+- self.assertEqual(
+- [],
+- list(e.getiterator('none')))
+- self.assertEqual(
+- [e],
+- list(e.getiterator()))
+-
+- def test_getiterator_filter(self):
+- Element = self.etree.Element
+- SubElement = self.etree.SubElement
+-
+- a = Element('a')
+- b = SubElement(a, 'b')
+- c = SubElement(a, 'c')
+- d = SubElement(b, 'd')
+- e = SubElement(c, 'e')
+-
+- self.assertEqual(
+- [a],
+- list(a.getiterator('a')))
+- a2 = SubElement(e, 'a')
+- self.assertEqual(
+- [a, a2],
+- list(a.getiterator('a')))
+- self.assertEqual(
+- [a2],
+- list(c.getiterator('a')))
+-
+- def test_getiterator_filter_all(self):
+- Element = self.etree.Element
+- SubElement = self.etree.SubElement
+-
+- a = Element('a')
+- b = SubElement(a, 'b')
+- c = SubElement(a, 'c')
+- d = SubElement(b, 'd')
+- e = SubElement(c, 'e')
+-
+- self.assertEqual(
+- [a, b, d, c, e],
+- list(a.getiterator('*')))
+-
+- def test_getiterator_filter_comment(self):
+- Element = self.etree.Element
+- Comment = self.etree.Comment
+- SubElement = self.etree.SubElement
+-
+- a = Element('a')
+- b = SubElement(a, 'b')
+- comment_b = Comment("TEST-b")
+- b.append(comment_b)
+-
+- self.assertEqual(
+- [comment_b],
+- list(a.getiterator(Comment)))
+-
+- comment_a = Comment("TEST-a")
+- a.append(comment_a)
+-
+- self.assertEqual(
+- [comment_b, comment_a],
+- list(a.getiterator(Comment)))
+-
+- self.assertEqual(
+- [comment_b],
+- list(b.getiterator(Comment)))
+-
+- def test_getiterator_filter_pi(self):
+- Element = self.etree.Element
+- PI = self.etree.ProcessingInstruction
+- SubElement = self.etree.SubElement
+-
+- a = Element('a')
+- b = SubElement(a, 'b')
+- pi_b = PI("TEST-b")
+- b.append(pi_b)
+-
+- self.assertEqual(
+- [pi_b],
+- list(a.getiterator(PI)))
+-
+- pi_a = PI("TEST-a")
+- a.append(pi_a)
+-
+- self.assertEqual(
+- [pi_b, pi_a],
+- list(a.getiterator(PI)))
+-
+- self.assertEqual(
+- [pi_b],
+- list(b.getiterator(PI)))
+-
+- def test_getiterator_with_text(self):
+- Element = self.etree.Element
+- SubElement = self.etree.SubElement
+-
+- a = Element('a')
+- a.text = 'a'
+- b = SubElement(a, 'b')
+- b.text = 'b'
+- b.tail = 'b1'
+- c = SubElement(a, 'c')
+- c.text = 'c'
+- c.tail = 'c1'
+- d = SubElement(b, 'd')
+- d.text = 'd'
+- d.tail = 'd1'
+- e = SubElement(c, 'e')
+- e.text = 'e'
+- e.tail = 'e1'
+-
+- self.assertEqual(
+- [a, b, d, c, e],
+- list(a.getiterator()))
+- #self.assertEqual(
+- # [d],
+- # list(d.getiterator()))
+-
+- def test_getiterator_filter_with_text(self):
+- Element = self.etree.Element
+- SubElement = self.etree.SubElement
+-
+- a = Element('a')
+- a.text = 'a'
+- b = SubElement(a, 'b')
+- b.text = 'b'
+- b.tail = 'b1'
+- c = SubElement(a, 'c')
+- c.text = 'c'
+- c.tail = 'c1'
+- d = SubElement(b, 'd')
+- d.text = 'd'
+- d.tail = 'd1'
+- e = SubElement(c, 'e')
+- e.text = 'e'
+- e.tail = 'e1'
+-
+- self.assertEqual(
+- [a],
+- list(a.getiterator('a')))
+- a2 = SubElement(e, 'a')
+- self.assertEqual(
+- [a, a2],
+- list(a.getiterator('a')))
+- self.assertEqual(
+- [a2],
+- list(e.getiterator('a')))
+-
+ def test_getslice(self):
+ Element = self.etree.Element
+ SubElement = self.etree.SubElement
+@@ -2710,41 +2512,6 @@ class _ETreeTestCaseBase(HelperTestCase):
+ self.assertEqual('A2',
+ a.tail)
+
+- def test_elementtree_getiterator(self):
+- Element = self.etree.Element
+- SubElement = self.etree.SubElement
+- ElementTree = self.etree.ElementTree
+-
+- a = Element('a')
+- b = SubElement(a, 'b')
+- c = SubElement(a, 'c')
+- d = SubElement(b, 'd')
+- e = SubElement(c, 'e')
+- t = ElementTree(element=a)
+-
+- self.assertEqual(
+- [a, b, d, c, e],
+- list(t.getiterator()))
+-
+- def test_elementtree_getiterator_filter(self):
+- Element = self.etree.Element
+- SubElement = self.etree.SubElement
+- ElementTree = self.etree.ElementTree
+- a = Element('a')
+- b = SubElement(a, 'b')
+- c = SubElement(a, 'c')
+- d = SubElement(b, 'd')
+- e = SubElement(c, 'e')
+- t = ElementTree(element=a)
+-
+- self.assertEqual(
+- [a],
+- list(t.getiterator('a')))
+- a2 = SubElement(e, 'a')
+- self.assertEqual(
+- [a, a2],
+- list(t.getiterator('a')))
+-
+ def test_ns_access(self):
+ ElementTree = self.etree.ElementTree
+ ns = 'http://xml.infrae.com/1'
+@@ -3180,17 +2947,6 @@ class _ETreeTestCaseBase(HelperTestCase):
+ 'value',
+ root[0].get(attr_name))
+
+- def test_iterparse_getiterator(self):
+- iterparse = self.etree.iterparse
+- f = BytesIO('<a><b><d/></b><c/></a>')
+-
+- counts = []
+- for event, elem in iterparse(f):
+- counts.append(len(list(elem.getiterator())))
+- self.assertEqual(
+- [1,2,1,4],
+- counts)
+-
+ def test_iterparse_move_elements(self):
+ iterparse = self.etree.iterparse
+ f = BytesIO('<a><b><d/></b><c/></a>')
+@@ -5119,6 +4875,8 @@ if ElementTree:
+
+ @classmethod
+ def setUpClass(cls):
++ if sys.version_info >= (3, 9):
++ return
+ import warnings
+ # ElementTree warns about getiterator() in recent Pythons
+ warnings.filterwarnings(
+diff --git a/src/lxml/tests/test_etree.py b/src/lxml/tests/test_etree.py
+index 3d8dee1c..56d38e75 100644
+--- a/src/lxml/tests/test_etree.py
++++ b/src/lxml/tests/test_etree.py
+@@ -674,6 +674,17 @@ class ETreeOnlyTestCase(HelperTestCase):
+ parse = self.etree.parse
+ self.assertRaises(TypeError, parse, 'notthere.xml', object())
+
++ def test_iterparse_getiterator(self):
++ iterparse = self.etree.iterparse
++ f = BytesIO('<a><b><d/></b><c/></a>')
++
++ counts = []
++ for event, elem in iterparse(f):
++ counts.append(len(list(elem.getiterator())))
++ self.assertEqual(
++ [1,2,1,4],
++ counts)
++
+ def test_iterparse_tree_comments(self):
+ # ET removes comments
+ iterparse = self.etree.iterparse
+@@ -3027,6 +3038,206 @@ class ETreeOnlyTestCase(HelperTestCase):
+ el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description')
+ self.assertEqual({'hha': None}, el.nsmap)
+
++ def test_getchildren(self):
++ Element = self.etree.Element
++ SubElement = self.etree.SubElement
++
++ a = Element('a')
++ b = SubElement(a, 'b')
++ c = SubElement(a, 'c')
++ d = SubElement(b, 'd')
++ e = SubElement(c, 'e')
++ self.assertXML(
++ _bytes('<a><b><d></d></b><c><e></e></c></a>'),
++ a)
++ self.assertEqual(
++ [b, c],
++ a.getchildren())
++ self.assertEqual(
++ [d],
++ b.getchildren())
++ self.assertEqual(
++ [],
++ d.getchildren())
++
++ def test_getiterator(self):
++ Element = self.etree.Element
++ SubElement = self.etree.SubElement
++
++ a = Element('a')
++ b = SubElement(a, 'b')
++ c = SubElement(a, 'c')
++ d = SubElement(b, 'd')
++ e = SubElement(c, 'e')
++
++ self.assertEqual(
++ [a, b, d, c, e],
++ list(a.getiterator()))
++ self.assertEqual(
++ [d],
++ list(d.getiterator()))
++
++ def test_getiterator_empty(self):
++ Element = self.etree.Element
++ SubElement = self.etree.SubElement
++
++ a = Element('a')
++ b = SubElement(a, 'b')
++ c = SubElement(a, 'c')
++ d = SubElement(b, 'd')
++ e = SubElement(c, 'e')
++
++ self.assertEqual(
++ [],
++ list(a.getiterator('none')))
++ self.assertEqual(
++ [],
++ list(e.getiterator('none')))
++ self.assertEqual(
++ [e],
++ list(e.getiterator()))
++
++ def test_getiterator_filter(self):
++ Element = self.etree.Element
++ SubElement = self.etree.SubElement
++
++ a = Element('a')
++ b = SubElement(a, 'b')
++ c = SubElement(a, 'c')
++ d = SubElement(b, 'd')
++ e = SubElement(c, 'e')
++
++ self.assertEqual(
++ [a],
++ list(a.getiterator('a')))
++ a2 = SubElement(e, 'a')
++ self.assertEqual(
++ [a, a2],
++ list(a.getiterator('a')))
++ self.assertEqual(
++ [a2],
++ list(c.getiterator('a')))
++
++ def test_getiterator_filter_all(self):
++ Element = self.etree.Element
++ SubElement = self.etree.SubElement
++
++ a = Element('a')
++ b = SubElement(a, 'b')
++ c = SubElement(a, 'c')
++ d = SubElement(b, 'd')
++ e = SubElement(c, 'e')
++
++ self.assertEqual(
++ [a, b, d, c, e],
++ list(a.getiterator('*')))
++
++ def test_getiterator_filter_comment(self):
++ Element = self.etree.Element
++ Comment = self.etree.Comment
++ SubElement = self.etree.SubElement
++
++ a = Element('a')
++ b = SubElement(a, 'b')
++ comment_b = Comment("TEST-b")
++ b.append(comment_b)
++
++ self.assertEqual(
++ [comment_b],
++ list(a.getiterator(Comment)))
++
++ comment_a = Comment("TEST-a")
++ a.append(comment_a)
++
++ self.assertEqual(
++ [comment_b, comment_a],
++ list(a.getiterator(Comment)))
++
++ self.assertEqual(
++ [comment_b],
++ list(b.getiterator(Comment)))
++
++ def test_getiterator_filter_pi(self):
++ Element = self.etree.Element
++ PI = self.etree.ProcessingInstruction
++ SubElement = self.etree.SubElement
++
++ a = Element('a')
++ b = SubElement(a, 'b')
++ pi_b = PI("TEST-b")
++ b.append(pi_b)
++
++ self.assertEqual(
++ [pi_b],
++ list(a.getiterator(PI)))
++
++ pi_a = PI("TEST-a")
++ a.append(pi_a)
++
++ self.assertEqual(
++ [pi_b, pi_a],
++ list(a.getiterator(PI)))
++
++ self.assertEqual(
++ [pi_b],
++ list(b.getiterator(PI)))
++
++ def test_getiterator_with_text(self):
++ Element = self.etree.Element
++ SubElement = self.etree.SubElement
++
++ a = Element('a')
++ a.text = 'a'
++ b = SubElement(a, 'b')
++ b.text = 'b'
++ b.tail = 'b1'
++ c = SubElement(a, 'c')
++ c.text = 'c'
++ c.tail = 'c1'
++ d = SubElement(b, 'd')
++ d.text = 'd'
++ d.tail = 'd1'
++ e = SubElement(c, 'e')
++ e.text = 'e'
++ e.tail = 'e1'
++
++ self.assertEqual(
++ [a, b, d, c, e],
++ list(a.getiterator()))
++ #self.assertEqual(
++ # [d],
++ # list(d.getiterator()))
++
++ def test_getiterator_filter_with_text(self):
++ Element = self.etree.Element
++ SubElement = self.etree.SubElement
++
++ a = Element('a')
++ a.text = 'a'
++ b = SubElement(a, 'b')
++ b.text = 'b'
++ b.tail = 'b1'
++ c = SubElement(a, 'c')
++ c.text = 'c'
++ c.tail = 'c1'
++ d = SubElement(b, 'd')
++ d.text = 'd'
++ d.tail = 'd1'
++ e = SubElement(c, 'e')
++ e.text = 'e'
++ e.tail = 'e1'
++
++ self.assertEqual(
++ [a],
++ list(a.getiterator('a')))
++ a2 = SubElement(e, 'a')
++ self.assertEqual(
++ [a, a2],
++ list(a.getiterator('a')))
++ self.assertEqual(
++ [a2],
++ list(e.getiterator('a')))
++
+ def test_getiterator_filter_multiple(self):
+ Element = self.etree.Element
+ SubElement = self.etree.SubElement
+@@ -3203,6 +3414,41 @@ class ETreeOnlyTestCase(HelperTestCase):
+ [a, b, c],
+ list(a.getiterator('*')))
+
++ def test_elementtree_getiterator(self):
++ Element = self.etree.Element
++ SubElement = self.etree.SubElement
++ ElementTree = self.etree.ElementTree
++
++ a = Element('a')
++ b = SubElement(a, 'b')
++ c = SubElement(a, 'c')
++ d = SubElement(b, 'd')
++ e = SubElement(c, 'e')
++ t = ElementTree(element=a)
++
++ self.assertEqual(
++ [a, b, d, c, e],
++ list(t.getiterator()))
++
++ def test_elementtree_getiterator_filter(self):
++ Element = self.etree.Element
++ SubElement = self.etree.SubElement
++ ElementTree = self.etree.ElementTree
++ a = Element('a')
++ b = SubElement(a, 'b')
++ c = SubElement(a, 'c')
++ d = SubElement(b, 'd')
++ e = SubElement(c, 'e')
++ t = ElementTree(element=a)
++
++ self.assertEqual(
++ [a],
++ list(t.getiterator('a')))
++ a2 = SubElement(e, 'a')
++ self.assertEqual(
++ [a, a2],
++ list(t.getiterator('a')))
++
+ def test_elementtree_getelementpath(self):
+ a = etree.Element("a")
+ b = etree.SubElement(a, "b")
+--
+2.26.2
+
+From 56ddb10e50eba7a6352e397f259d9497b44f658d Mon Sep 17 00:00:00 2001
+From: Stefan Behnel <stefan_ml@behnel.de>
+Date: Tue, 26 May 2020 11:30:45 +0200
+Subject: [PATCH 2/2] Fix a test after moving it to a different test module.
+
+---
+ src/lxml/tests/test_etree.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/lxml/tests/test_etree.py b/src/lxml/tests/test_etree.py
+index 56d38e75..105c59b8 100644
+--- a/src/lxml/tests/test_etree.py
++++ b/src/lxml/tests/test_etree.py
+@@ -3047,9 +3047,9 @@ class ETreeOnlyTestCase(HelperTestCase):
+ c = SubElement(a, 'c')
+ d = SubElement(b, 'd')
+ e = SubElement(c, 'e')
+- self.assertXML(
++ self.assertEqual(
+ _bytes('<a><b><d></d></b><c><e></e></c></a>'),
+- a)
++ self.etree.tostring(a, method="c14n"))
+ self.assertEqual(
+ [b, c],
+ a.getchildren())
+--
+2.26.2
+