-
-
Notifications
You must be signed in to change notification settings - Fork 70
Description
What happened?
If you have multiple workspaces declared in your pyproject.toml, and they depend on each other inside of the repo, then you get an analysis error from aspect_rules_py that looks like:
ERROR: /home/runner/.bazel/external/aspect_rules_py++uv+whl_install__pypi__default__define_defcl/BUILD.bazel:23:12: in src attribute of whl_install rule @@aspect_rules_py++uv+whl_install__pypi__default__define_defcl//:actual_install: rule '@@aspect_rules_py++uv+whl_install__pypi__default__define_defcl//:whl' does not exist
ERROR: /home/runner/.bazel/external/aspect_rules_py++uv+whl_install__pypi__default__define_defcl/BUILD.bazel:23:12: Analysis of target '@@aspect_rules_py++uv+whl_install__pypi__default__define_defcl//:actual_install' (config: ab9dc43) failed
In this case, a project called "define" depends on another project called "defcl," both of which are workspaces defined in the repo's root pyproject.toml.
Version
Development (host) and target OS/architectures: WSL 2, and ubuntu-linux on GirHub Actions
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.8.4")
Language(s) and/or frameworks involved: uv 0.10.0
How to reproduce
My agent claims this will reproduce it, although I haven't tested it. I can reproduce it basically by creating two packages that have actual dependencies on each other declared both in the pyproject.toml (with { workspace = true }) and in the BUILD.bazel files. But if you want some instructions to recreate a whole environment that you could just feed to an agent, here you go, maybe these will work:
# Repro: uv extension fails when lock file contains editable/workspace packages
## Steps
1. **Workspace with one member depending on another**
Root `pyproject.toml`:
[project]
name = "myapp"
version = "0.0.1"
requires-python = ">=3.12"
dependencies = []
[tool.uv.workspace]
members = ["packages/a", "packages/b"]
`packages/a/pyproject.toml`: any package, e.g. `name = "myapp-a"`, no deps.
`packages/b/pyproject.toml` (add one external dep so the lock has both PyPI and editable entries):
[project]
name = "myapp-b"
version = "0.0.1"
requires-python = ">=3.12"
dependencies = ["myapp-a", "requests"]
[tool.uv.sources]
myapp-a = { workspace = true }
**Root `BUILD.bazel`**:
load("@aspect_rules_py//py:defs.bzl", "py_library")
exports_files(["uv.lock", "pyproject.toml"])
py_library(
name = "lib",
srcs = ["main.py"],
deps = ["@pypi//requests"],
)
Create **`main.py`** at repo root (can be empty or `"""Stub."""`).
**`packages/a/BUILD.bazel`**:
exports_files(["pyproject.toml"])
**`packages/b/BUILD.bazel`**:
exports_files(["pyproject.toml"])
2. **Lock:** `uv lock` at repo root. Lock file will list `myapp-a` / `myapp-b` with `source = { editable = "..." }` and no `wheels`.
3. **Bazel:** In `MODULE.bazel` add (and keep your existing Python toolchain / bazel_deps as needed):
bazel_dep(name = "aspect_rules_py", version = "1.8.4")
bazel_dep(name = "rules_python", version = "1.8.3")
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
python.toolchain(python_version = "3.12")
pypi = use_extension("@aspect_rules_py//uv/unstable:extension.bzl", "uv")
pypi.declare_hub(hub_name = "pypi")
pypi.declare_venv(hub_name = "pypi", venv_name = "default")
pypi.lockfile(src = "//:uv.lock", hub_name = "pypi", venv_name = "default")
use_repo(pypi, "pypi")
4. **Build:** `bazel build //...`
## Result
Analysis fails with: `rule '...//:whl' does not exist` (for the editable package’s whl_install repo).
## Expected
Editable/workspace entries in the lock file are skipped or handled without requiring a `:whl` target.Any other information?
No response