aspect-build / aspect-build/rules_py
[Bug]: uv based venv generator creates .venv not usable with uv
- Dominant language
- Starlark
- Stars
- 145
- Forks
- 97
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 71
Description
### What happened?
I've got an environment that's [mocked here](https://github.com/ha1dfo/repro-py-proto/tree/use_uv).
I had previous ticket on venv generation [here](https://github.com/aspect-build/rules_py/issues/785).
I am generating the .venv so that my IDE (vscode) can pick it up.
Vscode uses `uv pip list --python=` 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//.cache/bazel/_bazel_/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//repos//.<...>+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//repos//.venv/bin/python
Using Python 3.13.12 environment at: /home//.cache/bazel/_bazel_/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//.cache/bazel/_bazel_/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//.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//repos/", 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//.cache/bazel/_bazel_/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//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, " \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.
Contributor guide
Research direction
Start by reproducing the uv-based venv generation with aspect_rules_py 1.10.0 and the linked mock repository, then compare `uv pip list --python` with direct activation and Python execution. Inspect the generated `pyvenv.cfg`, runfiles layout, and interpreter paths; done means uv and VS Code can inspect the generated environment while Python still imports `encodings` successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 42/100