aspect-build / aspect-build/rules_py
[Bug]: ty [environment] does not work on generated venv for ty IDE extension
- Dominant language
- Starlark
- Stars
- 145
- Forks
- 97
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 71
Description
### What happened?
When trying to integrate with the [`ty` VSCode/Cursor extension](https://marketplace.visualstudio.com/items?itemName=astral-sh.ty), I was unable to configure things in a way where a virtual environment could be linked in my `ty.toml` due to it erroring when resolving the `home` path.
```
2026-04-16 21:16:05.993043258 ERROR Failed to create project for workspace `file:///<>`: Failed to parse the `pyvenv.cfg` file at `/<>/bazel-out/<>/bin/.python3.venv/pyvenv.cfg` because the following error was encountered when trying to resolve the `home` value to a directory on disk: No such file or directory (os error 2). Falling back to default settings
```
I believe the issue was due to the inability of the extension (which I believe utilizes the base VSCode interpreter search, but haven't confirmed) to resolve the relative `./bin/` path from the virtual environment that is set from the pyvenv.cfg template:
```
home = ./bin/ # <- this
implementation = CPython
version_info = {{MAJOR}}.{{MINOR}}.{{PATCH}}
include-system-site-packages = {{INCLUDE_SYSTEM_SITE}}
aspect-include-user-site-packages = {{INCLUDE_USER_SITE}}
relocatable = true
{{INTERPRETER}}
```
### Version
Development (host) and target OS/architectures: Linux ARM64
Output of `bazel --version`: `bazel 9.0.0`
Version of the Aspect rules, or other relevant rules from your
`WORKSPACE` or `MODULE.bazel` file:
- `rules_py` -> `1.11.2`
- `ty` -> `0.0.9`
- VSCode/Cursor extension: `astral-sh.ty@2026.36.0`
Language(s) and/or frameworks involved:
### How to reproduce
```shell
Create a simple ty.toml file
[src]
exclude = [
"pytest_test",
".pytest_main"
]
[rules]
unresolved-import = "ignore"
[environment]
python = ".python3.venv"
BUILD rules to generate the a minimal virtual environment:
load("@aspect_rules_py//py:defs.bzl", "py_binary")
load("@bazel_skylib//rules:write_file.bzl", "write_file")
write_file(
name = "dummy_script",
out = "dummy_script.py",
content = ["print('Hello, World!')"],
is_executable = True,
visibility = ["//visibility:private"],
)
py_binary(
name = "python3",
srcs = [":dummy_script"],
visibility = ["//visibility:private"],
)
Execute to create the virtual environment:
bazel run //:python3.venv
VSCode/Cursor settings for the ty extension:
"ty.path": ["/path/to/ty"],
"ty.configurationFile": "/path/to/ty.toml",
In VSCode/Cursor query for the client logs:
> ty: Show client logs
An error message along these lines should appear (go to `Console > Output > ty Language Server`):
2026-04-16 21:16:05.993043258 ERROR Failed to create project for workspace `file:///<>`: Failed to parse the `pyvenv.cfg` file at `/<>/bazel-out/<>/bin/.python3.venv/pyvenv.cfg` because the following error was encountered when trying to resolve the `home` value to a directory on disk: No such file or directory (os error 2). Falling back to default settings
```
### Any other information?
I was able to crudely patch things to make the path relative to the folder containing the virtual environment, rather than the virtual environment itself, which fixed the problem.
I don't have a great sense for if this would break other commonly used workflows, I assume you all would have some insight into this.
```diff
--- a/py/tools/py/src/pyvenv.cfg.tmpl
+++ b/py/tools/py/src/pyvenv.cfg.tmpl
@@ -1,4 +1,4 @@
-home = ./bin/
+home = {{HOME}}
implementation = CPython
version_info = {{MAJOR}}.{{MINOR}}.{{PATCH}}
include-system-site-packages = {{INCLUDE_SYSTEM_SITE}}
--- a/py/tools/py/src/venv.rs
+++ b/py/tools/py/src/venv.rs
@@ -341,9 +341,12 @@ aspect-runfiles-repo = {1}
// Create the `pyvenv.cfg` file
// FIXME: Should this come from the ruleset?
+ // NOTE(george): this takes the last two components of the home directory to yield the output: `/bin`
+ let home_dir: PathBuf = venv.home_dir.components().rev().take(2).collect::>().into_iter().collect();
fs::write(
&venv.home_dir.join("pyvenv.cfg"),
include_str!("pyvenv.cfg.tmpl")
+ .replace("{{HOME}}", &home_dir.to_str().unwrap())
.replace("{{MAJOR}}", &venv.version_info.major.to_string())
.replace("{{MINOR}}", &venv.version_info.minor.to_string())
.replace("{{PATCH}}", &venv.version_info.patch.to_string())
```
Contributor guide
Research direction
Start with py/tools/py/src/pyvenv.cfg.tmpl and the virtual-environment generation in py/tools/py/src/venv.rs. Reproduce the Bazel-generated environment and inspect the ty language-server client logs in VSCode or Cursor. Done means the generated pyvenv.cfg resolves its home directory for the ty extension while preserving the existing virtual-environment workflow.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, rust
- Domain
- build-system, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 64/100