Repository navigation
feat(uv): support WORKSPACE builds in the lock() macro - #4360
Merged
Merged
Conversation
The `lock()` macro marked all of its targets incompatible unless bzlmod was enabled, because the only way to download `uv` and register a `uv_toolchain` was the `uv` module extension. To support WORKSPACE, add the extension's API to `@rules_python//python/uv:repositories.bzl` in two steps because only a repository rule can download the release manifests and WORKSPACE cannot look at a repository the same statement creates. The `uv_toolchains_manifest` repository rule fetches the manifests of the requested versions and writes their archive URLs and checksums, unfiltered, to `dist_manifest.bzl`; the `uv_register_toolchains()` macro loaded from there takes the `uv.configure()` fields as a `configure` list of dicts, creates the download repositories for the configured platforms that have an archive, defines one toolchain hub for all versions and registers it. Without a manifest, the same macro accepts explicit URLs. Users combine it with their own toolchains by registering them before or after that call. The extension's configuration and toolchain definition logic, and the manifest parsing, move into modules shared by both so they cannot drift. As a side effect, `netrc` and `auth_patterns` given to `uv.default()` now apply to configured versions; the extension stored but never used them. With toolchains available, the bzlmod gates in `lock()` and its template filegroups are removed. The root WORKSPACE registers `uv` so the existing `tests/uv` suite runs in WORKSPACE mode, and a WORKSPACE variant of the `uv_lock` bazel-in-bazel test reuses the existing Python test cases via a new `bzlmod` mode switch in the integration test runner. The `bzlmod_lockfile` test lockfile is refreshed because the `uv` extension's transitive digest changed. Tested on Bazel 7.x and 8.x in WORKSPACE mode, and on Bazel 7.x, 8.x and 9.x in bzlmod mode (Bazel 9 no longer evaluates WORKSPACE). Work towards bazel-contrib#1975
rickeylev
force-pushed
the
support_uv_lock_workspace
branch
from
October 27, 2026 03:26
106250b to
17193d6
Compare
The `uv_register_toolchains` docstring repeated the `uv.configure` rules and included multi-step WORKSPACE examples that belong in the user guide, and the new `.bzl` module docstrings still carried `EXPERIMENTAL` notices removed upstream. Move the custom-toolchain and no-manifest examples into `docs/pypi/lock.md`, trim `uv_register_toolchains`'s docstring to link to the guide and `uv.configure`, and remove the leftover `EXPERIMENTAL` notices.
Every value in `DIST_MANIFESTS` is a dict, list, or string, so JSON output is already valid Starlark syntax and `_render_manifests` is unnecessary. Replace `_render_manifests` in `uv_toolchains_manifest.bzl` with `json.encode_indent(manifests, indent = " ")` and drop the unused `//python/private:text_util` dependency.
rickeylev
marked this pull request as ready for review
October 27, 2026 04:58
aignas
approved these changes
Oct 27, 2026
rickeylev
added a commit
that referenced
this pull request
Oct 27, 2026
…rules (#4364) Capture review feedback from #4360 in the workspace agent rules so future Starlark and WORKSPACE implementations follow the same patterns: - Direct repository rules to serialize JSON-compatible data constants in generated `.bzl` files with `json.encode_indent()` instead of custom `render.*` helpers. - Keep `.bzl` API docstrings brief and place multi-scenario examples and setup guides in narrative `docs/` pages linked via `{ref}` or `{obj}`. - Require `WORKSPACE` macros to match Bzlmod extension defaults, tag schemas, and single-hub multi-version structure, splitting manifest downloads into a manifest repo rule and a bound registration macro.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This makes the uv
lock()rule work in workspace mode. Since we'llbe supporting Bazel 8 for another year, and I'd really like to get
rid of the remaining requirements.txt and compile_pip_requirements
calls, I figured we should just implement workspace support for it.
This is a fairly low-effort conversion of the bzlmod APIs to
workspace mode. Fundamentally, the bzlmod API works by obtaining
one or more manifests, then using the manifest information to
define repos with the uv binaries. Then the names of all those
repos are fed into the toolchain hub where the
toolchain()registrations are.
The workspace API more-or-less exposes that same API.
The
uv_toolchain_manifest()function is the equivalent of thefirst half of the bzlmod phase. All it does is download the
manifests so they can be read by subsequent workspace macros
and repos. Like the bzlmod API, a manifest per uv version can
be registered.
The
uv_register_toolchains()function is the equivalent of thesecond half of the bzlmod phase. It takes what's in the manifest
and defines repos pointing to a particular URL. Like the bzlmod
API, it accepts args to customize processing. This function also
keeps track of all the created toolchain implementations and
creates the toolchain hub with all the
toolchain()registrations.The args to the functions mirror the bzlmod API, which is basically
a list of key-values. Hence the
uv_register_toolchains.configurearg accepts a list of dicts, where the keys are the same as the
attributes of the
uv.configuretag class. This makes for asomewhat awkward API, but it matches the bzlmod API and makes it
easier to integrate into the underlying code.
Tested on Bazel 7.x and 8.x in WORKSPACE mode, and on Bazel 7.x, 8.x
and 9.x in bzlmod mode (Bazel 9 no longer evaluates WORKSPACE).
Work towards #1975