Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
tomhampshire opened this issue Oct 18, 2024 · 6 comments
Open
Labels
bug Something isn't working

Comments

@tomhampshire
Copy link

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:

  • OS: both Arch Linux and Debian
Output of pip list of the host Python, where tox is installed
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
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
]
@tomhampshire tomhampshire added the bug Something isn't working label Oct 18, 2024
@lecode-official
Copy link

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
Copy link
Member

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.

@RomainBrault
Copy link
Contributor

I can reproduce.

pin to some python version and run a tox session with another python version.

E.g.

rm -rf .tox/
rm -rf .python-version
uv python pin 3.13
tox run -e py39-....

The error does not happen when the python version of the tox session matches the pinned python.

@RomainBrault
Copy link
Contributor

RomainBrault commented Nov 13, 2024

This fails:

FROM ghcr.io/astral-sh/uv:0.5.1-python3.13-bookworm@sha256:ae1bf2a1a69ef66cb179b9b7cf36da21ac2fac1145bc91e29ddb93d9f171ae3b
RUN mkdir debug && \
    cd debug && \
    uv init --python=3.12 && \
    uv sync && \
    echo "[tox]\n[testenv:py3{12,13}]\nrunner=uv-venv-lock-runner\ncommands=python hello.py" > tox.ini
RUN cd debug && uvx --with tox-uv==1.16.0 tox run -e py312
RUN cd debug && uvx --with tox-uv==1.16.0 tox run -e py313
Log
  ```shell
  #0 building with "default" instance using docker driver
  
  #1 [internal] load build definition from Dockerfile
  #1 transferring dockerfile: 471B done
  #1 DONE 0.0s
  
  #2 [internal] load metadata for ghcr.io/astral-sh/uv:0.5.1-python3.13-bookworm@sha256:ae1bf2a1a69ef66cb179b9b7cf36da21ac2fac1145bc91e29ddb93d9f171ae3b
  #2 DONE 0.0s
  
  #3 [internal] load .dockerignore
  #3 transferring context: 2B done
  #3 DONE 0.0s
  
  #4 [1/4] FROM ghcr.io/astral-sh/uv:0.5.1-python3.13-bookworm@sha256:ae1bf2a1a69ef66cb179b9b7cf36da21ac2fac1145bc91e29ddb93d9f171ae3b
  #4 CACHED
  
  #5 [2/4] RUN mkdir debug &&     cd debug &&     uv init --python=3.12 &&     uv sync &&     echo "[tox]\n[testenv:py3{12,13}]\nrunner=uv-venv-lock-runner\ncommands=python hello.py" > tox.ini
  #5 0.158 Initialized project `debug`
  #5 3.065 Using CPython 3.12.7
  #5 3.065 Creating virtual environment at: .venv
  #5 3.071 Resolved 1 package in 2ms
  #5 3.072 Audited in 0.00ms
  #5 DONE 3.2s
  
  #6 [3/4] RUN cd debug && uvx --with tox-uv==1.16.0 tox run -e py312
  #6 0.537 Installed 13 packages in 20ms
  #6 1.682 py312: venv> /root/.cache/uv/archive-v0/5Hhc8AB5YoaxXoYTcriq7/bin/uv venv -p /root/.cache/uv/archive-v0/5Hhc8AB5YoaxXoYTcriq7/bin/python --allow-existing /debug/.tox/py312
  #6 1.748 py312: uv-sync> uv sync --frozen --no-dev
  #6 1.805 py312: commands[0]> python hello.py
  #6 1.838 Hello from debug!
  #6 1.843   py312: OK (0.17=setup[0.13]+cmd[0.04] seconds)
  #6 1.843   congratulations :) (0.37 seconds)
  #6 DONE 2.0s
  
  #7 [4/4] RUN cd debug && uvx --with tox-uv==1.16.0 tox run -e py313
  #7 0.377 py313: venv> /root/.cache/uv/archive-v0/5Hhc8AB5YoaxXoYTcriq7/bin/uv venv -p 3.13 --allow-existing /debug/.tox/py313
  #7 0.393 py313: uv-sync> uv sync --frozen --no-dev
  #7 0.574 py313: internal error
  #7 0.574 Traceback (most recent call last):
  #7 0.574   File "/root/.cache/uv/archive-v0/5Hhc8AB5YoaxXoYTcriq7/lib/python3.12/site-packages/tox/session/cmd/run/single.py", line 47, in _evaluate
  #7 0.574     tox_env.setup()
  #7 0.574   File "/root/.cache/uv/archive-v0/5Hhc8AB5YoaxXoYTcriq7/lib/python3.12/site-packages/tox/tox_env/api.py", line 250, in setup
  #7 0.574     self._setup_env()
  #7 0.574   File "/root/.cache/uv/archive-v0/5Hhc8AB5YoaxXoYTcriq7/lib/python3.12/site-packages/tox_uv/_run_lock.py", line 77, in _setup_env
  #7 0.574     outcome = self.execute(cmd, stdin=StdinSource.OFF, run_id="uv-sync", show=show)
  #7 0.574               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  #7 0.574   File "/root/.cache/uv/archive-v0/5Hhc8AB5YoaxXoYTcriq7/lib/python3.12/site-packages/tox/tox_env/api.py", line 389, in execute
  #7 0.574     with self.execute_async(cmd, stdin, show, cwd, run_id, executor) as status:
  #7 0.574          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  #7 0.574   File "/root/.local/share/uv/python/cpython-3.12.7-linux-x86_64-gnu/lib/python3.12/contextlib.py", line 144, in __exit__
  #7 0.574     next(self.gen)
  #7 0.574   File "/root/.cache/uv/archive-v0/5Hhc8AB5YoaxXoYTcriq7/lib/python3.12/site-packages/tox/tox_env/api.py", line 443, in execute_async
  #7 0.574     self._log_execute(request, execute_status)
  #7 0.574   File "/root/.cache/uv/archive-v0/5Hhc8AB5YoaxXoYTcriq7/lib/python3.12/site-packages/tox/tox_env/api.py", line 449, in _log_execute
  #7 0.574     self._write_execute_log(self.name, self.env_log_dir / f"{self._log_id}-{request.run_id}.log", request, status)
  #7 0.574   File "/root/.cache/uv/archive-v0/5Hhc8AB5YoaxXoYTcriq7/lib/python3.12/site-packages/tox/tox_env/api.py", line 453, in _write_execute_log
  #7 0.574     with log_file.open("wt", encoding="utf-8") as file:
  #7 0.574          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  #7 0.574   File "/root/.local/share/uv/python/cpython-3.12.7-linux-x86_64-gnu/lib/python3.12/pathlib.py", line 1013, in open
  #7 0.574     return io.open(self, mode, buffering, encoding, errors, newline)
  #7 0.574            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  #7 0.574 FileNotFoundError: [Errno 2] No such file or directory: '/debug/.tox/py313/log/2-uv-sync.log'
  #7 0.575   py313: FAIL code 2 (0.20 seconds)
  #7 0.575   evaluation failed :( (0.25 seconds)
  #7 ERROR: process "/bin/sh -c cd debug && uvx --with tox-uv==1.16.0 tox run -e py313" did not complete successfully: exit code: 2
  ------
   > [4/4] RUN cd debug && uvx --with tox-uv==1.16.0 tox run -e py313:
  0.574     self._write_execute_log(self.name, self.env_log_dir / f"{self._log_id}-{request.run_id}.log", request, status)
  0.574   File "/root/.cache/uv/archive-v0/5Hhc8AB5YoaxXoYTcriq7/lib/python3.12/site-packages/tox/tox_env/api.py", line 453, in _write_execute_log
  0.574     with log_file.open("wt", encoding="utf-8") as file:
  0.574          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  0.574   File "/root/.local/share/uv/python/cpython-3.12.7-linux-x86_64-gnu/lib/python3.12/pathlib.py", line 1013, in open
  0.574     return io.open(self, mode, buffering, encoding, errors, newline)
  0.574            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  0.574 FileNotFoundError: [Errno 2] No such file or directory: '/debug/.tox/py313/log/2-uv-sync.log'
  0.575   py313: FAIL code 2 (0.20 seconds)
  0.575   evaluation failed :( (0.25 seconds)
  ------
  Dockerfile:8
  --------------------
     6 |         echo "[tox]\n[testenv:py3{12,13}]\nrunner=uv-venv-lock-runner\ncommands=python hello.py" > tox.ini
     7 |     RUN cd debug && uvx --with tox-uv==1.16.0 tox run -e py312
     8 | >>> RUN cd debug && uvx --with tox-uv==1.16.0 tox run -e py313
     9 |
  --------------------
  ERROR: failed to solve: process "/bin/sh -c cd debug && uvx --with tox-uv==1.16.0 tox run -e py313" did not complete successfully: exit code: 2
  ```

