//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 haveno-cacheandrequires-networkadded 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 thenameaction. 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 runuv(and possiblypython) 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 thepip.parsebzlmod extension tag class. Note, you can usenative_testto 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
manualtags as locking results cannot be cached.- Args:
The prefix of all targets created by this macro.
The sources that will be used. Add all of the files that would be passed as srcs to the
uv pip compilecommand.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.runtarget.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 toTrue.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
pythonmodule extension.strip_extras– (bool) (default False)whether to strip extras from the output. Currently
rules_pythonrequires--no-strip-extrasto 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 toFalse.kwargs– common kwargs passed to rules.