Skip to content

Commit 18f76f9

Browse files
authored
refactor(uv): move around uv implementation files (#2580)
This PR starts establishing a structure that will eventually become a part of our API. This is a prerequisite for #2578 which removes the versions.bzl file in favour of a more dynamic configuration of the extension. We also remove the `defs.bzl` to establish a one symbol per file convention. Things that I wish we could change is `//python/uv:extensions.bzl` and the fact that we have `extensions` in the load path. I think it cannot be removed, because that may break the BCR test. On the other hand, maybe we could remove it and do an alpha release to verify this assumption. Work towards #1975
1 parent 0475c9e commit 18f76f9

15 files changed

+162
-58
lines changed

MODULE.bazel

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ use_repo(
175175

176176
# EXPERIMENTAL: This is experimental and may be removed without notice
177177
uv = use_extension(
178-
"//python/uv:extensions.bzl",
178+
"//python/uv:uv.bzl",
179179
"uv",
180180
dev_dependency = True,
181181
)

docs/BUILD.bazel

+5-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
1616
load("@dev_pip//:requirements.bzl", "requirement")
1717
load("//python/private:bzlmod_enabled.bzl", "BZLMOD_ENABLED") # buildifier: disable=bzl-visibility
1818
load("//python/private:util.bzl", "IS_BAZEL_7_OR_HIGHER") # buildifier: disable=bzl-visibility
19-
load("//python/uv/private:lock.bzl", "lock") # buildifier: disable=bzl-visibility
19+
load("//python/uv:lock.bzl", "lock") # buildifier: disable=bzl-visibility
2020
load("//sphinxdocs:readthedocs.bzl", "readthedocs_install")
2121
load("//sphinxdocs:sphinx.bzl", "sphinx_build_binary", "sphinx_docs")
2222
load("//sphinxdocs:sphinx_docs_library.bzl", "sphinx_docs_library")
@@ -105,6 +105,10 @@ sphinx_stardocs(
105105
"//python/private/api:py_common_api_bzl",
106106
"//python/private/pypi:config_settings_bzl",
107107
"//python/private/pypi:pkg_aliases_bzl",
108+
"//python/uv:lock_bzl",
109+
"//python/uv:uv_bzl",
110+
"//python/uv:uv_toolchain_bzl",
111+
"//python/uv:uv_toolchain_info_bzl",
108112
] + ([
109113
# Bazel 6 + Stardoc isn't able to parse something about the python bzlmod extension
110114
"//python/extensions:python_bzl",

examples/bzlmod/MODULE.bazel

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ python.single_version_platform_override(
105105
use_repo(python, "python_3_10", "python_3_9", "python_versions", "pythons_hub")
106106

107107
# EXPERIMENTAL: This is experimental and may be removed without notice
108-
uv = use_extension("@rules_python//python/uv:extensions.bzl", "uv")
108+
uv = use_extension("@rules_python//python/uv:uv.bzl", "uv")
109109
uv.toolchain(uv_version = "0.4.25")
110110
use_repo(uv, "uv_toolchains")
111111

python/uv/BUILD.bazel

+12-16
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ filegroup(
2727
visibility = ["//:__subpackages__"],
2828
)
2929

30-
# For stardoc to reference the files
31-
exports_files(["defs.bzl"])
32-
3330
toolchain_type(
3431
name = "uv_toolchain_type",
3532
visibility = ["//visibility:public"],
@@ -48,34 +45,33 @@ current_toolchain(
4845
)
4946

5047
bzl_library(
51-
name = "defs",
52-
srcs = ["defs.bzl"],
48+
name = "lock_bzl",
49+
srcs = ["lock.bzl"],
5350
# EXPERIMENTAL: Visibility is restricted to allow for changes.
5451
visibility = ["//:__subpackages__"],
52+
deps = ["//python/uv/private:lock_bzl"],
5553
)
5654

5755
bzl_library(
58-
name = "extensions",
59-
srcs = ["extensions.bzl"],
56+
name = "uv_bzl",
57+
srcs = ["uv.bzl"],
6058
# EXPERIMENTAL: Visibility is restricted to allow for changes.
6159
visibility = ["//:__subpackages__"],
62-
deps = [":repositories"],
60+
deps = ["//python/uv/private:uv_bzl"],
6361
)
6462

6563
bzl_library(
66-
name = "repositories",
67-
srcs = ["repositories.bzl"],
64+
name = "uv_toolchain_bzl",
65+
srcs = ["uv_toolchain.bzl"],
6866
# EXPERIMENTAL: Visibility is restricted to allow for changes.
6967
visibility = ["//:__subpackages__"],
70-
deps = [
71-
"//python/uv/private:toolchains_repo",
72-
"//python/uv/private:versions",
73-
],
68+
deps = ["//python/uv/private:uv_toolchain_bzl"],
7469
)
7570

7671
bzl_library(
77-
name = "toolchain",
78-
srcs = ["toolchain.bzl"],
72+
name = "uv_toolchain_info_bzl",
73+
srcs = ["uv_toolchain_info.bzl"],
7974
# EXPERIMENTAL: Visibility is restricted to allow for changes.
8075
visibility = ["//:__subpackages__"],
76+
deps = ["//python/uv/private:uv_toolchain_info_bzl"],
8177
)

python/uv/lock.bzl

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright 2025 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""The `uv` locking rule.
16+
17+
EXPERIMENTAL: This is experimental and may be removed without notice
18+
"""
19+
20+
load("//python/uv/private:lock.bzl", _lock = "lock")
21+
22+
lock = _lock

python/uv/private/BUILD.bazel

+47-5
Original file line numberDiff line numberDiff line change
@@ -21,28 +21,70 @@ filegroup(
2121
)
2222

2323
bzl_library(
24-
name = "current_toolchain",
24+
name = "current_toolchain_bzl",
2525
srcs = ["current_toolchain.bzl"],
2626
visibility = ["//python/uv:__subpackages__"],
2727
)
2828

2929
bzl_library(
30-
name = "toolchain_types",
30+
name = "lock_bzl",
31+
srcs = ["lock.bzl"],
32+
visibility = ["//python/uv:__subpackages__"],
33+
deps = [
34+
"//python:py_binary_bzl",
35+
"//python/private:bzlmod_enabled_bzl",
36+
"@bazel_skylib//rules:write_file",
37+
],
38+
)
39+
40+
bzl_library(
41+
name = "toolchain_types_bzl",
3142
srcs = ["toolchain_types.bzl"],
3243
visibility = ["//python/uv:__subpackages__"],
3344
)
3445

3546
bzl_library(
36-
name = "toolchains_repo",
37-
srcs = ["toolchains_repo.bzl"],
47+
name = "uv_bzl",
48+
srcs = ["uv.bzl"],
49+
visibility = ["//python/uv:__subpackages__"],
50+
deps = [":uv_repositories_bzl"],
51+
)
52+
53+
bzl_library(
54+
name = "uv_repositories_bzl",
55+
srcs = ["uv_repositories.bzl"],
56+
visibility = ["//python/uv:__subpackages__"],
57+
deps = [
58+
":toolchain_types_bzl",
59+
":uv_toolchains_repo_bzl",
60+
":versions_bzl",
61+
],
62+
)
63+
64+
bzl_library(
65+
name = "uv_toolchain_bzl",
66+
srcs = ["uv_toolchain.bzl"],
67+
visibility = ["//python/uv:__subpackages__"],
68+
deps = [":uv_toolchain_info_bzl"],
69+
)
70+
71+
bzl_library(
72+
name = "uv_toolchain_info_bzl",
73+
srcs = ["uv_toolchain_info.bzl"],
74+
visibility = ["//python/uv:__subpackages__"],
75+
)
76+
77+
bzl_library(
78+
name = "uv_toolchains_repo_bzl",
79+
srcs = ["uv_toolchains_repo.bzl"],
3880
visibility = ["//python/uv:__subpackages__"],
3981
deps = [
4082
"//python/private:text_util_bzl",
4183
],
4284
)
4385

4486
bzl_library(
45-
name = "versions",
87+
name = "versions_bzl",
4688
srcs = ["versions.bzl"],
4789
visibility = ["//python/uv:__subpackages__"],
4890
)

python/uv/private/lock.bzl

+9-15
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,23 @@ _REQUIREMENTS_TARGET_COMPATIBLE_WITH = select({
2626
"//conditions:default": [],
2727
}) if BZLMOD_ENABLED else ["@platforms//:incompatible"]
2828

29-
def lock(*, name, srcs, out, upgrade = False, universal = True, python_version = None, args = [], **kwargs):
29+
def lock(*, name, srcs, out, upgrade = False, universal = True, args = [], **kwargs):
3030
"""Pin the requirements based on the src files.
3131
32+
Differences with the current {obj}`compile_pip_requirements` rule:
33+
- This is implemented in shell and uv.
34+
- This does not error out if the output file does not exist yet.
35+
- Supports transitions out of the box.
36+
3237
Args:
3338
name: The name of the target to run for updating the requirements.
3439
srcs: The srcs to use as inputs.
3540
out: The output file.
3641
upgrade: Tell `uv` to always upgrade the dependencies instead of
3742
keeping them as they are.
3843
universal: Tell `uv` to generate a universal lock file.
39-
python_version: Tell `rules_python` to use a particular version.
40-
Defaults to the default py toolchain.
41-
args: Extra args to pass to the rule.
42-
**kwargs: Extra kwargs passed to the binary rule.
43-
44-
Differences with the current pip-compile rule:
45-
- This is implemented in shell and uv.
46-
- This does not error out if the output file does not exist yet.
47-
- Supports transitions out of the box.
44+
args: Extra args to pass to `uv`.
45+
**kwargs: Extra kwargs passed to the {obj}`py_binary` rule.
4846
"""
4947
pkg = native.package_name()
5048
update_target = name + ".update"
@@ -92,10 +90,6 @@ def lock(*, name, srcs, out, upgrade = False, universal = True, python_version =
9290
Label("//python:current_py_toolchain"),
9391
],
9492
)
95-
if python_version:
96-
py_binary_rule = lambda *args, **kwargs: py_binary(python_version = python_version, *args, **kwargs)
97-
else:
98-
py_binary_rule = py_binary
9993

10094
# Write a script that can be used for updating the in-tree version of the
10195
# requirements file
@@ -116,7 +110,7 @@ def lock(*, name, srcs, out, upgrade = False, universal = True, python_version =
116110
],
117111
)
118112

119-
py_binary_rule(
113+
py_binary(
120114
name = update_target,
121115
srcs = [update_target + ".py"],
122116
main = update_target + ".py",

python/uv/extensions.bzl python/uv/private/uv.bzl

+8-5
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,18 @@ EXPERIMENTAL: This is experimental and may be removed without notice
1818
A module extension for working with uv.
1919
"""
2020

21-
load("//python/uv:repositories.bzl", "uv_register_toolchains")
21+
load(":uv_repositories.bzl", "uv_repositories")
2222

2323
_DOC = """\
2424
A module extension for working with uv.
2525
"""
2626

27-
uv_toolchain = tag_class(attrs = {
28-
"uv_version": attr.string(doc = "Explicit version of uv.", mandatory = True),
29-
})
27+
uv_toolchain = tag_class(
28+
doc = "Configure uv toolchain for lock file generation.",
29+
attrs = {
30+
"uv_version": attr.string(doc = "Explicit version of uv.", mandatory = True),
31+
},
32+
)
3033

3134
def _uv_toolchain_extension(module_ctx):
3235
for mod in module_ctx.modules:
@@ -38,7 +41,7 @@ def _uv_toolchain_extension(module_ctx):
3841
"NOTE: We may wish to enforce a policy where toolchain configuration is only allowed in the root module, or in rules_python. See https://github.com/bazelbuild/bazel/discussions/22024",
3942
)
4043

41-
uv_register_toolchains(
44+
uv_repositories(
4245
uv_version = toolchain.uv_version,
4346
register_toolchains = False,
4447
)

python/uv/repositories.bzl python/uv/private/uv_repositories.bzl

+8-8
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ EXPERIMENTAL: This is experimental and may be removed without notice
1818
Create repositories for uv toolchain dependencies
1919
"""
2020

21-
load("//python/uv/private:toolchain_types.bzl", "UV_TOOLCHAIN_TYPE")
22-
load("//python/uv/private:toolchains_repo.bzl", "uv_toolchains_repo")
23-
load("//python/uv/private:versions.bzl", "UV_PLATFORMS", "UV_TOOL_VERSIONS")
21+
load(":toolchain_types.bzl", "UV_TOOLCHAIN_TYPE")
22+
load(":uv_toolchains_repo.bzl", "uv_toolchains_repo")
23+
load(":versions.bzl", "UV_PLATFORMS", "UV_TOOL_VERSIONS")
2424

2525
UV_BUILD_TMPL = """\
2626
# Generated by repositories.bzl
27-
load("@rules_python//python/uv:toolchain.bzl", "uv_toolchain")
27+
load("@rules_python//python/uv:uv_toolchain.bzl", "uv_toolchain")
2828
2929
uv_toolchain(
3030
name = "uv_toolchain",
@@ -77,13 +77,13 @@ uv_repository = repository_rule(
7777
},
7878
)
7979

80-
# buildifier: disable=unnamed-macro
81-
def uv_register_toolchains(uv_version = None, register_toolchains = True):
80+
def uv_repositories(name = "uv_toolchains", uv_version = None, register_toolchains = True):
8281
"""Convenience macro which does typical toolchain setup
8382
8483
Skip this macro if you need more control over the toolchain setup.
8584
8685
Args:
86+
name: {type}`str` The name of the toolchains repo.
8787
uv_version: The uv toolchain version to download.
8888
register_toolchains: If true, repositories will be generated to produce and register `uv_toolchain` targets.
8989
"""
@@ -109,12 +109,12 @@ def uv_register_toolchains(uv_version = None, register_toolchains = True):
109109
toolchain_compatible_with_by_toolchain[toolchain_name] = UV_PLATFORMS[platform].compatible_with
110110

111111
uv_toolchains_repo(
112-
name = "uv_toolchains",
112+
name = name,
113113
toolchain_type = str(UV_TOOLCHAIN_TYPE),
114114
toolchain_names = toolchain_names,
115115
toolchain_labels = toolchain_labels_by_toolchain,
116116
toolchain_compatible_with = toolchain_compatible_with_by_toolchain,
117117
)
118118

119119
if register_toolchains:
120-
native.register_toolchains("@uv_toolchains//:all")
120+
native.register_toolchains("@{}/:all".format(name))

python/uv/toolchain.bzl python/uv/private/uv_toolchain.bzl

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ EXPERIMENTAL: This is experimental and may be removed without notice
1818
This module implements the uv toolchain rule
1919
"""
2020

21-
load("//python/uv/private:providers.bzl", "UvToolchainInfo")
21+
load(":uv_toolchain_info.bzl", "UvToolchainInfo")
2222

2323
def _uv_toolchain_impl(ctx):
2424
uv = ctx.attr.uv
File renamed without changes.
File renamed without changes.

python/uv/uv.bzl

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright 2025 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
""" EXPERIMENTAL: This is experimental and may be removed without notice.
16+
17+
The uv toolchain extension.
18+
"""
19+
20+
load("//python/uv/private:uv.bzl", _uv = "uv")
21+
22+
uv = _uv

python/uv/uv_toolchain.bzl

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright 2025 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""The `uv_toolchain` rule.
16+
17+
EXPERIMENTAL: This is experimental and may be removed without notice
18+
"""
19+
20+
load("//python/uv/private:uv_toolchain.bzl", _uv_toolchain = "uv_toolchain")
21+
22+
uv_toolchain = _uv_toolchain

0 commit comments

Comments
 (0)