tox-dev / tox-uv

Use https://github.com/astral-sh/uv with tox
MIT License
106 stars 17 forks source link

tox-uv (1.15) runs with Python 3.9, and fails with 3.10 and 3.11. #110

Open tomhampshire opened 5 days ago

tomhampshire commented 5 days ago

Issue

tox-uv (1.15) runs with Python 3.9, and fails with 3.10 and 3.11.

tox                                 ✘ 2 󰌠 3.10.15 (temperature-sensor) 12:47:24
py: venv> .venv/bin/uv venv -p /home/tom/code/GSP/temperature-sensor/.venv/bin/python --allow-existing /home/tom/code/GSP/temperature-sensor/.tox/py
py: uv-sync> uv sync --frozen --extra cli
py: internal error
Traceback (most recent call last):
  File "/home/tom/code/GSP/temperature-sensor/.venv/lib/python3.10/site-packages/tox/session/cmd/run/single.py", line 47, in _evaluate
    tox_env.setup()
  File "/home/tom/code/GSP/temperature-sensor/.venv/lib/python3.10/site-packages/tox/tox_env/api.py", line 249, in setup
    self._setup_env()
  File "/home/tom/code/GSP/temperature-sensor/.venv/lib/python3.10/site-packages/tox_uv/_run_lock.py", line 69, in _setup_env
    outcome = self.execute(cmd, stdin=StdinSource.OFF, run_id="uv-sync", show=show)
  File "/home/tom/code/GSP/temperature-sensor/.venv/lib/python3.10/site-packages/tox/tox_env/api.py", line 388, in execute
    with self.execute_async(cmd, stdin, show, cwd, run_id, executor) as status:
  File "/home/tom/.local/share/uv/python/cpython-3.10.15-linux-x86_64-gnu/lib/python3.10/contextlib.py", line 142, in __exit__
    next(self.gen)
  File "/home/tom/code/GSP/temperature-sensor/.venv/lib/python3.10/site-packages/tox/tox_env/api.py", line 442, in execute_async
    self._log_execute(request, execute_status)
  File "/home/tom/code/GSP/temperature-sensor/.venv/lib/python3.10/site-packages/tox/tox_env/api.py", line 448, in _log_execute
    self._write_execute_log(self.name, self.env_log_dir / f"{self._log_id}-{request.run_id}.log", request, status)
  File "/home/tom/code/GSP/temperature-sensor/.venv/lib/python3.10/site-packages/tox/tox_env/api.py", line 452, in _write_execute_log
    with log_file.open("wt", encoding="utf-8") as file:
  File "/home/tom/.local/share/uv/python/cpython-3.10.15-linux-x86_64-gnu/lib/python3.10/pathlib.py", line 1119, in open
    return self._accessor.open(self, mode, buffering, encoding, errors,
FileNotFoundError: [Errno 2] No such file or directory: '/home/tom/code/GSP/temperature-sensor/.tox/py/log/2-uv-sync.log'
  py: FAIL code 2 (0.08 seconds)
  evaluation failed :( (0.12 seconds)

Environment

Provide at least:

Output of pip list of the host Python, where tox is installed ```console Package Version Editable project location ---------------------- ---------------------------- ------------------------------------- annotated-types 0.7.0 appdirs 1.4.4 brotli 1.1.0 cachetools 5.5.0 care-data-structures 0.0.1.dev311+a72f30fb cffi 1.17.1 cfgv 3.4.0 chardet 5.2.0 click 8.1.7 colorama 0.4.6 contourpy 1.3.0 coverage 7.6.3 cssselect2 0.7.0 cycler 0.12.1 distlib 0.3.9 dominate 2.9.1 exceptiongroup 1.2.2 execnet 2.1.1 filelock 3.16.1 flexcache 0.3 flexparser 0.3.1 fonttools 4.54.1 gsp-report-gen 0.0.1.dev47+55802601 gsp-temperature-sensor 0.1.dev46+g39f98b7.d20241018 /home/tom/code/GSP/temperature-sensor html5lib 1.1 identify 2.6.1 iniconfig 2.0.0 kiwisolver 1.4.7 markdown-it-py 3.0.0 matplotlib 3.9.2 mdurl 0.1.2 mypy 1.12.0 mypy-extensions 1.0.0 nodeenv 1.9.1 numpy 1.26.4 packaging 24.1 pillow 11.0.0 pint 0.24.3 platformdirs 4.3.6 pluggy 1.5.0 pre-commit 3.8.0 pycparser 2.22 pydantic 2.9.2 pydantic-core 2.23.4 pydyf 0.11.0 pygments 2.18.0 pyparsing 3.2.0 pyphen 0.16.0 pyproject-api 1.8.0 pytest 8.3.3 pytest-cov 4.1.0 pytest-mock 3.14.0 pytest-xdist 3.6.1 python-dateutil 2.9.0.post0 pyyaml 6.0.2 rich 13.9.2 ruff 0.6.9 scipy 1.13.1 shellingham 1.5.4 six 1.16.0 tinycss2 1.3.0 tomli 2.0.2 tox 4.22.0 tox-uv 1.15.0 typer 0.12.5 typing-extensions 4.12.2 uv 0.4.22 virtualenv 20.26.6 weasyprint 62.3 webencodings 0.5.1 zopfli 0.2.3 ```

Output of running tox

Output of tox -rvv ```console tox -rvv 󰌠 3.10.15 (temperature-sensor) 12:49:09 py: 104 W remove tox env folder /home/tom/code/GSP/temperature-sensor/.tox/py [tox/tox_env/api.py:324] py: 140 W venv> .venv/bin/uv venv -p /home/tom/code/GSP/temperature-sensor/.venv/bin/python --allow-existing -v /home/tom/code/GSP/temperature-sensor/.tox/py [tox/tox_env/api.py:426] DEBUG uv 0.4.22 DEBUG Found project root: `/home/tom/code/GSP/temperature-sensor` DEBUG No workspace root found, using project root DEBUG Checking for Python interpreter at path `.venv/bin/python` Using CPython 3.10.15 interpreter at: .venv/bin/python Creating virtual environment at: .tox/py DEBUG Allowing existing directory py: 150 I exit 0 (0.01 seconds) /home/tom/code/GSP/temperature-sensor> .venv/bin/uv venv -p /home/tom/code/GSP/temperature-sensor/.venv/bin/python --allow-existing -v /home/tom/code/GSP/temperature-sensor/.tox/py pid=312894 [tox/execute/api.py:286] py: 150 W uv-sync> uv sync --frozen --extra cli -v [tox/tox_env/api.py:426] DEBUG uv 0.4.22 DEBUG Found project root: `/home/tom/code/GSP/temperature-sensor` DEBUG No workspace root found, using project root DEBUG Reading requests from `/home/tom/code/GSP/temperature-sensor/.python-version` DEBUG The virtual environment's Python version does not satisfy `Python 3.9` DEBUG Searching for Python 3.9 in managed installations or system path DEBUG Searching for managed installations at `/home/tom/.local/share/uv/python` DEBUG Skipping incompatible managed installation `cpython-3.11.10-linux-x86_64-gnu` DEBUG Skipping incompatible managed installation `cpython-3.10.15-linux-x86_64-gnu` DEBUG Found managed installation `cpython-3.9.20-linux-x86_64-gnu` DEBUG Found `cpython-3.9.20-linux-x86_64-gnu` at `/home/tom/.local/share/uv/python/cpython-3.9.20-linux-x86_64-gnu/bin/python3` (managed installations) Using CPython 3.9.20 Removed virtual environment at: .tox/py Creating virtual environment at: .tox/py DEBUG Using request timeout of 30s DEBUG Requirement already cached: annotated-types==0.7.0 DEBUG Requirement already cached: appdirs==1.4.4 DEBUG Requirement already cached: brotli==1.1.0 DEBUG Requirement already cached: cachetools==5.5.0 DEBUG Requirement already cached: care-data-structures==0.0.1.dev311+a72f30fb DEBUG Requirement already cached: cffi==1.17.1 DEBUG Requirement already cached: cfgv==3.4.0 DEBUG Requirement already cached: chardet==5.2.0 DEBUG Requirement already cached: click==8.1.7 DEBUG Requirement already cached: colorama==0.4.6 DEBUG Requirement already cached: contourpy==1.3.0 DEBUG Requirement already cached: coverage==7.6.3 DEBUG Requirement already cached: cssselect2==0.7.0 DEBUG Requirement already cached: cycler==0.12.1 DEBUG Requirement already cached: distlib==0.3.9 DEBUG Requirement already cached: dominate==2.9.1 DEBUG Requirement already cached: exceptiongroup==1.2.2 DEBUG Requirement already cached: execnet==2.1.1 DEBUG Requirement already cached: filelock==3.16.1 DEBUG Requirement already cached: flexcache==0.3 DEBUG Requirement already cached: flexparser==0.3.1 DEBUG Requirement already cached: fonttools==4.54.1 DEBUG Requirement already cached: gsp-report-gen==0.0.1.dev47+55802601 DEBUG Directory source requirement already cached: gsp-temperature-sensor==0.1.dev46+g39f98b7.d20241018 (from file:///home/tom/code/GSP/temperature-sensor) DEBUG Requirement already cached: html5lib==1.1 DEBUG Requirement already cached: identify==2.6.1 DEBUG Requirement already cached: importlib-resources==6.4.5 DEBUG Requirement already cached: iniconfig==2.0.0 DEBUG Requirement already cached: kiwisolver==1.4.7 DEBUG Requirement already cached: markdown-it-py==3.0.0 DEBUG Requirement already cached: matplotlib==3.9.2 DEBUG Requirement already cached: mdurl==0.1.2 DEBUG Requirement already cached: mypy==1.12.0 DEBUG Requirement already cached: mypy-extensions==1.0.0 DEBUG Requirement already cached: nodeenv==1.9.1 DEBUG Requirement already cached: numpy==1.26.4 DEBUG Requirement already cached: packaging==24.1 DEBUG Requirement already cached: pillow==11.0.0 DEBUG Requirement already cached: pint==0.24.3 DEBUG Requirement already cached: platformdirs==4.3.6 DEBUG Requirement already cached: pluggy==1.5.0 DEBUG Requirement already cached: pre-commit==3.8.0 DEBUG Requirement already cached: pycparser==2.22 DEBUG Requirement already cached: pydantic==2.9.2 DEBUG Requirement already cached: pydantic-core==2.23.4 DEBUG Requirement already cached: pydyf==0.11.0 DEBUG Requirement already cached: pygments==2.18.0 DEBUG Requirement already cached: pyparsing==3.2.0 DEBUG Requirement already cached: pyphen==0.16.0 DEBUG Requirement already cached: pyproject-api==1.8.0 DEBUG Requirement already cached: pytest==8.3.3 DEBUG Requirement already cached: pytest-cov==4.1.0 DEBUG Requirement already cached: pytest-mock==3.14.0 DEBUG Requirement already cached: pytest-xdist==3.6.1 DEBUG Requirement already cached: python-dateutil==2.9.0.post0 DEBUG Requirement already cached: pyyaml==6.0.2 DEBUG Requirement already cached: rich==13.9.2 DEBUG Requirement already cached: ruff==0.6.9 DEBUG Requirement already cached: scipy==1.13.1 DEBUG Requirement already cached: shellingham==1.5.4 DEBUG Requirement already cached: six==1.16.0 DEBUG Requirement already cached: tinycss2==1.3.0 DEBUG Requirement already cached: tomli==2.0.2 DEBUG Requirement already cached: tox==4.22.0 DEBUG Requirement already cached: tox-uv==1.15.0 DEBUG Requirement already cached: typer==0.12.5 DEBUG Requirement already cached: typing-extensions==4.12.2 DEBUG Requirement already cached: uv==0.4.22 DEBUG Requirement already cached: virtualenv==20.26.6 DEBUG Requirement already cached: weasyprint==62.3 DEBUG Requirement already cached: webencodings==0.5.1 DEBUG Requirement already cached: zipp==3.20.2 DEBUG Requirement already cached: zopfli==0.2.3 Installed 73 packages in 28ms + annotated-types==0.7.0 + appdirs==1.4.4 + brotli==1.1.0 + cachetools==5.5.0 + care-data-structures==0.0.1.dev311+a72f30fb + cffi==1.17.1 + cfgv==3.4.0 + chardet==5.2.0 + click==8.1.7 + colorama==0.4.6 + contourpy==1.3.0 + coverage==7.6.3 + cssselect2==0.7.0 + cycler==0.12.1 + distlib==0.3.9 + dominate==2.9.1 + exceptiongroup==1.2.2 + execnet==2.1.1 + filelock==3.16.1 + flexcache==0.3 + flexparser==0.3.1 + fonttools==4.54.1 + gsp-report-gen==0.0.1.dev47+55802601 + gsp-temperature-sensor==0.1.dev46+g39f98b7.d20241018 (from file:///home/tom/code/GSP/temperature-sensor) + html5lib==1.1 + identify==2.6.1 + importlib-resources==6.4.5 + iniconfig==2.0.0 + kiwisolver==1.4.7 + markdown-it-py==3.0.0 + matplotlib==3.9.2 + mdurl==0.1.2 + mypy==1.12.0 + mypy-extensions==1.0.0 + nodeenv==1.9.1 + numpy==1.26.4 + packaging==24.1 + pillow==11.0.0 + pint==0.24.3 + platformdirs==4.3.6 + pluggy==1.5.0 + pre-commit==3.8.0 + pycparser==2.22 + pydantic==2.9.2 + pydantic-core==2.23.4 + pydyf==0.11.0 + pygments==2.18.0 + pyparsing==3.2.0 + pyphen==0.16.0 + pyproject-api==1.8.0 + pytest==8.3.3 + pytest-cov==4.1.0 + pytest-mock==3.14.0 + pytest-xdist==3.6.1 + python-dateutil==2.9.0.post0 + pyyaml==6.0.2 + rich==13.9.2 + ruff==0.6.9 + scipy==1.13.1 + shellingham==1.5.4 + six==1.16.0 + tinycss2==1.3.0 + tomli==2.0.2 + tox==4.22.0 + tox-uv==1.15.0 + typer==0.12.5 + typing-extensions==4.12.2 + uv==0.4.22 + virtualenv==20.26.6 + weasyprint==62.3 + webencodings==0.5.1 + zipp==3.20.2 + zopfli==0.2.3 py: 208 E internal error [tox/session/cmd/run/single.py:60] Traceback (most recent call last): File "/home/tom/code/GSP/temperature-sensor/.venv/lib/python3.10/site-packages/tox/session/cmd/run/single.py", line 47, in _evaluate tox_env.setup() File "/home/tom/code/GSP/temperature-sensor/.venv/lib/python3.10/site-packages/tox/tox_env/api.py", line 249, in setup self._setup_env() File "/home/tom/code/GSP/temperature-sensor/.venv/lib/python3.10/site-packages/tox_uv/_run_lock.py", line 69, in _setup_env outcome = self.execute(cmd, stdin=StdinSource.OFF, run_id="uv-sync", show=show) File "/home/tom/code/GSP/temperature-sensor/.venv/lib/python3.10/site-packages/tox/tox_env/api.py", line 388, in execute with self.execute_async(cmd, stdin, show, cwd, run_id, executor) as status: File "/home/tom/.local/share/uv/python/cpython-3.10.15-linux-x86_64-gnu/lib/python3.10/contextlib.py", line 142, in __exit__ next(self.gen) File "/home/tom/code/GSP/temperature-sensor/.venv/lib/python3.10/site-packages/tox/tox_env/api.py", line 442, in execute_async self._log_execute(request, execute_status) File "/home/tom/code/GSP/temperature-sensor/.venv/lib/python3.10/site-packages/tox/tox_env/api.py", line 448, in _log_execute self._write_execute_log(self.name, self.env_log_dir / f"{self._log_id}-{request.run_id}.log", request, status) File "/home/tom/code/GSP/temperature-sensor/.venv/lib/python3.10/site-packages/tox/tox_env/api.py", line 452, in _write_execute_log with log_file.open("wt", encoding="utf-8") as file: File "/home/tom/.local/share/uv/python/cpython-3.10.15-linux-x86_64-gnu/lib/python3.10/pathlib.py", line 1119, in open return self._accessor.open(self, mode, buffering, encoding, errors, FileNotFoundError: [Errno 2] No such file or directory: '/home/tom/code/GSP/temperature-sensor/.tox/py/log/2-uv-sync.log' py: FAIL code 2 (0.10 seconds) evaluation failed :( (0.14 seconds) ```

Minimal example

tox.ini contents:
[cicd]
python =
    3.9: py39
    3.10: py310
    3.11: py311

[testenv]
runner = uv-venv-lock-runner
extras =
    cli
with_dev = true
commands =
    pytest --cov --cov-config=pyproject.toml
    ruff check
    mypy src

pyproject.toml:

[build-system]
requires = ["setuptools>=64", "setuptools_scm>=8", "wheel"]
build-backend = "setuptools.build_meta"

[project]
dynamic = ["version"]
name = "gsp-temperature-sensor"
description = ""
requires-python = '>=3.9'
authors = []
readme = "README.md"
urls = { Homepage = "https://goldstandardphantoms.com" }

dependencies = [
  "numpy == 1.*",
  "pydantic == 2.*",
  "matplotlib == 3.*",
  "typer[all] == 0.*",
  "pint == 0.*",
  "scipy == 1.*",
]

[tool.mypy]
plugins = ["pydantic.mypy", "numpy.typing.mypy_plugin"]
files = ["src/gsp_temperature_sensor"]
disallow_untyped_defs = true
disallow_any_unimported = true
no_implicit_optional = true
check_untyped_defs = true
warn_return_any = true
warn_unused_ignores = true
show_error_codes = true

[[tool.mypy.overrides]]
module = "setuptools.*,scipy.*,matplotlib.*"
ignore_missing_imports = true

[tool.pydantic-mypy]
init_forbid_extra = true
init_typed = true
warn_required_dynamic_aliases = true
warn_untyped_fields = true

[tool.uv]
dev-dependencies = [
  "pre-commit~=3.7",
  "pytest~=8.1",
  "pytest-cov~=4.1",
  "pytest-xdist~=3.5",
  "pytest-mock~=3.14",
  "tox-uv~=1.11",
  "mypy~=1.0",
  "ruff~=0.6",
]

[tool.setuptools]
package-dir = { "" = "src" }
package-data = { "gsp_temperature_sensor" = [
  "py.typed",
  "resources/functions_temperature_u.png",
  "resources/functions_temperature_calculation.png",
] }

[tool.setuptools_scm]

[tool.ruff]
fix = true

# Enable recommended rules
lint.select = [
  "E",    # pycodestyle errors
  "F",    # pyflakes
  "W",    # pycodestyle warnings
  "C90",  # mccabe
  "I",    # isort
  "N",    # pep8-naming
  "D",    # pydocstyle
  "D204", # blank like after class docstring
  "UP",   # pyupgrade
  "YTT",  # flake8-2020
  "ANN",  # flake8-annotations
  "S",    # flake8-bandit
  "BLE",  # flake8-blind-except
  "FBT",  # flake8-boolean-trap
  "B",    # flake8-bugbear
  "A",    # flake8-builtins
  "COM",  # flake8-commas
  "C4",   # flake8-comprehensions
  "DTZ",  # flake8-datetimez
  "T10",  # flake8-debugger
  "DJ",   # flake8-django
  "EM",   # flake8-errmsg
  "EXE",  # flake8-executable
  "ISC",  # flake8-implicit-str-concat
  "ICN",  # flake8-import-conventions
  "G",    # flake8-logging-format
  "INP",  # flake8-no-pep420
  "PIE",  # flake8-pie
  "T20",  # flake8-print
  "PYI",  # flake8-pyi
  "PT",   # flake8-pytest-style
  "Q",    # flake8-quotes
  "RSE",  # flake8-raise
  "RET",  # flake8-return
  "SLF",  # flake8-self
  "SIM",  # flake8-simplify
  "TID",  # flake8-tidy-imports
  "TCH",  # flake8-type-checking
  "ARG",  # flake8-unused-arguments
  "PTH",  # flake8-use-pathlib
  "ERA",  # eradicate
  "PD",   # pandas-vet
  "PGH",  # pygrep-hooks
  "PL",   # Pylint
  "TRY",  # tryceratops
  "RUF",  # Ruff-specific rules
]

lint.ignore = [
  #Ignores allowable in all repos
  "E501",   # Never enforce `E501` (line length violations)
  "ANN101", # Ignore missing self type as this rule is deprecated
  "ANN102", #complaint over type cls - deprecated rule
  "ANN401", # Dynamically typed expressions (typing.Any)
  "PYI041", # complaints about int | float
  "C901",   #disable errors on complexity
  "SLF001", #private member accessed
  "PGH003", # instead of specific rules when ignoring type cases
  "E741",   # complaints about I as variable name
  "N806",   # complaints about capital in variable
  "PT011",  # complaint that raises(ValueError too broad)#Ruff errors that we should fix during migration.
  "ERA001", # found commented out code
  "S324",   # security check for hashlib function
  "PT013",  #complains when from pytest import
  "D205",   #Blank line after docstring summary
]

# Allow autofix for all enabled rules (when `--fix`) is provided
lint.fixable = [
  "A",
  "B",
  "C",
  "D",
  "E",
  "F",
  "G",
  "I",
  "N",
  "Q",
  "S",
  "T",
  "W",
  "ANN",
  "ARG",
  "BLE",
  "COM",
  "DJ",
  "DTZ",
  "EM",
  "ERA",
  "EXE",
  "FBT",
  "ICN",
  "INP",
  "ISC",
  "NPY",
  "PD",
  "PGH",
  "PIE",
  "PL",
  "PT",
  "PTH",
  "PYI",
  "RET",
  "RSE",
  "RUF",
  "SIM",
  "SLF",
  "TCH",
  "TID",
  "TRY",
  "UP",
  "YTT",
]

lint.unfixable = []

# Exclude a variety of commonly ignored directories
lint.exclude = [
  ".bzr",
  ".direnv",
  ".eggs",
  ".git",
  ".hg",
  ".mypy_cache",
  ".nox",
  ".pants.d",
  ".pytype",
  ".ruff_cache",
  ".svn",
  ".tox",
  ".venv",
  "__pypackages__",
  "_build",
  "buck-out",
  "build",
  "dist",
  "node_modules",
  "venv",
]

#Temporary- remove before merge
exclude = ["docs/**"]

# Allow unused variables when underscore-prefixed
lint.dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

# Assume Python 3.9
target-version = "py39"

[tool.ruff.lint.pydocstyle]
convention = "google"

[tool.ruff.lint.pylint]
max-args = 5
max-returns = 3

[tool.ruff.lint.flake8-quotes]
docstring-quotes = "double"
inline-quotes = "double"

[tool.ruff.lint.pep8-naming]
classmethod-decorators = ["classmethod", "pydantic.validator"]

[tool.ruff.lint.per-file-ignores]
"test_*.py" = ["S101"]

[tool.ruff.lint.flake8-bugbear]
# Allow default arguments like,
# e.g., `log_file: Path = typer.Argument(..., help="Path to the log file")`
extend-immutable-calls = ["typer.Argument", "typer.Option"]

[tool.ruff.lint.flake8-type-checking]
# Exempt classes that list any of the enumerated classes as a base class from needing
# to be moved into type-checking blocks.
runtime-evaluated-base-classes = ["pydantic.BaseModel"]

[tool.ruff.lint.extend-per-file-ignores]
"test_*.py" = [
  "PLR2004", # allow magic numbers in tests
]
lecode-official commented 5 days ago

I am facing the exact same issue, except that I am targeting Python 3.10 - 3.13 and only 3.13 works. This only happens when using the uv-venv-lock-runner. I do not get this error with uv-venv-runner.

gaborbernat commented 4 days ago

Can you provide a reproducible using a docker image? That way I can reproduce it on my machine and easier to fix it and understand what's happening.