This works:

FROM ghcr.io/astral-sh/uv:0.5.1-python3.13-bookworm@sha256:ae1bf2a1a69ef66cb179b9b7cf36da21ac2fac1145bc91e29ddb93d9f171ae3b
RUN mkdir debug && \
    cd debug && \
    uv init --python=3.12 && \
    uv sync && \
    echo "[tox]\n[testenv:py3{12,13}]\nrunner=uv-venv-lock-runner\ncommands=python hello.py" > tox.ini
RUN cd debug && uvx --with tox-uv==1.16.0 tox run -e py312
RUN cd debug && rm .python-version && uvx --with tox-uv==1.16.0 tox run -e py313 && uv python pin 3.12
RUN cd debug && uvx --with tox-uv==1.16.0 tox run -e py313

Tested with Docker version 27.3.1, build ce12230 and command docker build . --no-cache --progress=plain.

@RomainBrault
Copy link
Contributor

RomainBrault commented Nov 22, 2024

I have a fix:

FROM ghcr.io/astral-sh/uv:0.5.4-python3.13-bookworm@sha256:c053e153740d87b1847cb201a23f7bb9267d66cf666d9009101b241bfef57eca
RUN mkdir debug && \
    cd debug && \
    uv init --python=3.12 && \
    uv sync && \
    uv tool install --with tox-uv==1.16.0 tox && \
    echo "[tox]\n[testenv:py3{12,13}]\nrunner=uv-venv-lock-runner\ncommands=python hello.py" > tox.ini
