dev-python/lxml: Port to py39
authorMichał Górny <mgorny@gentoo.org>
Tue, 26 May 2020 10:20:52 +0000 (12:20 +0200)
committerMichał Górny <mgorny@gentoo.org>
Tue, 26 May 2020 10:35:45 +0000 (12:35 +0200)
Signed-off-by: Michał Górny <mgorny@gentoo.org>
dev-python/lxml/files/lxml-4.5.1-py39.patch [new file with mode: 0644]
dev-python/lxml/lxml-4.5.1.ebuild

diff --git a/dev-python/lxml/files/lxml-4.5.1-py39.patch b/dev-python/lxml/files/lxml-4.5.1-py39.patch
new file mode 100644 (file)
index 0000000..3032e53
--- /dev/null
@@ -0,0 +1,620 @@
+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
+
index 34a5acd3ff98dea3935657f6e4cc12740be7d599..076c86886ddeff24e7048ee6efec04fdf5177be3 100644 (file)
@@ -3,7 +3,7 @@
 
 EAPI=7
 
-PYTHON_COMPAT=( python2_7 python3_{6,7,8} pypy3 )
+PYTHON_COMPAT=( python2_7 python3_{6,7,8,9} pypy3 )
 
 inherit distutils-r1 eutils toolchain-funcs
 
@@ -34,6 +34,7 @@ DISTUTILS_IN_SOURCE_BUILD=1
 
 PATCHES=(
        "${FILESDIR}"/${PN}-4.5.0-tests-pypy.patch
+       "${FILESDIR}"/lxml-4.5.1-py39.patch
 )
 
 python_prepare_all() {