//python/uv:lock.bzl

The uv locking rule.

Differences with the legacy compile_pip_requirements rule:

  • This is implemented as a rule that performs locking in a build action.

  • Additionally one can use the runnable target.

  • Uses uv.

  • This does not error out if the output file does not exist yet.

  • Supports transitions out of the box.

Note, this does not provide a test target like compile_pip_requirements does. The uv pip compile command is not hermetic and thus a test based on it would most likely be flaky:

  • It may require auth injected into it, so most likely it requires a local tag added so that the bazel action runs without sandboxing.

  • It requires network access.

Given those points, a test target should be an explicit and properly documented target and not a hidden implicit target. If, you would like to add a test target that always does the locking automatically to ensure that the requirements.txt file is up-to-date, add something similar to:

load("@bazel_skylib//rules:native_binary.bzl", "native_test")
load("@rules_python//python/uv:lock.bzl", "lock")

lock(
    name = "requirements",
    srcs = ["pyproject.toml"],
)

native_test(
    name = "requirements_test",
    src = "requirements.update",
)

EXPERIMENTAL: This is experimental and may be changed without notice.

lock(name, srcs, out, args=[], build_constraints=[], constraints=[], env=None, generate_hashes=True, python_version=None, strip_extras=False, **kwargs)

Pin the requirements based on the src files.

This macro creates the following targets:

  • name: the target that creates the requirements.txt file in a build action. This target will have no-cache and requires-network added to its tags.

  • name.run: a runnable target that can be used to pass extra parameters to the same command that would be run in the name action. This will update the source copy of the requirements file. You can customize the args via the command line, but it requires being able to run uv (and possibly python) directly on your host.

  • name.update: a target that can be run to update the source-tree version of the requirements lock file. The output can be fed to the pip.parse bzlmod extension tag class. Note, you can use native_test to wrap this target to make a test. You can’t customize the args via command line, but you can use RBE to generate requirements (offload execution and run for different platforms). Note, that for RBE to be usable, one needs to ensure that the nodes running the action have internet connectivity or the indexes are provided in a different way for a fully offline operation.

Note

All of the targets have manual tags as locking results cannot be cached.

Args:
  • name(str)

    The prefix of all targets created by this macro.

  • srcs(list[Label])

    The sources that will be used. Add all of the files that would be passed as srcs to the uv pip compile command.

  • out(str)

    The output file relative to the package.

  • args(list[str]) (default [])

    The list of args to pass to uv. Note, these are written into the runnable name.run target.

  • build_constraints(list[Label]) (default [])

    The list of build constraints to use.

  • constraints(list[Label]) (default [])

    The list of constraints files to use.

  • env(dict[str, str]) (default None)

    the environment variables to set. Note, this is passed as is and the environment variables are not expanded.

  • generate_hashes(bool) (default True)

    Generate hashes for all of the requirements. This is a must if you want to use pip.parse.experimental_index_url. Defaults to True.

  • python_version(str | None) (default None)

    the python_version to transition to when locking the requirements. Defaults to the default python version configured by the python module extension.

  • strip_extras(bool) (default False)

    whether to strip extras from the output. Currently rules_python requires --no-strip-extras to properly function, but sometimes one may want to not have the extras if you are compiling the requirements file for using it as a constraints file. Defaults to False.

  • kwargs – common kwargs passed to rules.