Skip to content

Commit

Permalink
Revert to supporting simple Python factors (#2849)
Browse files Browse the repository at this point in the history
Co-authored-by: Bernát Gábor <bgabor8@bloomberg.net>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Fixes #2657
Fixes #2848
  • Loading branch information
stephenfin committed Jan 11, 2023
1 parent 34b79a2 commit 9f89f51
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 39 deletions.
3 changes: 2 additions & 1 deletion .github/ISSUE_TEMPLATE/feature-request.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ assignees: ""

## Alternative Solutions

<!-- Have you tried to workaround the problem using tox or other tools? Or a different approach to solving this issue? Please elaborate here. -->
<!-- Have you tried to workaround the problem using tox or other tools? Or a different approach to solving this issue?
Please elaborate here. -->

## Additional context

Expand Down
12 changes: 2 additions & 10 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,10 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.py }}
- name: Pick environment to run
run: |
import os; import platform; import sys; from pathlib import Path
env = f'TOXENV=py{"" if platform.python_implementation() == "CPython" else "py"}3{sys.version_info.minor}'
print(f"Picked: {env} for {sys.version} based of {sys.executable}")
with Path(os.environ["GITHUB_ENV"]).open("ta") as file_handler:
file_handler.write(env)
shell: python
- name: Setup test suite
run: tox r -vv --notest
run: tox r -e py${{ matrix.py }} -vv --notest
- name: Run test suite
run: tox r --skip-pkg-install
run: tox r -e py${{ matrix.py }} --skip-pkg-install
env:
CI_RUN: "yes"
DIFF_AGAINST: HEAD
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ repos:
hooks:
- id: rst-backticks
- repo: https://github.com/tox-dev/tox-ini-fmt
rev: "0.5.2"
rev: "0.6.0"
hooks:
- id: tox-ini-fmt
args: ["-p", "fix"]
Expand All @@ -69,7 +69,7 @@ repos:
- "@prettier/plugin-xml@2.2"
args: ["--print-width=120", "--prose-wrap=always"]
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.32.2
rev: v0.33.0
hooks:
- id: markdownlint
- repo: local
Expand Down
6 changes: 6 additions & 0 deletions docs/changelog/2848.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
tox has reverted support for Python factors that include PATCH release info (e.g. ``py3.10.1``), build architecture
(e.g. ``pypy3-64``) or do not define a ``py`` prefix or other supported prefix (e.g. ``3.10``). These complex factors
were initially supported with the release of tox 4.0 but has proven complicated to support. Instead, the simple factors
supported by tox 3 e.g. (``py310``, ``pypy3``) or period-separated equivalent (``py3.10``) introduced in tox 4 should be
used. Users who wish to specify more specific Python version information should configure the :ref:`base_python` setting
- by :user:`stephenfin`.
18 changes: 9 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[build-system]
build-backend = "hatchling.build"
requires = ["hatchling>=1.12", "hatch-vcs>=0.3"]
requires = ["hatchling>=1.12.2", "hatch-vcs>=0.3"]

