From bc0eb93e65ae98795e98df6eeb18a90bed2c681cd4cb8ab329d4a7567eff6863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Thu, 27 Aug 2020 19:44:55 +0000 Subject: [PATCH] Accepting request 830019 from home:mcalabkova:branches:devel:languages:python:pytest - Update to 1.1 * Drop support for Python 3.3 and 3.4. * Try to import from ``collections.abc`` to remove DeprecationWarning and ensure ``html5lib`` keeps working in future Python versions. (#403) * Drop optional ``datrie`` dependency. (#442) - Drop merged patches: * pytest4-mhroncok.patch * collections-abc.patch * pytest5.patch - Add upstream patch pytest6.patch OBS-URL: https://build.opensuse.org/request/show/830019 OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-html5lib?expand=0&rev=47 --- collections-abc.patch | 44 ----------- html5lib-1.0.1.tar.gz | 3 - html5lib-1.1.tar.gz | 3 + pytest4-mhroncok.patch | 143 ----------------------------------- pytest5.patch | 63 ---------------- pytest6.patch | 163 ++++++++++++++++++++++++++++++++++++++++ python-html5lib.changes | 14 ++++ python-html5lib.spec | 10 +-- 8 files changed, 183 insertions(+), 260 deletions(-) delete mode 100644 collections-abc.patch delete mode 100644 html5lib-1.0.1.tar.gz create mode 100644 html5lib-1.1.tar.gz delete mode 100644 pytest4-mhroncok.patch delete mode 100644 pytest5.patch create mode 100644 pytest6.patch diff --git a/collections-abc.patch b/collections-abc.patch deleted file mode 100644 index f0d0bad..0000000 --- a/collections-abc.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 322a2d57bfdc52a9ce14bee93f9abb372cc08487 Mon Sep 17 00:00:00 2001 -From: 5j9 <5j9@users.noreply.github.com> -Date: Sun, 23 Sep 2018 11:32:46 +0330 -Subject: [PATCH] Try to import MutableMapping from collections.abc - -Note that collections.abc has been added in Python 3.3. - -Fixes #402 ---- - html5lib/_trie/_base.py | 5 ++++- - html5lib/treebuilders/dom.py | 5 ++++- - 2 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/html5lib/_trie/_base.py b/html5lib/_trie/_base.py -index a1158bbb..6b71975f 100644 ---- a/html5lib/_trie/_base.py -+++ b/html5lib/_trie/_base.py -@@ -1,6 +1,9 @@ - from __future__ import absolute_import, division, unicode_literals - --from collections import Mapping -+try: -+ from collections.abc import Mapping -+except ImportError: # Python 2.7 -+ from collections import Mapping - - - class Trie(Mapping): -diff --git a/html5lib/treebuilders/dom.py b/html5lib/treebuilders/dom.py -index dcfac220..d8b53004 100644 ---- a/html5lib/treebuilders/dom.py -+++ b/html5lib/treebuilders/dom.py -@@ -1,7 +1,10 @@ - from __future__ import absolute_import, division, unicode_literals - - --from collections import MutableMapping -+try: -+ from collections.abc import MutableMapping -+except ImportError: # Python 2.7 -+ from collections import MutableMapping - from xml.dom import minidom, Node - import weakref - diff --git a/html5lib-1.0.1.tar.gz b/html5lib-1.0.1.tar.gz deleted file mode 100644 index f0b9e8e..0000000 --- a/html5lib-1.0.1.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:66cb0dcfdbbc4f9c3ba1a63fdb511ffdbd4f513b2b6d81b80cd26ce6b3fb3736 -size 252959 diff --git a/html5lib-1.1.tar.gz b/html5lib-1.1.tar.gz new file mode 100644 index 0000000..11bd2ce --- /dev/null +++ b/html5lib-1.1.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f +size 272215 diff --git a/pytest4-mhroncok.patch b/pytest4-mhroncok.patch deleted file mode 100644 index df254b7..0000000 --- a/pytest4-mhroncok.patch +++ /dev/null @@ -1,143 +0,0 @@ -From dd117cc62d961573e9867d79ae1c3461a42e6167 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= -Date: Thu, 28 Mar 2019 01:45:43 +0100 -Subject: [PATCH] Support pytest 4 - -Fixes https://github.com/html5lib/html5lib-python/issues/411 ---- - html5lib/tests/test_encoding.py | 4 ++-- - html5lib/tests/test_sanitizer.py | 14 +++++++------- - html5lib/tests/test_serializer.py | 2 +- - html5lib/tests/test_stream.py | 7 ++++--- - html5lib/tests/test_treewalkers.py | 2 +- - requirements-test.txt | 2 +- - tox.ini | 2 +- - 7 files changed, 17 insertions(+), 16 deletions(-) - ---- a/html5lib/tests/test_encoding.py -+++ b/html5lib/tests/test_encoding.py -@@ -94,13 +94,13 @@ def runPreScanEncodingTest(data, encodin - - assert encoding == stream.charEncoding[0].name, errorMessage(data, encoding, stream.charEncoding[0].name) - -- -+@pytest.mark.skip(reason="broken under pytest4") - def test_encoding(): - for filename in get_data_files("encoding"): - tests = _TestData(filename, b"data", encoding=None) - for test in tests: -- yield (runParserEncodingTest, test[b'data'], test[b'encoding']) -- yield (runPreScanEncodingTest, test[b'data'], test[b'encoding']) -+ runParserEncodingTest(test[b'data'], test[b'encoding']) -+ runPreScanEncodingTest(test[b'data'], test[b'encoding']) - - - # pylint:disable=wrong-import-position ---- a/html5lib/tests/test_sanitizer.py -+++ b/html5lib/tests/test_sanitizer.py -@@ -67,19 +67,19 @@ def test_sanitizer(): - 'tfoot', 'th', 'thead', 'tr', 'select']: - continue # TODO - if tag_name == 'image': -- yield (runSanitizerTest, "test_should_allow_%s_tag" % tag_name, -+ runSanitizerTest("test_should_allow_%s_tag" % tag_name, - "foo <bad>bar</bad> baz", - "<%s title='1'>foo bar baz" % (tag_name, tag_name)) - elif tag_name == 'br': -- yield (runSanitizerTest, "test_should_allow_%s_tag" % tag_name, -+ runSanitizerTest("test_should_allow_%s_tag" % tag_name, - "
foo <bad>bar</bad> baz
", - "<%s title='1'>foo bar baz" % (tag_name, tag_name)) - elif tag_name in constants.voidElements: -- yield (runSanitizerTest, "test_should_allow_%s_tag" % tag_name, -+ runSanitizerTest("test_should_allow_%s_tag" % tag_name, - "<%s title=\"1\"/>foo <bad>bar</bad> baz" % tag_name, - "<%s title='1'>foo bar baz" % (tag_name, tag_name)) - else: -- yield (runSanitizerTest, "test_should_allow_%s_tag" % tag_name, -+ runSanitizerTest("test_should_allow_%s_tag" % tag_name, - "<%s title=\"1\">foo <bad>bar</bad> baz" % (tag_name, tag_name), - "<%s title='1'>foo bar baz" % (tag_name, tag_name)) - -@@ -93,7 +93,7 @@ def test_sanitizer(): - attribute_value = 'foo' - if attribute_name in sanitizer.attr_val_is_uri: - attribute_value = '%s://sub.domain.tld/path/object.ext' % sanitizer.allowed_protocols[0] -- yield (runSanitizerTest, "test_should_allow_%s_attribute" % attribute_name, -+ runSanitizerTest("test_should_allow_%s_attribute" % attribute_name, - "

foo <bad>bar</bad> baz

" % (attribute_name, attribute_value), - "

foo bar baz

" % (attribute_name, attribute_value)) - -@@ -101,7 +101,7 @@ def test_sanitizer(): - rest_of_uri = '//sub.domain.tld/path/object.ext' - if protocol == 'data': - rest_of_uri = 'image/png;base64,aGVsbG8gd29ybGQ=' -- yield (runSanitizerTest, "test_should_allow_uppercase_%s_uris" % protocol, -+ runSanitizerTest("test_should_allow_uppercase_%s_uris" % protocol, - "foo" % (protocol, rest_of_uri), - """foo""" % (protocol, rest_of_uri)) - -@@ -110,7 +110,7 @@ def test_sanitizer(): - if protocol == 'data': - rest_of_uri = 'image/png;base64,aGVsbG8gd29ybGQ=' - protocol = protocol.upper() -- yield (runSanitizerTest, "test_should_allow_uppercase_%s_uris" % protocol, -+ runSanitizerTest("test_should_allow_uppercase_%s_uris" % protocol, - "foo" % (protocol, rest_of_uri), - """foo""" % (protocol, rest_of_uri)) - ---- a/html5lib/tests/test_serializer.py -+++ b/html5lib/tests/test_serializer.py -@@ -222,4 +222,4 @@ def test_serializer(): - with open(filename) as fp: - tests = json.load(fp) - for test in tests['tests']: -- yield runSerializerTest, test["input"], test["expected"], test.get("options", {}) -+ runSerializerTest(test["input"], test["expected"], test.get("options", {})) ---- a/html5lib/tests/test_stream.py -+++ b/html5lib/tests/test_stream.py -@@ -308,9 +308,10 @@ def test_invalid_codepoints(inp, num): - ("'\\uD800\\uD800\\uD800'", 3), - ("'a\\uD800a\\uD800a\\uD800a'", 3), - ("'\\uDFFF\\uDBFF'", 2), -- pytest.mark.skipif(sys.maxunicode == 0xFFFF, -- ("'\\uDBFF\\uDFFF'", 2), -- reason="narrow Python")]) -+ pytest.param( -+ "'\\uDBFF\\uDFFF'", 2, -+ marks=pytest.mark.skipif(sys.maxunicode == 0xFFFF, -+ reason="narrow Python"))]) - def test_invalid_codepoints_surrogates(inp, num): - inp = eval(inp) # pylint:disable=eval-used - fp = StringIO(inp) ---- a/html5lib/tests/test_treewalkers.py -+++ b/html5lib/tests/test_treewalkers.py -@@ -99,7 +99,7 @@ def test_treewalker_six_mix(): - - for tree in sorted(treeTypes.items()): - for intext, attrs, expected in sm_tests: -- yield runTreewalkerEditTest, intext, expected, attrs, tree -+ runTreewalkerEditTest(intext, expected, attrs, tree) - - - @pytest.mark.parametrize("tree,char", itertools.product(sorted(treeTypes.items()), ["x", "\u1234"])) ---- a/requirements-test.txt -+++ b/requirements-test.txt -@@ -4,7 +4,7 @@ tox - - flake8<3.0 - --pytest==3.2.5 -+pytest>=4.3,<4.4 - coverage - pytest-expect>=1.1,<2.0 - mock ---- a/tox.ini -+++ b/tox.ini -@@ -1,5 +1,5 @@ - [tox] --envlist = {py27,py33,py34,py35,py36,pypy}-{base,six19,optional} -+envlist = {py27,py34,py35,py36,py37,py38,pypy}-{base,six19,optional} - - [testenv] - deps = diff --git a/pytest5.patch b/pytest5.patch deleted file mode 100644 index fe18735..0000000 --- a/pytest5.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 3f10121d98ce8ca36b4b856275093dd189fdf1d2 Mon Sep 17 00:00:00 2001 -From: Sam Sneddon -Date: Fri, 22 May 2020 20:37:19 +0100 -Subject: [PATCH] Update pytest - ---- - .pytest.expect | 4 +-- - html5lib/tests/tree_construction.py | 12 ++++----- - 3 files changed, 15 insertions(+), 42 deletions(-) - -diff --git a/html5lib/tests/tree_construction.py b/html5lib/tests/tree_construction.py -index 6112d11d..1ef6e725 100644 ---- a/html5lib/tests/tree_construction.py -+++ b/html5lib/tests/tree_construction.py -@@ -57,8 +57,6 @@ def _getParserTests(self, treeName, treeAPIs): - item.add_marker(pytest.mark.parser) - if namespaceHTMLElements: - item.add_marker(pytest.mark.namespaced) -- if treeAPIs is None: -- item.add_marker(pytest.mark.skipif(True, reason="Treebuilder not loaded")) - yield item - - def _getTreeWalkerTests(self, treeName, treeAPIs): -@@ -69,8 +67,6 @@ def _getTreeWalkerTests(self, treeName, treeAPIs): - treeAPIs) - item.add_marker(getattr(pytest.mark, treeName)) - item.add_marker(pytest.mark.treewalker) -- if treeAPIs is None: -- item.add_marker(pytest.mark.skipif(True, reason="Treebuilder not loaded")) - yield item - - -@@ -84,12 +80,14 @@ def convertTreeDump(data): - class ParserTest(pytest.Item): - def __init__(self, name, parent, test, treeClass, namespaceHTMLElements): - super(ParserTest, self).__init__(name, parent) -- self.obj = lambda: 1 # this is to hack around skipif needing a function! - self.test = test - self.treeClass = treeClass - self.namespaceHTMLElements = namespaceHTMLElements - - def runtest(self): -+ if self.treeClass is None: -+ pytest.skip("Treebuilder not loaded") -+ - p = html5parser.HTMLParser(tree=self.treeClass, - namespaceHTMLElements=self.namespaceHTMLElements) - -@@ -147,11 +145,13 @@ def repr_failure(self, excinfo): - class TreeWalkerTest(pytest.Item): - def __init__(self, name, parent, test, treeAPIs): - super(TreeWalkerTest, self).__init__(name, parent) -- self.obj = lambda: 1 # this is to hack around skipif needing a function! - self.test = test - self.treeAPIs = treeAPIs - - def runtest(self): -+ if self.treeAPIs is None: -+ pytest.skip("Treebuilder not loaded") -+ - p = html5parser.HTMLParser(tree=self.treeAPIs["builder"]) - - input = self.test['data'] diff --git a/pytest6.patch b/pytest6.patch new file mode 100644 index 0000000..a6f610d --- /dev/null +++ b/pytest6.patch @@ -0,0 +1,163 @@ +From 2c19b9899ab3a3e8bd0ca35e5d78544334204169 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= +Date: Sat, 8 Aug 2020 13:39:22 +0200 +Subject: [PATCH] Use Node.from_parent() constructor to support pytest 6 + +Add a wrapper not to break pytest 4 (needed for Python 2 support). + + ============================= test session starts ============================== + platform linux -- Python 3.9.0b5, pytest-6.0.1, py-1.9.0, pluggy-0.13.1 + rootdir: /builddir/build/BUILD/html5lib-1.1, configfile: pytest.ini + plugins: expect-1.1.0 + collected 0 items / 1 error + + ==================================== ERRORS ==================================== + ________________________ ERROR collecting test session _________________________ + /usr/lib/python3.9/site-packages/pluggy/hooks.py:286: in __call__ + return self._hookexec(self, self.get_hookimpls(), kwargs) + /usr/lib/python3.9/site-packages/pluggy/manager.py:93: in _hookexec + return self._inner_hookexec(hook, methods, kwargs) + /usr/lib/python3.9/site-packages/pluggy/manager.py:84: in + self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall( + html5lib/tests/conftest.py:105: in pytest_collect_file + return TokenizerFile(path, parent) + /usr/lib/python3.9/site-packages/_pytest/nodes.py:95: in __call__ + warnings.warn(NODE_USE_FROM_PARENT.format(name=self.__name__), stacklevel=2) + E pytest.PytestDeprecationWarning: Direct construction of TokenizerFile has been deprecated, please use TokenizerFile.from_parent. + E See https://docs.pytest.org/en/stable/deprecations.html#node-construction-changed-to-node-from-parent for more details. + +Fixes https://github.com/html5lib/html5lib-python/issues/505 +--- + html5lib/tests/conftest.py | 15 ++++++++++++--- + html5lib/tests/sanitizer.py | 2 +- + html5lib/tests/tokenizer.py | 10 +++++----- + html5lib/tests/tree_construction.py | 20 ++++++++++---------- + requirements-test.txt | 2 +- + 5 files changed, 29 insertions(+), 20 deletions(-) + +diff --git a/html5lib/tests/conftest.py b/html5lib/tests/conftest.py +index dad167c5..fffeb50c 100644 +--- a/html5lib/tests/conftest.py ++++ b/html5lib/tests/conftest.py +@@ -99,10 +99,19 @@ def pytest_collect_file(path, parent): + + if _tree_construction in dir_and_parents: + if path.ext == ".dat": +- return TreeConstructionFile(path, parent) ++ return TreeConstructionFile.from_parent(parent, fspath=path) + elif _tokenizer in dir_and_parents: + if path.ext == ".test": +- return TokenizerFile(path, parent) ++ return TokenizerFile.from_parent(parent, fspath=path) + elif _sanitizer_testdata in dir_and_parents: + if path.ext == ".dat": +- return SanitizerFile(path, parent) ++ return SanitizerFile.from_parent(parent, fspath=path) ++ ++ ++# Tiny wrapper to allow .from_parent constructors on older pytest for PY27 ++if not hasattr(pytest.Item.__base__, "from_parent"): ++ @classmethod ++ def from_parent(cls, parent, **kwargs): ++ return cls(parent=parent, **kwargs) ++ ++ pytest.Item.__base__.from_parent = from_parent +diff --git a/html5lib/tests/sanitizer.py b/html5lib/tests/sanitizer.py +index bb483421..16e53868 100644 +--- a/html5lib/tests/sanitizer.py ++++ b/html5lib/tests/sanitizer.py +@@ -13,7 +13,7 @@ def collect(self): + with codecs.open(str(self.fspath), "r", encoding="utf-8") as fp: + tests = json.load(fp) + for i, test in enumerate(tests): +- yield SanitizerTest(str(i), self, test=test) ++ yield SanitizerTest.from_parent(self, name=str(i), test=test) + + + class SanitizerTest(pytest.Item): +diff --git a/html5lib/tests/tokenizer.py b/html5lib/tests/tokenizer.py +index 47264cc3..cc9897a4 100644 +--- a/html5lib/tests/tokenizer.py ++++ b/html5lib/tests/tokenizer.py +@@ -192,7 +192,7 @@ def collect(self): + tests = json.load(fp) + if 'tests' in tests: + for i, test in enumerate(tests['tests']): +- yield TokenizerTestCollector(str(i), self, testdata=test) ++ yield TokenizerTestCollector.from_parent(self, name=str(i), testdata=test) + + + class TokenizerTestCollector(pytest.Collector): +@@ -207,10 +207,10 @@ def __init__(self, name, parent=None, config=None, session=None, testdata=None): + def collect(self): + for initialState in self.testdata["initialStates"]: + initialState = capitalize(initialState) +- item = TokenizerTest(initialState, +- self, +- self.testdata, +- initialState) ++ item = TokenizerTest.from_parent(self, ++ name=initialState, ++ test=self.testdata, ++ initialState=initialState) + if self.testdata["input"] is None: + item.add_marker(pytest.mark.skipif(True, reason="Relies on lone surrogates")) + yield item +diff --git a/html5lib/tests/tree_construction.py b/html5lib/tests/tree_construction.py +index 1ef6e725..fb0657bf 100644 +--- a/html5lib/tests/tree_construction.py ++++ b/html5lib/tests/tree_construction.py +@@ -26,7 +26,7 @@ class TreeConstructionFile(pytest.File): + def collect(self): + tests = TestData(str(self.fspath), "data") + for i, test in enumerate(tests): +- yield TreeConstructionTest(str(i), self, testdata=test) ++ yield TreeConstructionTest.from_parent(self, name=str(i), testdata=test) + + + class TreeConstructionTest(pytest.Collector): +@@ -48,11 +48,11 @@ def _getParserTests(self, treeName, treeAPIs): + nodeid = "%s::parser::namespaced" % treeName + else: + nodeid = "%s::parser::void-namespace" % treeName +- item = ParserTest(nodeid, +- self, +- self.testdata, +- treeAPIs["builder"] if treeAPIs is not None else None, +- namespaceHTMLElements) ++ item = ParserTest.from_parent(self, ++ name=nodeid, ++ test=self.testdata, ++ treeClass=treeAPIs["builder"] if treeAPIs is not None else None, ++ namespaceHTMLElements=namespaceHTMLElements) + item.add_marker(getattr(pytest.mark, treeName)) + item.add_marker(pytest.mark.parser) + if namespaceHTMLElements: +@@ -61,10 +61,10 @@ def _getParserTests(self, treeName, treeAPIs): + + def _getTreeWalkerTests(self, treeName, treeAPIs): + nodeid = "%s::treewalker" % treeName +- item = TreeWalkerTest(nodeid, +- self, +- self.testdata, +- treeAPIs) ++ item = TreeWalkerTest.from_parent(self, ++ name=nodeid, ++ test=self.testdata, ++ treeAPIs=treeAPIs) + item.add_marker(getattr(pytest.mark, treeName)) + item.add_marker(pytest.mark.treewalker) + yield item +diff --git a/requirements-test.txt b/requirements-test.txt +index 703d0e69..57f8f617 100644 +--- a/requirements-test.txt ++++ b/requirements-test.txt +@@ -3,7 +3,7 @@ + tox>=3.15.1,<4 + flake8>=3.8.1,<3.9 + pytest>=4.6.10,<5 ; python_version < '3' +-pytest>=5.4.2,<6 ; python_version >= '3' ++pytest>=5.4.2,<7 ; python_version >= '3' + coverage>=5.1,<6 + pytest-expect>=1.1.0,<2 + mock>=3.0.5,<4 ; python_version < '3.6' diff --git a/python-html5lib.changes b/python-html5lib.changes index 187800c..c2e10ee 100644 --- a/python-html5lib.changes +++ b/python-html5lib.changes @@ -1,3 +1,17 @@ +------------------------------------------------------------------- +Thu Aug 27 14:03:46 UTC 2020 - Marketa Calabkova + +- Update to 1.1 + * Drop support for Python 3.3 and 3.4. + * Try to import from ``collections.abc`` to remove DeprecationWarning and ensure + ``html5lib`` keeps working in future Python versions. (#403) + * Drop optional ``datrie`` dependency. (#442) +- Drop merged patches: + * pytest4-mhroncok.patch + * collections-abc.patch + * pytest5.patch +- Add upstream patch pytest6.patch + ------------------------------------------------------------------- Fri May 29 09:17:23 UTC 2020 - Tomáš Chvátal diff --git a/python-html5lib.spec b/python-html5lib.spec index eb5a608..628f464 100644 --- a/python-html5lib.spec +++ b/python-html5lib.spec @@ -18,19 +18,15 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-html5lib -Version: 1.0.1 +Version: 1.1 Release: 0 Summary: HTML parser based on the WHAT-WG Web Applications 1 License: MIT URL: https://github.com/html5lib/html5lib-python Source: https://files.pythonhosted.org/packages/source/h/html5lib/html5lib-%{version}.tar.gz -# PATCH-FIX-UPSTREAM pytest4-mhroncok.patch gh#html5lib/html5lib-python#429 mcepl@suse.com -# This patch makes testsuite pass with pytest4 -Patch0: pytest4-mhroncok.patch -Patch1: collections-abc.patch -Patch2: pytest5.patch +# PATCH-FIX_UPSTREAM https://github.com/html5lib/html5lib-python/commit/2c19b9899ab3a3e8bd0ca35e5d78544334204169 Use Node.from_parent() constructor to support pytest 6 +Patch0: pytest6.patch BuildRequires: %{python_module Genshi} -BuildRequires: %{python_module datrie} BuildRequires: %{python_module lxml} BuildRequires: %{python_module mock} BuildRequires: %{python_module pytest >= 4.0}