From 9a929f296c1f77d05a6dda8581e1e1ce16b8f7ee Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 4 Jan 2023 16:51:32 +0000 Subject: [PATCH] Fail on mismatched python spec attributes The following is intended to be a correct tox configuration: [tox] min_version = 4.1 env_list = py{38,39,310,311},docs [testenv] base_python = python3 [testenv:docs] commands = sphinx-build ... The goal of this is to use 'python3' (i.e. the value of '[testenv] base_python') for all environments except those with specific 'pyXX' factors in them. This helps eliminate issues where environments that do not specify a 'pyXX' factor run with different Python versions in different environments. An earlier bug, #477 [1], prevented us from doing this. Due to #477, the interpreter version indicated by '[testenv] base_python' (or rather '[testenv] basepython' - the underscore-separated variant was only introduced in tox 4) would override the value indicated by the 'pyXX' factor. This was resolved with a PR, #841 [2], which started warning users if they were unintentionally running against the wrong interpreter and introduced the 'ignore_basepython_conflict' value to opt into the correct behavior. Unfortunately, this has been broken in the move to tox 4. Currently, running with the above configuration will result in 'python3' being used for every environment. This is clearly incorrect. This issue stems from an errant bit of logic. When comparing interpreter versions as part of the '_validate_base_python', we ignore various attributes if they are unset on either '[testenv] base_python' or the 'pyXX' factor. This allows e.g. 'python3' to match 'python3.8', which isn't correct. Correct this by insisting on matching on all attributes that are set on the factor. [1] https://github.com/tox-dev/tox/issues/477 [2] https://github.com/tox-dev/tox/pull/841 Signed-off-by: Stephen Finucane Closes: #2754 --- src/tox/tox_env/python/api.py | 2 +- tests/tox_env/python/test_python_api.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tox/tox_env/python/api.py b/src/tox/tox_env/python/api.py index 9a8ff6ce3f..58e73ca21d 100644 --- a/src/tox/tox_env/python/api.py +++ b/src/tox/tox_env/python/api.py @@ -154,7 +154,7 @@ def _validate_base_python(env_name: str, base_pythons: list[str], ignore_base_py if any( getattr(spec_base, key) != getattr(spec_name, key) for key in ("implementation", "major", "minor", "micro", "architecture") - if getattr(spec_base, key) is not None and getattr(spec_name, key) is not None + if getattr(spec_name, key) is not None ): msg = f"env name {env_name} conflicting with base python {base_python}" if ignore_base_python_conflict: diff --git a/tests/tox_env/python/test_python_api.py b/tests/tox_env/python/test_python_api.py index 0520ff1733..b11c4376c9 100644 --- a/tests/tox_env/python/test_python_api.py +++ b/tests/tox_env/python/test_python_api.py @@ -95,6 +95,7 @@ def test_base_python_env_no_conflict(env: str, base_python: list[str], ignore_co ("py3", ["py2"], ["py2"]), ("py38", ["py39"], ["py39"]), ("py38", ["py38", "py39"], ["py39"]), + ("py38", ["python3"], ["python3"]), ("py310", ["py38", "py39"], ["py38", "py39"]), ("py3.11.1", ["py3.11.2"], ["py3.11.2"]), ("py3-64", ["py3-32"], ["py3-32"]),