Skip to content

[Bug]: uv based venv generator creates .venv not usable with uv #895

Description

@ha1dfo

What happened?

I've got an environment that's mocked here.
I had previous ticket on venv generation here.

I am generating the .venv so that my IDE (vscode) can pick it up.
Vscode uses uv pip list --python=<path> to parse the .venv.

However, when generating a .venv with aspect_rules_py, it creates one that's not parseable by uv.

When looking at it with strace, I can see that it prints that we've got python 3.13 and nothing more.

$ strace -ff -o /tmp/uvpip uv pip list --python .<...>+orchestrator.venv/bin/python
Using Python 3.13.12 environment at: /home/<USER>/.cache/bazel/_bazel_<USER>/09e1a13f6e7dc94649c8d65787235f07/execroot/_main/bazel-out/k8-fastbuild-ST-f38e6014d46d/bin/<...>/orchestrator.venv.runfiles/_main/<...>/.orchestrator.venv

We do have a pyvenv.cfg:

unix_users  359 Mar 26 06:44 pyvenv.cfg
$ cat /home/<USER>/repos/<repo>/.<...>+orchestrator.venv/pyvenv.cfg
home = ./bin/
implementation = CPython
version_info = 3.13.0
include-system-site-packages = false
aspect-include-user-site-packages = false
relocatable = true
# Non-standard extension keys used by the Aspect shim
aspect-runfiles-interpreter = aspect_rules_py++python_interpreters+python_3_13_x86_64_unknown_linux_gnu/bin/python3
aspect-runfiles-repo = _main

But uv pip list fails:

$ uv pip list --python /home/<USER>/repos/<REPO>/.venv/bin/python
Using Python 3.13.12 environment at: /home/<USER>/.cache/bazel/_bazel_<USER>/09e1a13f6e7dc94649c8d65787235f07/execroot/_main/bazel-out/k8-fastbuild-ST-f38e6014d46d/bin/<...>/venv.runfiles/_main/<...>/.venv

Strace:

$ strace -ff -o /tmp/uvpip uv pip list --python .<...>+orchestrator.venv/bin/python
Using Python 3.13.12 environment at: /home/<USER>/.cache/bazel/_bazel_<USER>/09e1a13f6e7dc94649c8d65787235f07/execroot/_main/bazel-out/k8-fastbuild-ST-f38e6014d46d/bin/<...>/orchestrator.venv.runfiles/_main/<...>/.orchestrator.venv

It finds the proper directory: lib/python3.13/site-packages, but then the process exits:

