Skip to content

2.32.0a1 uv resolver: remote cache hit can skip local venv_cache materialization #23344

Description

@henridwyer

Describe the bug
With Pants 2.32.0a1, [python].resolver = "uv", and remote cache reads enabled, a clean reader can get a cache hit for Create venv from uv lockfile ... without materializing the local venv_cache. A later PEX build then tries to execute .cache/venv_cache/.../bin/python and fails with No such file or directory.

This reproduces with Pants' experimental-file remote cache; I also saw the same failure with a REAPI/bazel-remote cache.

Pants version
2.32.0a1

OS
MacOS

Additional info

Minimal reproduction:

Create three files:

pants.toml

[GLOBAL]
pants_version = "2.32.0a1"
backend_packages = ["pants.backend.python"]
remote_provider = "experimental-file"
remote_store_address = "file:///tmp/pants-uv-remote-cache-repro"

[python]
enable_resolves = true
resolver = "uv"
interpreter_constraints = ["==3.12.*"]

[python.resolves]
python-default = "uv.lock"

requirements.txt

packaging>=24
typing-extensions>=4

test_smoke.py

from packaging.version import Version

def test_smoke():
    assert Version("1") < Version("2")

Generate BUILD and lockfile:

pants --no-pantsd tailor ::
pants --no-pantsd generate-lockfiles --resolve=python-default

Populate the remote cache:

rm -rf .pants.d ~/.cache/pants /tmp/pants-uv-remote-cache-repro
PANTS_REMOTE_CACHE_READ=false \
PANTS_REMOTE_CACHE_WRITE=true \
pants --no-pantsd test :tests0

Now edit test_smoke.py to add a second dependency from the same uv lockfile:

from packaging.version import Version
from typing_extensions import assert_never

def test_smoke():
    assert Version("1") < Version("2")
    assert assert_never

Read from remote cache with clean local state:

rm -rf .pants.d ~/.cache/pants
PANTS_REMOTE_CACHE_READ=true \
PANTS_REMOTE_CACHE_WRITE=false \
pants --no-pantsd test :tests0

Here I would expect pants to materialize the uv venv into local venv_cache, or avoid treating that venv creation process as remotely cacheable.

Actually, the second run fails:

Canceled: Create venv from uv lockfile at uv.lock
Completed: Building 2 requirements for requirements.pex from the uv.lock resolve: packaging>=24, typing-extensions>=4

IntrinsicError: Failed to execute: Process {
    argv: [
        ".cache/venv_cache/.../python-default/.../bin/python",
        "./pex",
        ...
        "--venv-repository=.cache/venv_cache/...",
    ],
    append_only_caches: {
        CacheName("venv_cache"): RelativePath(".cache/venv_cache"),
    },
    cache_scope: Successful,
}

Error launching process: Os { code: 2, kind: NotFound, message: "No such file or directory" }

The clean reader's named_caches/venv_cache exists but is empty.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions