From 66ff10deb71965cec805e498a77b23a171f6d703 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Mon, 9 Jan 2023 17:22:01 +0000 Subject: [PATCH] Reintroduce support for arch-suffixed factors Apparently we need to support these. Signed-off-by: Stephen Finucane --- src/tox/tox_env/python/api.py | 27 +++++++++++++++++++++++-- tests/tox_env/python/test_python_api.py | 5 ++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/tox/tox_env/python/api.py b/src/tox/tox_env/python/api.py index 271a3803da..cd2fecbbf0 100644 --- a/src/tox/tox_env/python/api.py +++ b/src/tox/tox_env/python/api.py @@ -130,11 +130,34 @@ def default_base_python(self, conf: Config, env_name: str | None) -> list[str]: @classmethod def extract_base_python(cls, env_name: str) -> str | None: candidates: list[str] = [] - for factor in env_name.split("-"): + factors = env_name.split("-") + + def _parse_factor(factor: str) -> str | None: spec = PythonSpec.from_string_spec(factor) impl = spec.implementation or "python" if impl.lower() in INTERPRETER_SHORT_NAMES and env_name is not None and spec.path is None: - candidates.append(factor) + return factor + return None + + # unfortunately we have an exception to the "factors are delimited by dashes" rule: the architecture + # we must support e.g. py38-64, which means python3.8 (64 bit) + if len(factors) > 1 and "32" in factors or "64" in factors: + for arch in {"32", "64"}: + if arch not in factors: + continue + idx = factors.index(arch) + if idx == 0: + continue + factor = "-".join([factors[idx - 1], factors[idx]]) + candidate = _parse_factor(factor) + if candidate: + candidates.append(candidate) + del factors[idx - 1 : idx + 1] + + for factor in factors: + candidate = _parse_factor(factor) + if candidate: + candidates.append(candidate) if candidates: if len(candidates) > 1: raise ValueError(f"conflicting factors {', '.join(candidates)} in {env_name}") diff --git a/tests/tox_env/python/test_python_api.py b/tests/tox_env/python/test_python_api.py index 725eab057a..85b60ceb89 100644 --- a/tests/tox_env/python/test_python_api.py +++ b/tests/tox_env/python/test_python_api.py @@ -99,6 +99,9 @@ def test_base_python_env_no_conflict(env: str, base_python: list[str], ignore_co ("py310", ["py38", "py39"], "py310", ["py38", "py39"]), ("py3.11.1", ["py3.11.2"], "py3.11.1", ["py3.11.2"]), ("py3-64", ["py3-32"], "py3-64", ["py3-32"]), + ("foo-py38-64-bar", ["python3"], "py38-64", ["python3"]), + ("foo-py36-32", ["python3"], "py36-32", ["python3"]), + ("py311-22", ["python3"], "py311", ["python3"]), ("py310-magic", ["py39"], "py310", ["py39"]), ], ids=lambda a: "|".join(a) if isinstance(a, list) else str(a), @@ -110,7 +113,7 @@ def test_base_python_env_conflict( conflict: list[str], ignore_conflict: bool, ) -> None: - if env == "py3-64": + if env == "py311-22": raise pytest.skip("bug #2657") if ignore_conflict: