Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

rules_uv

API reference, generated from the module’s .bzl docstrings (stardoc).


rules_uv roadmap

v0.1

  • @uv//:binary built from source via cargo_bootstrap_repository.
  • uv_run macro: sandbox-escaping bazel run wrapper.
  • pip.parse module extension: uv.lock@pip hub + per-package repos.
  • Pure-Python wheel materialization (py3-none-any).
  • Sdist fallback (raw download; no build step yet).
  • End-to-end smoke test in examples/smoke.

v0.2 (this release)

  • Prebuilt-uv toolchain alternative. uv.toolchain(source = "prebuilt") fetches the official release asset for the host platform from astral-sh/uv releases. Supported hosts today: darwin_{aarch64,x86_64} and linux_{aarch64,x86_64}. musl + 32-bit + Windows triples are intentionally omitted until someone needs them — pinning shas we never test is security theater.
  • Unified target shape. Both build and prebuilt produce @uv//:binary as a File; uv_toolchain accepts the file directly (no more :install rust_binary indirection).

v0.3 (this release)

  • Native wheel selection. PEP 425 / PEP 600 tag scoring in pip/private/wheel_selection.bzl: parse wheel filenames, fan out compressed tag fields, score against a host-specific ordered tag list (pip/private/platform.bzl). MVP covers the 4 fastverk hosts (darwin_{aarch64,x86_64}, linux_{aarch64,x86_64}); rules_python’s whl_target_platforms is more thorough and will be the backing implementation once their internals stabilize.
  • Sdist installation via uv. sdist_install_repo (pip/private/sdist_install.bzl): downloads the sdist, shells to @uv//:uv (uv pip install --target=. --no-deps) at repo-rule time. Python interpreter via python = "host" (python3 on PATH) or python = "uv" (uv python install into a per-repo scratch dir).
  • python_version + python attrs on pip.parse. Wheel tag matching consults python_version; sdist install dispatches on python.

v0.4 (this release)

  • Extras: requirement("pkg[extra]") resolves to a per-extra Bazel target that re-exports :pkg plus the extra’s deps. Generated from each package’s [package.optional-dependencies] table.
  • Markers: PEP 508 subset evaluated at extension time against python_version + host platform. Edges whose markers fail are filtered out. Cross-platform select() is v0.5.
  • Git sources (source = { git = "…", rev = "…" }): new_git_repository with the BUILD wrapper.
  • Path sources (source = { path = "…" }): new_local_repository-style symlink rule.
  • Editable sources: explicit failure with a clear message (editable installs don’t translate to Bazel).
  • Hermetic uv invocation: --no-config on all uv pip and uv python install calls so the user’s ~/.config/uv/uv.toml (which on many machines points at a private index) doesn’t leak into sandbox builds.

v0.5 (this release)

  • Cross-platform wheels. pip.parse(platforms = [...]) opts the hub into multi-platform mode. Packages with platform-divergent native wheels fan out into per-platform repos (@<hub>__<pkg>__<platform>) behind a selector repo that emits alias(name = "pkg", actual = select(...)) over @platforms//os + @platforms//cpu constraint values. Non-host platform repos are declared but lazy-fetched — they only land on disk when Bazel’s configuration triggers that branch of the select().
  • Multi-platform smoke (examples/multiplatform/): pure-python wheel (idna) flows through the single-repo path; native wheel (markupsafe) flows through the per-platform select.

v0.6 (next)

Smoke fixtures for git + path sources

v0.4 wires git/path source materialization, but no smoke fixture exercises either. A fixture that lock-files a tiny pure-Python package from a pinned GitHub commit + a sibling local path package would catch regressions.

Sdist install in multi-platform mode

Today sdist install is host-only — if a multi-platform lockfile references an sdist-only package, the extension fails fast rather than silently producing a broken cross-platform target. v0.6 could support per-platform sdist installs by running uv pip install --target once per requested platform (each producing its own per-platform repo). Requires either cross-compilation toolchains on the host (rare) or Bazel platform-transition magic.

musl + Windows platform tag tables