# FIX HERE
#
# we monkey patch with find + sed _run_lock.py
# remove the RUN line below and it should fail
#
RUN find /root/.local/share/uv/ -type f -name "_run_lock.py" -exec sed -i 's/cmd = \["uv", "sync", "--frozen"\]/cmd = ["uv", "sync", "-p", self.env_python(), "--frozen"]/g' {} +
########
RUN cd debug && /root/.local/bin/tox run -e py313

i.e:

in _run_lock.py line 63:

cmd = ["uv", "sync", "--frozen"]

replace

cmd = ["uv", "sync", "--frozen"]

with

cmd = ["uv", "sync", "-p", self.env_python(), "--frozen"]

I do not have time for a PR, I'll let someone else do it.

Note that #121 might be right. This fixes uv sync failing, probably due to a interpreter missing. But any time uv sync will fail for some other reason, the log creation will fail. As a result:

@RomainBrault
Copy link
Contributor

RomainBrault commented Nov 22, 2024

meanwhile one can also use

uv_sync_flags=--python={env_python}

Test:

FROM ghcr.io/astral-sh/uv:0.5.4-python3.13-bookworm@sha256:c053e153740d87b1847cb201a23f7bb9267d66cf666d9009101b241bfef57eca
RUN mkdir debug && \
    cd debug && \
    uv init --python=3.12 && \
    uv sync && \
    uv tool install --with tox-uv==1.16.0 tox && \
    echo "[tox]\n[testenv:py3{12,13}]\nrunner=uv-venv-lock-runner\ncommands=python hello.py\nuv_sync_flags=--python={env_python}" > tox.ini
RUN cd debug && /root/.local/bin/tox run -e py313

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants