uv icon indicating copy to clipboard operation
uv copied to clipboard

uv add fails due to interpreter-v4 cache missing invalidation

Open tlandschoff-scale opened this issue 6 months ago • 6 comments

Summary

First, thanks for uv, it is a great help for us. We used to use pip + virtualenv, and regularly ran into errors because a dev did not update the venv. uv run now takes care of this 😄

We are currently migrating toward using manylinux wheels (used to pip install everything from source) and ran into issues because the virtual environment $PROJECT/.venv is recreated without --system-site-packages, but uv does not catch that change.

Here is a transcript of the misbehavior on my Ubuntu noble system:

~/tmp/2025-05-14/broken$ uv init --python `which python3`
~/tmp/2025-05-14/broken$ uv python pin `which python3`
~/tmp/2025-05-14/broken$ uv venv --system-site-packages

# Fails as expected, system-site-packages disable manylinux wheels:

~/tmp/2025-05-14/broken$ uv add --no-build cffi==1.17.1
Using CPython 3.9.20 interpreter at: /opt/scalesdk/python39/bin/python3.9
Removed virtual environment at: .venv
Creating virtual environment at: .venv
Resolved 3 packages in 599ms
error: Distribution `cffi==1.17.1 @ registry+https://pypi.service.scale/simple/` can't be installed because it is marked as `--no-build` but has no binary distribution

# But after recreating the virtualenv without this issue, it should work

~/tmp/2025-05-14/broken$ rm -rf .venv/ && uv venv
~/tmp/2025-05-14/broken$ uv add --no-build cffi==1.17.1
Using CPython 3.9.20 interpreter at: /opt/scalesdk/python39/bin/python3.9
Removed virtual environment at: .venv
Creating virtual environment at: .venv
Resolved 3 packages in 615ms
error: Distribution `cffi==1.17.1 @ registry+https://pypi.service.scale/simple/` can't be installed because it is marked as `--no-build` but has no binary distribution

This appears to be a caching issue, it can be fixed by deleting the interpreter-v4 cache. Here is a Dockerfile based on Debian bookworm that reproduces the behavior:

FROM python:3.12-bookworm
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

RUN mkdir /workspace
WORKDIR /workspace

RUN echo "\
manylinux1_compatible = False\n\
manylinux2010_compatible = False\n\
manylinux2014_compatible = False\n\
def manylinux_compatible(*_, **__):\n\
    return False\n\
" > `python -c "import sysconfig;print(sysconfig.get_path('purelib'))"`/_manylinux.py
RUN cat `python -c "import sysconfig;print(sysconfig.get_path('purelib'))"`/_manylinux.py

RUN uv self version && python --version
RUN uv init --python `which python` && uv venv --system-site-packages
RUN uv add --no-build cffi==1.17.1 || true  # uv add fails: no binary
RUN rm -rf .venv && uv venv
RUN uv add --no-build cffi==1.17.1 || true  # fails again, why?
RUN rm -rf $HOME/.cache/uv/interpreter-v4
RUN uv add --no-build cffi==1.17.1  # works

Running it, I get this:

$ docker build . --progress plain --no-cache
[sudo] password for torsten.landschoff: 
#0 building with "default" instance using docker driver

#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 873B done
#1 DONE 0.0s

#2 [internal] load metadata for docker.io/library/python:3.12-bookworm
#2 ...

#3 [internal] load metadata for ghcr.io/astral-sh/uv:latest
#3 DONE 0.7s

#2 [internal] load metadata for docker.io/library/python:3.12-bookworm
#2 DONE 1.3s

#4 [internal] load .dockerignore
#4 transferring context: 2B done
#4 DONE 0.0s

#5 FROM ghcr.io/astral-sh/uv:latest@sha256:87a04222b228501907f487b338ca6fc1514a93369bfce6930eb06c8d576e58a4
#5 CACHED

#6 [stage-0  1/13] FROM docker.io/library/python:3.12-bookworm@sha256:4f13b45cdbbb834d3cc6c60abbd8f2923ad36e43a23a52769e07a6223c1fced7
#6 CACHED

#7 [stage-0  2/13] COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
#7 DONE 0.2s

#8 [stage-0  3/13] RUN mkdir /workspace
#8 DONE 0.3s

#9 [stage-0  4/13] WORKDIR /workspace
#9 DONE 0.0s

#10 [stage-0  5/13] RUN echo "manylinux1_compatible = False\nmanylinux2010_compatible = False\nmanylinux2014_compatible = False\ndef manylinux_compatible(*_, **__):\n    return False\n" > `python -c "import sysconfig;print(sysconfig.get_path('purelib'))"`/_manylinux.py
#10 DONE 0.3s

#11 [stage-0  6/13] RUN cat `python -c "import sysconfig;print(sysconfig.get_path('purelib'))"`/_manylinux.py
#11 0.207 manylinux1_compatible = False
#11 0.207 manylinux2010_compatible = False
#11 0.207 manylinux2014_compatible = False
#11 0.207 def manylinux_compatible(*_, **__):
#11 0.207     return False
#11 0.207 
#11 DONE 0.2s

#12 [stage-0  7/13] RUN uv self version && python --version
#12 0.189 uv 0.7.3
#12 0.193 Python 3.12.10
#12 DONE 0.2s

#13 [stage-0  8/13] RUN uv init --python `which python` && uv venv --system-site-packages
#13 0.379 Initialized project `workspace`
#13 0.536 Using CPython 3.12.10 interpreter at: /usr/local/bin/python3.12
#13 0.536 Creating virtual environment at: .venv
#13 DONE 0.6s

#14 [stage-0  9/13] RUN uv add --no-build cffi==1.17.1 || true  # uv add fails: no binary
#14 0.655 Resolved 3 packages in 254ms
#14 0.657 error: Distribution `cffi==1.17.1 @ registry+https://pypi.org/simple` can't be installed because it is marked as `--no-build` but has no binary distribution
#14 DONE 0.7s

#15 [stage-0 10/13] RUN rm -rf .venv && uv venv
#15 0.231 Using CPython 3.12.10 interpreter at: /usr/local/bin/python3.12
#15 0.231 Creating virtual environment at: .venv
#15 DONE 0.2s

#16 [stage-0 11/13] RUN uv add --no-build cffi==1.17.1 || true  # fails again, why?
#16 0.231 Resolved 3 packages in 10ms
#16 0.233 error: Distribution `cffi==1.17.1 @ registry+https://pypi.org/simple` can't be installed because it is marked as `--no-build` but has no binary distribution
#16 DONE 0.3s

#17 [stage-0 12/13] RUN rm -rf $HOME/.cache/uv/interpreter-v4
#17 DONE 0.3s

#18 [stage-0 13/13] RUN uv add --no-build cffi==1.17.1  # works
#18 0.422 Resolved 3 packages in 6ms
#18 0.592 Prepared 2 packages in 168ms
#18 0.604 Installed 2 packages in 12ms
#18 0.604  + cffi==1.17.1
#18 0.604  + pycparser==2.22
#18 DONE 0.6s

#19 exporting to image
#19 exporting layers
#19 exporting layers 0.4s done
#19 writing image sha256:6e804a371b654517435e1f3e79e950b3b5f6067ba26a488d1ce3f1af0ea40f62 done
#19 DONE 0.4s

The workaround to remove the interpreter cache helps us out here, but this happens for every developer that updates to our current main branch, and also during uv sync.

Platform

Debian bookworm (docker image python:3.12-bookworm)

Version

uv 0.7.3

Python version

Python 3.12.10

tlandschoff-scale avatar May 14 '25 07:05 tlandschoff-scale