pip/private/platform.bzl ships tag tables for the four fastverk hosts only. Adding musllinux + Windows entries (with @platforms//os:windows and a musl libc constraint) is mechanical once a consumer needs them.

Marker evaluator: spot tests

pip/private/markers.bzl is a hand-rolled PEP 508 subset parser. A skylib unittest suite covering operators, precedence, and the python_full_version vs python_version edge cases would lock the behavior down.

Beyond v0.6

  • uv_pip_compile: bazel run-able workflow to regenerate requirements.txt from a pyproject.toml (analogous to rules_uv upstream’s compile workflow).
  • Cross-platform wheels: support emitting select() deps when a package has multiple platform wheels but the consumer wants to target several configurations from one tree.
  • Stardoc-generated reference in /docs.

Delete uv/ when rules_python’s uv is stable

rules_python ships its own experimental uv toolchain primitive at @rules_python//python/uv:uv_toolchain.bzl and a binary-fetching module extension at @rules_python//python/uv:uv.bzl. Both are marked EXPERIMENTAL: This is experimental and may be removed without notice, so today rules_uv carries its own toolchain + fetch + build paths.

When rules_python promotes these out of experimental, rules_uv’s uv/ directory becomes pure duplication and should be removed:

  • Drop uv/extensions.bzl, uv/toolchains.bzl, uv/private/known_versions.bzl, uv/private/uv_source.BUILD.bazel.
  • Replace our uv_run macro with one that resolves through rules_python’s uv_toolchain_type.
  • The pip extension keeps using @uv//:binary at repo-rule time (just pointing at whichever target rules_python’s extension materializes by then).

This trims rules_uv down to its actual reason for existing: the uv.lock TOML → @pip materializer. Track upstream status at https://github.com/bazelbuild/rules_python/issues/ (search for “uv toolchain experimental”).


pip_parse module extension — uv.lock → @ + per-pkg repos.

Counterpart to rules_python’s pip_parse, but driven by uv.lock instead of requirements.txt. For each package the lockfile resolves to, we create a Bazel-fetched repo containing the unpacked wheel (or installed sdist, or fetched git/path source). A hub repo aggregates these and exposes a requirement("<name>") macro plus pre-aliased @<hub>//<name>:pkg labels.

Consumer:

pip = use_extension("@rules_uv//pip:extensions.bzl", "pip")
pip.parse(
    hub_name = "pip",
    lock = "//:uv.lock",
    python_version = "3.12",
)
use_repo(pip, "pip")

Extras are exposed as additional sub-targets on the package repo:

load("@pip//:requirements.bzl", "requirement")
py_library(
    name = "app",
    deps = [
        requirement("requests"),              # base package
        requirement("requests[security]"),    # base + extra deps
    ],
)

Markers (e.g. marker = "python_version < '3.11'") are evaluated at extension time against the configured python_version + host platform. Edges whose markers fail are silently dropped from the generated BUILD — keeping the host-only view simple. Cross-platform select() is v0.5.

pip

pip = use_extension("@rules_uv//pip:extensions.bzl", "pip")
pip.parse(hub_name, lock, platforms, python, python_version, uv)

Materialize @ + per-pkg repos from a uv.lock.

TAG CLASSES

parse

Attributes

NameDescriptionTypeMandatoryDefault
hub_nameName of the hub repo (the @<hub_name>//… namespace).Stringoptional"pip"
lockLabel pointing at a uv.lock file.Labelrequired
platformsOptional list of <os>_<arch> platforms this lockfile should support. Default is host-only (the v0.4 behavior — select() is not introduced). Supported entries: darwin_aarch64, darwin_x86_64, linux_aarch64, linux_x86_64. Packages with platform-divergent native wheels fan out into per-platform repos behind a select() alias; sdist/git/path packages remain host-only and the build will fail loudly if a non-host platform tries to resolve them.List of stringsoptional[]
pythonHow to find a Python interpreter for sdist install. host uses python3 on PATH; uv runs uv python install <python_version> per package.Stringoptional"host"
python_versionPython major.minor used for wheel-tag matching and (when python = “uv”) the uv-managed interpreter.Stringoptional"3.12"
uvLabel of the uv binary used to install sdists.Labeloptional"@uv"

User-facing rules for rules_uv.

  • uv_run — sh_binary macro: bazel run //path:NAME invokes uv <subcommand> against the live workspace source. Intentionally non-hermetic (escapes the runfiles sandbox) for the dev loop (uv pip sync, uv lock, uv run …).

Lockfile-driven Python repo materialization lives in @rules_uv//pip:extensions.bzl (pip_parse), which is the rules_uv analogue of rules_python’s pip_parse but reads uv.lock rather than requirements.txt.

uv_run

load("@rules_uv//uv:defs.bzl", "uv_run")

uv_run(name, subcommand, args, **kwargs)

bazel run-able wrapper around uv <subcommand>.

Escapes the runfiles sandbox via BUILD_WORKSPACE_DIRECTORY so uv operates on the user’s source tree (uv lock, uv pip sync … both need to write into the workspace).

PARAMETERS

NameDescriptionDefault Value
nametarget name.none
subcommandfirst arg passed to uv (e.g. pip, lock, run).none
argsextra args appended after the subcommand.None
kwargsforwarded to the underlying sh_binary.none

Toolchain wrapper for the uv binary.

UvToolchainInfo.uv is a File for the uv executable. Consumers resolve it via ctx.toolchains["@rules_uv//uv:toolchain_type"].

The attr uses allow_single_file = True rather than executable = True because the bootstrapped binary at @uv//:binary is an alias to a source File (cargo_bootstrap_repository’s output) — Bazel rejects source files as executable attr inputs, so we accept the file and let the consuming rule mark it executable itself.

uv_toolchain

load("@rules_uv//uv:toolchains.bzl", "uv_toolchain")

uv_toolchain(name, uv)

Declares a uv toolchain.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
uvLabel of the uv binary (either built via cargo_bootstrap_repository or fetched as a prebuilt release asset).Labelrequired

UvToolchainInfo

load("@rules_uv//uv:toolchains.bzl", "UvToolchainInfo")

UvToolchainInfo(uv)

Information about a uv toolchain.

FIELDS

NameDescription
uvFile pointing at the uv executable.