statx(AT_FDCWD, "/home/<USER>/.local/share/uv", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFDIR|0775, stx_size=4096, ...}) = 0
getcwd("/home/<USER>/repos/<REPO>", 512) = 26
ioctl(2, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(2, TCGETS, {B38400 opost isig icanon echo ...}) = 0
write(2, "\33[2m", 4)                   = 4
ioctl(2, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(2, TCGETS, {B38400 opost isig icanon echo ...}) = 0
write(2, "Using Python 3.13.12 environment"..., 285) = 285
ioctl(2, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(2, TCGETS, {B38400 opost isig icanon echo ...}) = 0
write(2, "\33[0m", 4)                   = 4
ioctl(2, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(2, TCGETS, {B38400 opost isig icanon echo ...}) = 0
write(2, "\n", 1)                       = 1
openat(AT_FDCWD, "/home/<USER>/.cache/bazel/_bazel_<USER>/09e1a13f6e7dc94649c8d65787235f07/execroot/_main/bazel-out/k8-fastbuild-ST-f38e6014d46d/bin/<...>/orchestrator.venv.runfiles/_main/<...>/.orchestrator.venv/lib/python3.13/site-packages", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 10
newfstatat(10, "", {st_mode=S_IFDIR|0555, st_size=4096, ...}, AT_EMPTY_PATH) = 0
getdents64(10, 0x7f8038000f40 /* 74 entries */, 32768) = 3096
getdents64(10, 0x7f8038000f40 /* 0 entries */, 32768) = 0
close(10)                               = 0

Normally I would chalk this up as an uv failure, however, the main purpose of the uv based venv generation is to create one that's usable with uv, so I'm playing my luck and ask for help here.

To make things more interesting, when I'm trying to repro this with the mock repo, I am not even getting that far, not even the python3.13 is found:

$ strace -ff -o /tmp/uvpip uv pip list --python /home/<USER>/repos/repro-py-proto/.application+apple.venv

The strace details say we're trying to run a mock script (i guess it must be like what ./configure used to be before bazel), it fails on loading encodings.

(...)
stat("/install/lib/python313.zip", 0x7ffcd1f596d8) = -1 ENOENT (No such file or directory)
stat("/install/lib", 0x7ffcd1f59708)    = -1 ENOENT (No such file or directory)
stat("/install", 0x7ffcd1f59708)        = -1 ENOENT (No such file or directory)
stat("", 0x7ffcd1f59708)                = -1 ENOENT (No such file or directory)
stat("/install/lib/python313.zip", 0x7ffcd1f59a08) = -1 ENOENT (No such file or directory)
stat("/install/lib/python3.13", 0x7ffcd1f59708) = -1 ENOENT (No such file or directory)
stat("/install/lib", 0x7ffcd1f59708)    = -1 ENOENT (No such file or directory)
stat("/install", 0x7ffcd1f59708)        = -1 ENOENT (No such file or directory)
stat("", 0x7ffcd1f59708)                = -1 ENOENT (No such file or directory)
stat("/install/lib/python3.13", 0x7ffcd1f59a08) = -1 ENOENT (No such file or directory)
stat("/install/lib/python3.13/lib-dynload", 0x7ffcd1f59708) = -1 ENOENT (No such file or directory)
stat("/install/lib/python3.13", 0x7ffcd1f59708) = -1 ENOENT (No such file or directory)
stat("/install/lib", 0x7ffcd1f59708)    = -1 ENOENT (No such file or directory)
stat("/install", 0x7ffcd1f59708)        = -1 ENOENT (No such file or directory)
stat("", 0x7ffcd1f59708)                = -1 ENOENT (No such file or directory)
stat("/install/lib/python3.13/lib-dynload", 0x7ffcd1f59a08) = -1 ENOENT (No such file or directory)
write(2, "Fatal Python error: ", 20)    = 20
write(2, "Failed to import encodings modul"..., 33) = 33
write(2, "\n", 1)                       = 1
write(2, "Python runtime state: ", 22)  = 22
write(2, "core initialized", 16)        = 16
write(2, "\n", 1)                       = 1
write(2, "ModuleNotFoundError", 19)     = 19
write(2, ": ", 2)                       = 2
write(2, "No module named 'encodings'", 27) = 27
write(2, "\n", 1)                       = 1
write(2, "\n", 1)                       = 1
write(2, "Current thread 0x", 17)       = 17
write(2, "00007f1721ee9740", 16)        = 16
write(2, " (most recent call first):\n", 27) = 27
write(2, "  <no Python frame>\n", 20)   = 20
exit_group(1)                           = ?
+++ exited with 1 +++

Interestingly, when I'm activating the .venv and try load the .venv with python, it works all fine:

$ . .application+apple.venv/bin/activate
$ which python
.application+apple.venv/bin/python
$ python
Python 3.13.11 (main, Dec  9 2025, 19:04:10) [Clang 21.1.4 ] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import encodings
>>>
$

At this point again could be a uv issue, but still; I was hoping to generate a venv with aspect_rules_py that is usable by vscode, and something is just not clicking.

I am happy to collect more data to work this out.

Version

Development (host) and target OS/architectures:

Output of bazel --version: 9.0.0

Version of the Aspect rules, or other relevant rules from your
WORKSPACE or MODULE.bazel file: bazel_dep(name = "aspect_rules_py", version = "1.10.0")

Language(s) and/or frameworks involved: Python

How to reproduce

Please advise, see above.

Any other information?

Happy to gather.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions