From ea6bbce7c17a54921179d6fafe77572491e417d4 Mon Sep 17 00:00:00 2001 From: Dominic Davis-Foster Date: Mon, 3 Oct 2022 11:25:49 +0100 Subject: [PATCH 1/4] Run tests on ALT Linux via GitHub Actions --- .github/workflows/python_ci_alt_linux.yml | 65 +++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .github/workflows/python_ci_alt_linux.yml diff --git a/.github/workflows/python_ci_alt_linux.yml b/.github/workflows/python_ci_alt_linux.yml new file mode 100644 index 00000000..01af08c4 --- /dev/null +++ b/.github/workflows/python_ci_alt_linux.yml @@ -0,0 +1,65 @@ +# This file is managed by 'repo_helper'. Don't edit it directly. +--- +name: ALT Linux + +on: + push: + branches-ignore: + - 'repo-helper-update' + - 'pre-commit-ci-update-config' + - 'imgbot' + tags: + - '*' + pull_request: + +permissions: + actions: write + issues: write + contents: read + +jobs: + tests: + name: "alt-linux / Python ${{ matrix.config.python-version }}" + runs-on: "ubuntu-20.04" + container: + image: ghcr.io/domdfcoding/alt-linux-python:latest + continue-on-error: ${{ matrix.config.experimental }} + env: + USING_COVERAGE: '3.10' + + strategy: + fail-fast: False + matrix: + config: + - {python-version: "3.10", testenvs: "py310,build", experimental: False} + + steps: + - name: Checkout 🛎️ + uses: "actions/checkout@v3" + + - name: "Configure" + run: git config --global --add safe.directory /__w/${{ github.event.repository.name }}/${{ github.event.repository.name }} + + - name: Check for changed files + if: startsWith(github.ref, 'refs/tags/') != true + uses: dorny/paths-filter@v2 + id: changes + with: + list-files: "json" + filters: | + code: + - '!(doc-source/**|CONTRIBUTING.rst|.imgbotconfig|.pre-commit-config.yaml|.pylintrc|.readthedocs.yml)' + + - name: Install dependencies 🔧 + id: setup-python + if: ${{ steps.changes.outputs.code == 'true' || steps.changes.outcome == 'skipped' }} + run: | + python3 -VV + python3 -m site + python3 -m pip install --upgrade pip setuptools wheel + python3 -m pip install --upgrade tox virtualenv!=20.16.0 + python3 -m pip install --upgrade coverage_pyver_pragma + + - name: "Run Tests for Python ${{ matrix.config.python-version }}" + if: steps.setup-python.outcome == 'success' + run: python3 -m tox -e "${{ matrix.config.testenvs }}" -s false From 4ce9f268a09f4843b4e7dbcc34a3551c80e88734 Mon Sep 17 00:00:00 2001 From: Dominic Davis-Foster Date: Mon, 3 Oct 2022 14:32:46 +0100 Subject: [PATCH 2/4] Split asyncio test into altlinux and the rest. --- tests/test_import_tools.py | 128 ++++++++++++++++-- ...> test_iter_submodules_asyncio__3_10_.yml} | 0 ...=> test_iter_submodules_asyncio__3_6_.yml} | 0 ...=> test_iter_submodules_asyncio__3_7_.yml} | 0 ...st_iter_submodules_asyncio__3_7_pypy_.yml} | 0 ...=> test_iter_submodules_asyncio__3_8_.yml} | 0 ...st_iter_submodules_asyncio__3_8_pypy_.yml} | 0 ...=> test_iter_submodules_asyncio__3_9_.yml} | 0 ...st_iter_submodules_asyncio__3_9_pypy_.yml} | 0 ...iter_submodules_asyncio_altlinux_3_10_.yml | 29 ++++ ..._iter_submodules_asyncio_altlinux_3_6_.yml | 23 ++++ ..._iter_submodules_asyncio_altlinux_3_7_.yml | 23 ++++ ..._submodules_asyncio_altlinux_3_7_pypy_.yml | 25 ++++ ..._iter_submodules_asyncio_altlinux_3_8_.yml | 27 ++++ ..._submodules_asyncio_altlinux_3_8_pypy_.yml | 29 ++++ ..._iter_submodules_asyncio_altlinux_3_9_.yml | 28 ++++ ..._submodules_asyncio_altlinux_3_9_pypy_.yml | 30 ++++ 17 files changed, 332 insertions(+), 10 deletions(-) rename tests/test_import_tools_/{test_iter_submodules_asyncio_3_10_.yml => test_iter_submodules_asyncio__3_10_.yml} (100%) rename tests/test_import_tools_/{test_iter_submodules_asyncio_3_6_.yml => test_iter_submodules_asyncio__3_6_.yml} (100%) rename tests/test_import_tools_/{test_iter_submodules_asyncio_3_7_.yml => test_iter_submodules_asyncio__3_7_.yml} (100%) rename tests/test_import_tools_/{test_iter_submodules_asyncio_3_7_pypy_.yml => test_iter_submodules_asyncio__3_7_pypy_.yml} (100%) rename tests/test_import_tools_/{test_iter_submodules_asyncio_3_8_.yml => test_iter_submodules_asyncio__3_8_.yml} (100%) rename tests/test_import_tools_/{test_iter_submodules_asyncio_3_8_pypy_.yml => test_iter_submodules_asyncio__3_8_pypy_.yml} (100%) rename tests/test_import_tools_/{test_iter_submodules_asyncio_3_9_.yml => test_iter_submodules_asyncio__3_9_.yml} (100%) rename tests/test_import_tools_/{test_iter_submodules_asyncio_3_9_pypy_.yml => test_iter_submodules_asyncio__3_9_pypy_.yml} (100%) create mode 100644 tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_10_.yml create mode 100644 tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_6_.yml create mode 100644 tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_7_.yml create mode 100644 tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_7_pypy_.yml create mode 100644 tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_8_.yml create mode 100644 tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_8_pypy_.yml create mode 100644 tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_9_.yml create mode 100644 tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_9_pypy_.yml diff --git a/tests/test_import_tools.py b/tests/test_import_tools.py index 634aaaeb..a903f210 100644 --- a/tests/test_import_tools.py +++ b/tests/test_import_tools.py @@ -1,5 +1,7 @@ # stdlib import inspect +import platform +import re import sys from contextlib import contextmanager @@ -175,16 +177,122 @@ def test_discover_entry_points_by_name_name_match_func(advanced_data_regression: ) @pytest.mark.parametrize( "module", - [ - "collections", - "importlib", - "domdf_python_tools", - "consolekit", - "asyncio", - "json", - "cRQefleMvm", - "reprlib" - ], + ["collections", "importlib", "domdf_python_tools", "consolekit", "json", "cRQefleMvm", "reprlib"], ) def test_iter_submodules(version, module: str, advanced_data_regression: AdvancedDataRegressionFixture): advanced_data_regression.check(list(iter_submodules(module))) + + +if sys.version_info < (3, 10): + # From https://github.com/python/cpython/blob/main/Lib/platform.py#L1319 + # License: https://github.com/python/cpython/blob/main/LICENSE + + ### freedesktop.org os-release standard + # https://www.freedesktop.org/software/systemd/man/os-release.html + + # NAME=value with optional quotes (' or "). The regular expression is less + # strict than shell lexer, but that's ok. + _os_release_line = re.compile("^(?P[a-zA-Z0-9_]+)=(?P[\"']?)(?P.*)(?P=quote)$") + # unescape five special characters mentioned in the standard + _os_release_unescape = re.compile(r"\\([\\\$\"\'`])") + # /etc takes precedence over /usr/lib + _os_release_candidates = ("/etc/os-release", "/usr/lib/os-release") + + def freedesktop_os_release(): + """ + Return operation system identification from freedesktop.org os-release + """ + + errno = None + for candidate in _os_release_candidates: + try: + with open(candidate, encoding="utf-8") as f: + info = {"ID": "linux"} + + for line in f: + mo = _os_release_line.match(line) + if mo is not None: + info[mo.group("name")] = _os_release_unescape.sub(r"\1", mo.group("value")) + + return info + + except OSError as e: + errno = e.errno + + else: + raise OSError(errno, f"Unable to read files {', '.join(_os_release_candidates)}") + +else: + freedesktop_os_release = platform.freedesktop_os_release + +on_alt_linux = False + +if platform.system() == "Linux": + try: + on_alt_linux = freedesktop_os_release()["ID"] == "altlinux" + except OSError: + pass + + +@pytest.mark.parametrize( + "version", + [ + pytest.param(3.6, marks=only_version(3.6, reason="Output differs on Python 3.6")), + pytest.param( + 3.7, + marks=[ + only_version(3.7, reason="Output differs on Python 3.7"), + not_pypy("Output differs on PyPy") + ] + ), + pytest.param( + "3.7-pypy", + marks=[ + only_version(3.7, reason="Output differs on Python 3.7"), + only_pypy("Output differs on PyPy") + ] + ), + pytest.param( + 3.8, + marks=[ + only_version(3.8, reason="Output differs on Python 3.8"), + not_pypy("Output differs on PyPy 3.8") + ] + ), + pytest.param( + "3.8_pypy", + marks=[ + only_version(3.8, reason="Output differs on Python 3.8"), + only_pypy("Output differs on PyPy 3.8") + ] + ), + pytest.param( + 3.9, + marks=[ + only_version(3.9, reason="Output differs on Python 3.9"), + not_pypy("Output differs on PyPy 3.9") + ] + ), + pytest.param( + "3.9_pypy", + marks=[ + only_version(3.9, reason="Output differs on Python 3.9"), + only_pypy("Output differs on PyPy 3.9") + ] + ), + pytest.param("3.10", marks=only_version("3.10", reason="Output differs on Python 3.10")), + ] + ) +@pytest.mark.parametrize( + "platform", + [ + pytest.param('', marks=pytest.mark.skipif(on_alt_linux, reason="Not for ALT Linux")), + pytest.param("altlinux", marks=pytest.mark.skipif(not on_alt_linux, reason="Only for ALT Linux")), + ] + ) +def test_iter_submodules_asyncio( + platform, + version, + advanced_data_regression: AdvancedDataRegressionFixture, + ): + advanced_data_regression.check(list(iter_submodules("asyncio"))) diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_3_10_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio__3_10_.yml similarity index 100% rename from tests/test_import_tools_/test_iter_submodules_asyncio_3_10_.yml rename to tests/test_import_tools_/test_iter_submodules_asyncio__3_10_.yml diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_3_6_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio__3_6_.yml similarity index 100% rename from tests/test_import_tools_/test_iter_submodules_asyncio_3_6_.yml rename to tests/test_import_tools_/test_iter_submodules_asyncio__3_6_.yml diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_3_7_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio__3_7_.yml similarity index 100% rename from tests/test_import_tools_/test_iter_submodules_asyncio_3_7_.yml rename to tests/test_import_tools_/test_iter_submodules_asyncio__3_7_.yml diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_3_7_pypy_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio__3_7_pypy_.yml similarity index 100% rename from tests/test_import_tools_/test_iter_submodules_asyncio_3_7_pypy_.yml rename to tests/test_import_tools_/test_iter_submodules_asyncio__3_7_pypy_.yml diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_3_8_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio__3_8_.yml similarity index 100% rename from tests/test_import_tools_/test_iter_submodules_asyncio_3_8_.yml rename to tests/test_import_tools_/test_iter_submodules_asyncio__3_8_.yml diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_3_8_pypy_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio__3_8_pypy_.yml similarity index 100% rename from tests/test_import_tools_/test_iter_submodules_asyncio_3_8_pypy_.yml rename to tests/test_import_tools_/test_iter_submodules_asyncio__3_8_pypy_.yml diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_3_9_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio__3_9_.yml similarity index 100% rename from tests/test_import_tools_/test_iter_submodules_asyncio_3_9_.yml rename to tests/test_import_tools_/test_iter_submodules_asyncio__3_9_.yml diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_3_9_pypy_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio__3_9_pypy_.yml similarity index 100% rename from tests/test_import_tools_/test_iter_submodules_asyncio_3_9_pypy_.yml rename to tests/test_import_tools_/test_iter_submodules_asyncio__3_9_pypy_.yml diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_10_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_10_.yml new file mode 100644 index 00000000..2a3a76a6 --- /dev/null +++ b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_10_.yml @@ -0,0 +1,29 @@ +- asyncio +- asyncio.__main__ +- asyncio.base_events +- asyncio.base_futures +- asyncio.base_subprocess +- asyncio.base_tasks +- asyncio.constants +- asyncio.coroutines +- asyncio.events +- asyncio.exceptions +- asyncio.format_helpers +- asyncio.futures +- asyncio.locks +- asyncio.log +- asyncio.mixins +- asyncio.proactor_events +- asyncio.protocols +- asyncio.queues +- asyncio.runners +- asyncio.selector_events +- asyncio.sslproto +- asyncio.staggered +- asyncio.streams +- asyncio.subprocess +- asyncio.tasks +- asyncio.threads +- asyncio.transports +- asyncio.trsock +- asyncio.unix_events diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_6_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_6_.yml new file mode 100644 index 00000000..de98c1d6 --- /dev/null +++ b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_6_.yml @@ -0,0 +1,23 @@ +- asyncio +- asyncio.base_events +- asyncio.base_futures +- asyncio.base_subprocess +- asyncio.base_tasks +- asyncio.compat +- asyncio.constants +- asyncio.coroutines +- asyncio.events +- asyncio.futures +- asyncio.locks +- asyncio.log +- asyncio.proactor_events +- asyncio.protocols +- asyncio.queues +- asyncio.selector_events +- asyncio.sslproto +- asyncio.streams +- asyncio.subprocess +- asyncio.tasks +- asyncio.test_utils +- asyncio.transports +- asyncio.unix_events diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_7_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_7_.yml new file mode 100644 index 00000000..392e7149 --- /dev/null +++ b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_7_.yml @@ -0,0 +1,23 @@ +- asyncio +- asyncio.base_events +- asyncio.base_futures +- asyncio.base_subprocess +- asyncio.base_tasks +- asyncio.constants +- asyncio.coroutines +- asyncio.events +- asyncio.format_helpers +- asyncio.futures +- asyncio.locks +- asyncio.log +- asyncio.proactor_events +- asyncio.protocols +- asyncio.queues +- asyncio.runners +- asyncio.selector_events +- asyncio.sslproto +- asyncio.streams +- asyncio.subprocess +- asyncio.tasks +- asyncio.transports +- asyncio.unix_events diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_7_pypy_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_7_pypy_.yml new file mode 100644 index 00000000..7e08c33c --- /dev/null +++ b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_7_pypy_.yml @@ -0,0 +1,25 @@ +- asyncio +- asyncio.base_events +- asyncio.base_futures +- asyncio.base_subprocess +- asyncio.base_tasks +- asyncio.compat +- asyncio.constants +- asyncio.coroutines +- asyncio.events +- asyncio.format_helpers +- asyncio.futures +- asyncio.locks +- asyncio.log +- asyncio.proactor_events +- asyncio.protocols +- asyncio.queues +- asyncio.runners +- asyncio.selector_events +- asyncio.sslproto +- asyncio.streams +- asyncio.subprocess +- asyncio.tasks +- asyncio.test_utils +- asyncio.transports +- asyncio.unix_events diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_8_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_8_.yml new file mode 100644 index 00000000..d835a91a --- /dev/null +++ b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_8_.yml @@ -0,0 +1,27 @@ +- asyncio +- asyncio.__main__ +- asyncio.base_events +- asyncio.base_futures +- asyncio.base_subprocess +- asyncio.base_tasks +- asyncio.constants +- asyncio.coroutines +- asyncio.events +- asyncio.exceptions +- asyncio.format_helpers +- asyncio.futures +- asyncio.locks +- asyncio.log +- asyncio.proactor_events +- asyncio.protocols +- asyncio.queues +- asyncio.runners +- asyncio.selector_events +- asyncio.sslproto +- asyncio.staggered +- asyncio.streams +- asyncio.subprocess +- asyncio.tasks +- asyncio.transports +- asyncio.trsock +- asyncio.unix_events diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_8_pypy_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_8_pypy_.yml new file mode 100644 index 00000000..75ae7570 --- /dev/null +++ b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_8_pypy_.yml @@ -0,0 +1,29 @@ +- asyncio +- asyncio.__main__ +- asyncio.base_events +- asyncio.base_futures +- asyncio.base_subprocess +- asyncio.base_tasks +- asyncio.compat +- asyncio.constants +- asyncio.coroutines +- asyncio.events +- asyncio.exceptions +- asyncio.format_helpers +- asyncio.futures +- asyncio.locks +- asyncio.log +- asyncio.proactor_events +- asyncio.protocols +- asyncio.queues +- asyncio.runners +- asyncio.selector_events +- asyncio.sslproto +- asyncio.staggered +- asyncio.streams +- asyncio.subprocess +- asyncio.tasks +- asyncio.test_utils +- asyncio.transports +- asyncio.trsock +- asyncio.unix_events diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_9_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_9_.yml new file mode 100644 index 00000000..544ebfdf --- /dev/null +++ b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_9_.yml @@ -0,0 +1,28 @@ +- asyncio +- asyncio.__main__ +- asyncio.base_events +- asyncio.base_futures +- asyncio.base_subprocess +- asyncio.base_tasks +- asyncio.constants +- asyncio.coroutines +- asyncio.events +- asyncio.exceptions +- asyncio.format_helpers +- asyncio.futures +- asyncio.locks +- asyncio.log +- asyncio.proactor_events +- asyncio.protocols +- asyncio.queues +- asyncio.runners +- asyncio.selector_events +- asyncio.sslproto +- asyncio.staggered +- asyncio.streams +- asyncio.subprocess +- asyncio.tasks +- asyncio.threads +- asyncio.transports +- asyncio.trsock +- asyncio.unix_events diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_9_pypy_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_9_pypy_.yml new file mode 100644 index 00000000..dfb82ee1 --- /dev/null +++ b/tests/test_import_tools_/test_iter_submodules_asyncio_altlinux_3_9_pypy_.yml @@ -0,0 +1,30 @@ +- asyncio +- asyncio.__main__ +- asyncio.base_events +- asyncio.base_futures +- asyncio.base_subprocess +- asyncio.base_tasks +- asyncio.compat +- asyncio.constants +- asyncio.coroutines +- asyncio.events +- asyncio.exceptions +- asyncio.format_helpers +- asyncio.futures +- asyncio.locks +- asyncio.log +- asyncio.proactor_events +- asyncio.protocols +- asyncio.queues +- asyncio.runners +- asyncio.selector_events +- asyncio.sslproto +- asyncio.staggered +- asyncio.streams +- asyncio.subprocess +- asyncio.tasks +- asyncio.test_utils +- asyncio.threads +- asyncio.transports +- asyncio.trsock +- asyncio.unix_events From be27d9bf8888b3286a051b009cd2b1fde5f4f0f5 Mon Sep 17 00:00:00 2001 From: Dominic Davis-Foster Date: Mon, 3 Oct 2022 16:05:43 +0100 Subject: [PATCH 3/4] Lint --- tests/test_import_tools.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_import_tools.py b/tests/test_import_tools.py index a903f210..a92b6826 100644 --- a/tests/test_import_tools.py +++ b/tests/test_import_tools.py @@ -219,8 +219,7 @@ def freedesktop_os_release(): except OSError as e: errno = e.errno - else: - raise OSError(errno, f"Unable to read files {', '.join(_os_release_candidates)}") + raise OSError(errno, f"Unable to read files {', '.join(_os_release_candidates)}") else: freedesktop_os_release = platform.freedesktop_os_release From ac849fae6ba206e98d6d6b1683e234180f42d6a0 Mon Sep 17 00:00:00 2001 From: Dominic Davis-Foster Date: Mon, 3 Oct 2022 20:11:20 +0100 Subject: [PATCH 4/4] De-duplicate code in test_import_tools.py --- tests/test_import_tools.py | 55 ++++---------------------------------- 1 file changed, 5 insertions(+), 50 deletions(-) diff --git a/tests/test_import_tools.py b/tests/test_import_tools.py index a92b6826..71fcc984 100644 --- a/tests/test_import_tools.py +++ b/tests/test_import_tools.py @@ -126,7 +126,7 @@ def test_discover_entry_points_by_name_name_match_func(advanced_data_regression: advanced_data_regression.check({k: v.__name__ for k, v in entry_points.items()}) -@pytest.mark.parametrize( +iter_submodules_versions = pytest.mark.parametrize( "version", [ pytest.param(3.6, marks=only_version(3.6, reason="Output differs on Python 3.6")), @@ -175,6 +175,9 @@ def test_discover_entry_points_by_name_name_match_func(advanced_data_regression: pytest.param("3.10", marks=only_version("3.10", reason="Output differs on Python 3.10")), ] ) + + +@iter_submodules_versions @pytest.mark.parametrize( "module", ["collections", "importlib", "domdf_python_tools", "consolekit", "json", "cRQefleMvm", "reprlib"], @@ -233,55 +236,7 @@ def freedesktop_os_release(): pass -@pytest.mark.parametrize( - "version", - [ - pytest.param(3.6, marks=only_version(3.6, reason="Output differs on Python 3.6")), - pytest.param( - 3.7, - marks=[ - only_version(3.7, reason="Output differs on Python 3.7"), - not_pypy("Output differs on PyPy") - ] - ), - pytest.param( - "3.7-pypy", - marks=[ - only_version(3.7, reason="Output differs on Python 3.7"), - only_pypy("Output differs on PyPy") - ] - ), - pytest.param( - 3.8, - marks=[ - only_version(3.8, reason="Output differs on Python 3.8"), - not_pypy("Output differs on PyPy 3.8") - ] - ), - pytest.param( - "3.8_pypy", - marks=[ - only_version(3.8, reason="Output differs on Python 3.8"), - only_pypy("Output differs on PyPy 3.8") - ] - ), - pytest.param( - 3.9, - marks=[ - only_version(3.9, reason="Output differs on Python 3.9"), - not_pypy("Output differs on PyPy 3.9") - ] - ), - pytest.param( - "3.9_pypy", - marks=[ - only_version(3.9, reason="Output differs on Python 3.9"), - only_pypy("Output differs on PyPy 3.9") - ] - ), - pytest.param("3.10", marks=only_version("3.10", reason="Output differs on Python 3.10")), - ] - ) +@iter_submodules_versions @pytest.mark.parametrize( "platform", [