[project]
name = "tox"
Expand All @@ -22,24 +22,24 @@ maintainers = [
]
requires-python = ">=3.7"
dependencies = [
"cachetools>=5.2",
"cachetools>=5.2.1",
"chardet>=5.1",
"colorama>=0.4.6",
"packaging>=22",
"packaging>=23",
"platformdirs>=2.6.2",
"pluggy>=1",
"pyproject-api>=1.2.1",
"pyproject-api>=1.4",
'tomli>=2.0.1; python_version < "3.11"',
"virtualenv>=20.17.1",
"filelock>=3.9",
'importlib-metadata>=5.2; python_version < "3.8"',
'importlib-metadata>=6; python_version < "3.8"',
'typing-extensions>=4.4; python_version < "3.8"',
]
optional-dependencies.docs = [
"furo>=2022.12.7",
"sphinx>=6",
"sphinx-argparse-cli>=1.10",
"sphinx-autodoc-typehints>=1.19.5",
"sphinx>=6.1.3",
"sphinx-argparse-cli>=1.11",
"sphinx-autodoc-typehints>=1.20.1",
"sphinx-copybutton>=0.5.1",
"sphinx-inline-tabs>=2022.1.2b11",
"sphinxcontrib-towncrier>=0.2.1a0",
Expand All @@ -53,7 +53,7 @@ optional-dependencies.testing = [
"distlib>=0.3.6",
"flaky>=3.7",
"hatch-vcs>=0.3",
"hatchling>=1.12",
"hatchling>=1.12.2",
"psutil>=5.9.4",
"pytest>=7.2",
"pytest-cov>=4",
Expand Down
17 changes: 13 additions & 4 deletions src/tox/tox_env/python/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
from __future__ import annotations

import logging
import re
import sys
from abc import ABC, abstractmethod
from pathlib import Path
from typing import Any, List, NamedTuple, cast

from packaging.tags import INTERPRETER_SHORT_NAMES
from virtualenv.discovery.py_spec import PythonSpec

from tox.config.main import Config
Expand Down Expand Up @@ -47,6 +47,16 @@ def version_dot(self) -> str:
return f"{self.version_info.major}.{self.version_info.minor}"


PY_FACTORS_RE = re.compile(
r"""
^(?!py$) # don't match 'py' as it doesn't provide any info
(?P<impl>py|pypy|cpython|jython|rustpython|ironpython) # the interpeter; most users will simply use 'py'
(?P<version>[2-9]\.?[0-9]?[0-9]?)?$ # the version; one of: MAJORMINOR, MAJOR.MINOR
""",
re.VERBOSE,
)


class Python(ToxEnv, ABC):
def __init__(self, create_args: ToxEnvCreateArgs) -> None:
self._base_python: PythonInfo | None = None
Expand Down Expand Up @@ -131,9 +141,8 @@ def default_base_python(self, conf: Config, env_name: str | None) -> list[str]:
def extract_base_python(cls, env_name: str) -> str | None:
candidates: list[str] = []
for factor in env_name.split("-"):
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:
match = PY_FACTORS_RE.match(factor)
if match:
candidates.append(factor)
if candidates:
if len(candidates) > 1:
Expand Down
37 changes: 31 additions & 6 deletions tests/tox_env/python/test_python_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,36 @@ def test_diff_msg_no_diff() -> None:
assert Python._diff_msg({}, {}) == "python "


@pytest.mark.parametrize(
("env", "base_python"),
[
("py3", "py3"),
("py311", "py311"),
("py3.12", "py3.12"),
("pypy2", "pypy2"),
("rustpython3", "rustpython3"),
("cpython3.8", "cpython3.8"),
("ironpython2.7", "ironpython2.7"),
("functional-py310", "py310"),
("bar-pypy2-foo", "pypy2"),
("py", None),
("django-32", None),
("eslint-8.3", None),
("py-310", None),
("py3000", None),
("4.foo", None),
("310", None),
("5", None),
("2000", None),
("4000", None),
],
ids=lambda a: "|".join(a) if isinstance(a, list) else str(a),
)
def test_extract_base_python(env: str, base_python: str | None) -> None:
result = Python.extract_base_python(env)
assert result == base_python


@pytest.mark.parametrize("ignore_conflict", [True, False])
@pytest.mark.parametrize(
("env", "base_python"),
Expand All @@ -89,16 +119,14 @@ def test_base_python_env_no_conflict(env: str, base_python: list[str], ignore_co
@pytest.mark.parametrize(
("env", "base_python", "expected", "conflict"),
[
("cpython", ["pypy"], "cpython", ["pypy"]),
("pypy", ["cpython"], "pypy", ["cpython"]),
("pypy2", ["pypy3"], "pypy2", ["pypy3"]),
("py3", ["py2"], "py3", ["py2"]),
("py38", ["py39"], "py38", ["py39"]),
("py38", ["py38", "py39"], "py38", ["py39"]),
("py38", ["python3"], "py38", ["python3"]),
("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"]),
("py3.11", ["py310"], "py3.11", ["py310"]),
("py310-magic", ["py39"], "py310", ["py39"]),
],
ids=lambda a: "|".join(a) if isinstance(a, list) else str(a),
Expand All @@ -110,9 +138,6 @@ def test_base_python_env_conflict(
conflict: list[str],
ignore_conflict: bool,
) -> None:
if env == "py3-64":
raise pytest.skip("bug #2657")

if ignore_conflict:
result = Python._validate_base_python(env, base_python, ignore_conflict)
assert result == [expected]
Expand Down
12 changes: 6 additions & 6 deletions tests/tox_env/python/virtual_env/test_virtualenv_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ def virtualenv_opt(monkeypatch: MonkeyPatch, mocker: MockerFixture) -> VirtualEn

def test_virtualenv_default_settings(tox_project: ToxProjectCreator, virtualenv_opt: VirtualEnvOptions) -> None:
proj = tox_project({"tox.ini": "[testenv]\npackage=skip"})
result = proj.run("r", "-e", "py", "--discover", sys.executable, str(proj.path / "a"))
result = proj.run("r", "-e", "py3", "--discover", sys.executable, str(proj.path / "a"))
result.assert_success()

conf = result.env_conf("py")
conf = result.env_conf("py3")
assert conf["system_site_packages"] is False
assert conf["always_copy"] is False
assert conf["download"] is False
Expand All @@ -46,7 +46,7 @@ def test_virtualenv_default_settings(tox_project: ToxProjectCreator, virtualenv_
assert virtualenv_opt.download is False
assert virtualenv_opt.copies is False
assert virtualenv_opt.no_periodic_update is True
assert virtualenv_opt.python == ["py"]
assert virtualenv_opt.python == ["py3"]
assert virtualenv_opt.try_first_with == [str(sys.executable), str(proj.path / "a")]


Expand All @@ -60,10 +60,10 @@ def test_virtualenv_flipped_settings(
)
monkeypatch.setenv("VIRTUALENV_CLEAR", "0")

result = proj.run("r", "-e", "py")
result = proj.run("r", "-e", "py3")
result.assert_success()

conf = result.env_conf("py")
conf = result.env_conf("py3")
assert conf["system_site_packages"] is True
assert conf["always_copy"] is True
assert conf["download"] is True
Expand All @@ -72,7 +72,7 @@ def test_virtualenv_flipped_settings(
assert virtualenv_opt.system_site is True
assert virtualenv_opt.download is True
assert virtualenv_opt.copies is True
assert virtualenv_opt.python == ["py"]
assert virtualenv_opt.python == ["py3"]


def test_virtualenv_env_ignored_if_set(
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ description = do a release, required posarg of the version number
skip_install = true
deps =
gitpython>=3.1.30
packaging>=22
packaging>=23
towncrier>=22.12
commands =
python {toxinidir}/tasks/release.py --version {posargs}
Expand Down

0 comments on commit 9f89f51

Please sign in to comment.