Skip to content

Commit f4631dc

Browse files
authored
Merge branch 'bazel-contrib:main' into default_version_file
2 parents 2b1286d + 701ba45 commit f4631dc

File tree

71 files changed

+5275
-909
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+5275
-909
lines changed

.bcr/metadata.template.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
}
1414
],
1515
"repository": [
16-
"github:bazelbuild/rules_python"
16+
"github:bazelbuild/rules_python",
17+
"github:bazel-contrib/rules_python"
1718
],
1819
"versions": [],
1920
"yanked_versions": {}

CHANGELOG.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,22 @@ Unreleased changes template.
5555
* (deps) platforms 0.0.4 -> 0.0.11
5656
* (py_wheel) Package `py_library.pyi_srcs` (`.pyi` files) in the wheel.
5757
* (py_package) Package `py_library.pyi_srcs` (`.pyi` files) in `py_package`.
58+
* (gazelle) The generated manifest file (default: `gazelle_python.yaml`) will now include the
59+
YAML document start `---` line. Implemented in
60+
[#2656](https://github.com/bazelbuild/rules_python/pull/2656).
5861

5962
{#v0-0-0-fixed}
6063
### Fixed
6164
* (pypi) The `ppc64le` is now pointing to the right target in the `platforms` package.
62-
* (gazelle) No longer incorrectly merge `py_binary` targets during partial updates in
65+
* (gazelle) No longer incorrectly merge `py_binary` targets during partial updates in
6366
`file` generation mode. Fixed in [#2619](https://github.com/bazelbuild/rules_python/pull/2619).
6467
* (bzlmod) Running as root is no longer an error. `ignore_root_user_error=True`
6568
is now the default. Note that running as root may still cause spurious
6669
Bazel cache invalidation
6770
([#1169](https://github.com/bazelbuild/rules_python/issues/1169)).
6871
* (gazelle) Don't collapse depsets to a list or into args when generating the modules mapping file.
6972
Support spilling modules mapping args into a params file.
73+
* (coverage) Fix missing files in the coverage report if they have no tests.
7074
* (pypi) From now on `python` invocations in repository and module extension
7175
evaluation contexts will invoke Python interpreter with `-B` to avoid
7276
creating `.pyc` files.
@@ -80,6 +84,24 @@ Unreleased changes template.
8084
* {obj}`//python/bin:python`: convenience target for directly running an
8185
interpreter. {obj}`--//python/bin:python_src` can be used to specify a
8286
binary whose interpreter to use.
87+
* (uv) Now the extension can be fully configured via `bzlmod` APIs without the
88+
need to patch `rules_python`. The documentation has been added to `rules_python`
89+
docs but usage of the extension may result in your setup breaking without any
90+
notice. What is more, the URLs and SHA256 values will be retrieved from the
91+
GitHub releases page metadata published by the `uv` project.
92+
* (pypi) An extra argument to add the interpreter lib dir to `LDFLAGS` when
93+
building wheels from `sdist`.
94+
* (pypi) Direct HTTP urls for wheels and sdists are now supported when using
95+
{obj}`experimental_index_url` (bazel downloader).
96+
Partially fixes [#2363](https://github.com/bazelbuild/rules_python/issues/2363).
97+
* (rules) APIs for creating custom rules based on the core py_binary, py_test,
98+
and py_library rules
99+
([#1647](https://github.com/bazelbuild/rules_python/issues/1647))
100+
* (rules) Added env-var to allow additional interpreter args for stage1 bootstrap.
101+
See {obj}`RULES_PYTHON_ADDITIONAL_INTERPRETER_ARGS` environment variable.
102+
Only applicable for {obj}`--bootstrap_impl=script`.
103+
* (rules) Added {obj}`interpreter_args` attribute to `py_binary` and `py_test`,
104+
which allows pass arguments to the interpreter before the regular args.
83105

84106
{#v0-0-0-removed}
85107
### Removed

MODULE.bazel

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -174,16 +174,83 @@ use_repo(
174174
"build_bazel_bazel_self",
175175
)
176176

177-
# EXPERIMENTAL: This is experimental and may be removed without notice
178-
uv = use_extension(
177+
# TODO @aignas 2025-01-27: should this be moved to `//python/extensions:uv.bzl` or should
178+
# it stay as it is? I think I may prefer to move it.
179+
uv = use_extension("//python/uv:uv.bzl", "uv")
180+
181+
# Here is how we can define platforms for the `uv` binaries - this will affect
182+
# all of the downstream callers because we are using the extension without
183+
# `dev_dependency = True`.
184+
uv.default(
185+
base_url = "https://github.com/astral-sh/uv/releases/download",
186+
manifest_filename = "dist-manifest.json",
187+
version = "0.6.3",
188+
)
189+
uv.default(
190+
compatible_with = [
191+
"@platforms//os:macos",
192+
"@platforms//cpu:aarch64",
193+
],
194+
platform = "aarch64-apple-darwin",
195+
)
196+
uv.default(
197+
compatible_with = [
198+
"@platforms//os:linux",
199+
"@platforms//cpu:aarch64",
200+
],
201+
platform = "aarch64-unknown-linux-gnu",
202+
)
203+
uv.default(
204+
compatible_with = [
205+
"@platforms//os:linux",
206+
"@platforms//cpu:ppc",
207+
],
208+
platform = "powerpc64-unknown-linux-gnu",
209+
)
210+
uv.default(
211+
compatible_with = [
212+
"@platforms//os:linux",
213+
"@platforms//cpu:ppc64le",
214+
],
215+
platform = "powerpc64le-unknown-linux-gnu",
216+
)
217+
uv.default(
218+
compatible_with = [
219+
"@platforms//os:linux",
220+
"@platforms//cpu:s390x",
221+
],
222+
platform = "s390x-unknown-linux-gnu",
223+
)
224+
uv.default(
225+
compatible_with = [
226+
"@platforms//os:macos",
227+
"@platforms//cpu:x86_64",
228+
],
229+
platform = "x86_64-apple-darwin",
230+
)
231+
uv.default(
232+
compatible_with = [
233+
"@platforms//os:windows",
234+
"@platforms//cpu:x86_64",
235+
],
236+
platform = "x86_64-pc-windows-msvc",
237+
)
238+
uv.default(
239+
compatible_with = [
240+
"@platforms//os:linux",
241+
"@platforms//cpu:x86_64",
242+
],
243+
platform = "x86_64-unknown-linux-gnu",
244+
)
245+
use_repo(uv, "uv")
246+
247+
register_toolchains("@uv//:all")
248+
249+
uv_dev = use_extension(
179250
"//python/uv:uv.bzl",
180251
"uv",
181252
dev_dependency = True,
182253
)
183-
uv.toolchain(uv_version = "0.4.25")
184-
use_repo(uv, "uv_toolchains")
185-
186-
register_toolchains(
187-
"@uv_toolchains//:all",
188-
dev_dependency = True,
254+
uv_dev.configure(
255+
version = "0.6.2",
189256
)

docs/BUILD.bazel

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,19 @@ sphinx_stardocs(
100100
"//python:py_test_bzl",
101101
"//python:repositories_bzl",
102102
"//python/api:api_bzl",
103+
"//python/api:executables_bzl",
104+
"//python/api:libraries_bzl",
103105
"//python/cc:py_cc_toolchain_bzl",
104106
"//python/cc:py_cc_toolchain_info_bzl",
105107
"//python/entry_points:py_console_script_binary_bzl",
108+
"//python/private:attr_builders_bzl",
109+
"//python/private:builders_util_bzl",
106110
"//python/private:py_binary_rule_bzl",
107111
"//python/private:py_cc_toolchain_rule_bzl",
108112
"//python/private:py_library_rule_bzl",
109113
"//python/private:py_runtime_rule_bzl",
110114
"//python/private:py_test_rule_bzl",
115+
"//python/private:rule_builders_bzl",
111116
"//python/private/api:py_common_api_bzl",
112117
"//python/private/pypi:config_settings_bzl",
113118
"//python/private/pypi:pkg_aliases_bzl",

docs/_includes/field_kwargs_doc.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
:::{field} kwargs
2+
:type: dict[str, Any]
3+
4+
Additional kwargs to use when building. This is to allow manipulations that
5+
aren't directly supported by the builder's API. The state of this dict
6+
may or may not reflect prior API calls, and subsequent API calls may
7+
modify this dict. The general contract is that modifications to this will
8+
be respected when `build()` is called, assuming there were no API calls
9+
in between.
10+
:::
11+

docs/_includes/volatile_api.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
:::{important}
2+
3+
**Public, but volatile, API.** Some parts are stable, while others are
4+
implementation details and may change more frequently.
5+
:::

docs/environment-variables.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,33 @@
11
# Environment Variables
22

3+
::::{envvar} RULES_PYTHON_ADDITIONAL_INTERPRETER_ARGS
4+
5+
This variable allows for additional arguments to be provided to the Python interpreter
6+
at bootstrap time when the `bash` bootstrap is used. If
7+
`RULES_PYTHON_ADDITIONAL_INTERPRETER_ARGS` were provided as `-Xaaa`, then the command
8+
would be;
9+
10+
```
11+
python -Xaaa /path/to/file.py
12+
```
13+
14+
This feature is likely to be useful for the integration of debuggers. For example,
15+
it would be possible to configure the `RULES_PYTHON_ADDITIONAL_INTERPRETER_ARGS` to
16+
be set to `/path/to/debugger.py --port 12344 --file` resulting
17+
in the command executed being;
18+
19+
```
20+
python /path/to/debugger.py --port 12345 --file /path/to/file.py
21+
```
22+
23+
:::{seealso}
24+
The {bzl:obj}`interpreter_args` attribute.
25+
:::
26+
27+
:::{versionadded} VERSION_NEXT_FEATURE
28+
29+
::::
30+
331
:::{envvar} RULES_PYTHON_BOOTSTRAP_VERBOSE
432

533
When `1`, debug information about bootstrapping of a program is printed to

docs/extending.md

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# Extending the rules
2+
3+
:::{important}
4+
**This is public, but volatile, functionality.**
5+
6+
Extending and customizing the rules is supported functionality, but with weaker
7+
backwards compatibility guarantees, and is not fully subject to the normal
8+
backwards compatibility procedures and policies. It's simply not feasible to
9+
support every possible customization with strong backwards compatibility
10+
guarantees.
11+
:::
12+
13+
Because of the rich ecosystem of tools and variety of use cases, APIs are
14+
provided to make it easy to create custom rules using the existing rules as a
15+
basis. This allows implementing behaviors that aren't possible using
16+
wrapper macros around the core rules, and can make certain types of changes
17+
much easier and transparent to implement.
18+
19+
:::{note}
20+
It is not required to extend a core rule. The minimum requirement for a custom
21+
rule is to return the appropriate provider (e.g. {bzl:obj}`PyInfo` etc).
22+
Extending the core rules is most useful when you want all or most of the
23+
behavior of a core rule.
24+
:::
25+
26+
Follow or comment on https://github.com/bazelbuild/rules_python/issues/1647
27+
for the development of APIs to support custom derived rules.
28+
29+
## Creating custom rules
30+
31+
Custom rules can be created using the core rules as a basis by using their rule
32+
builder APIs.
33+
34+
* [`//python/apis:executables.bzl`](#python-apis-executables-bzl): builders for
35+
executables.
36+
* [`//python/apis:libraries.bzl`](#python-apis-libraries-bzl): builders for
37+
libraries.
38+
39+
These builders create {bzl:obj}`ruleb.Rule` objects, which are thin
40+
wrappers around the keyword arguments eventually passed to the `rule()`
41+
function. These builder APIs give access to the _entire_ rule definition and
42+
allow arbitrary modifications.
43+
44+
This is level of control is powerful, but also volatile. A rule definition
45+
contains many details that _must_ change as the implementation changes. What
46+
is more or less likely to change isn't known in advance, but some general
47+
rules are:
48+
49+
* Additive behavior to public attributes will be less prone to breaking.
50+
* Internal attributes that directly support a public attribute are likely
51+
reliable.
52+
* Internal attributes that support an action are more likely to change.
53+
* Rule toolchains are moderately stable (toolchains are mostly internal to
54+
how a rule works, but custom toolchains are supported).
55+
56+
## Example: validating a source file
57+
58+
In this example, we derive from `py_library` a custom rule that verifies source
59+
code contains the word "snakes". It does this by:
60+
61+
* Adding an implicit dependency on a checker program
62+
* Calling the base implementation function
63+
* Running the checker on the srcs files
64+
* Adding the result to the `_validation` output group (a special output
65+
group for validation behaviors).
66+
67+
To users, they can use `has_snakes_library` the same as `py_library`. The same
68+
is true for other targets that might consume the rule.
69+
70+
```
71+
load("@rules_python//python/api:libraries.bzl", "libraries")
72+
load("@rules_python//python/api:attr_builders.bzl", "attrb")
73+
74+
def _has_snakes_impl(ctx, base):
75+
providers = base(ctx)
76+
77+
out = ctx.actions.declare_file(ctx.label.name + "_snakes.check")
78+
ctx.actions.run(
79+
inputs = ctx.files.srcs,
80+
outputs = [out],
81+
executable = ctx.attr._checker[DefaultInfo].files_to_run,
82+
args = [out.path] + [f.path for f in ctx.files.srcs],
83+
)
84+
prior_ogi = None
85+
for i, p in enumerate(providers):
86+
if type(p) == "OutputGroupInfo":
87+
prior_ogi = (i, p)
88+
break
89+
if prior_ogi:
90+
groups = {k: getattr(prior_ogi[1], k) for k in dir(prior_ogi)}
91+
if "_validation" in groups:
92+
groups["_validation"] = depset([out], transitive=groups["_validation"])
93+
else:
94+
groups["_validation"] = depset([out])
95+
providers[prior_ogi[0]] = OutputGroupInfo(**groups)
96+
else:
97+
providers.append(OutputGroupInfo(_validation=depset([out])))
98+
return providers
99+
100+
def create_has_snakes_rule():
101+
r = libraries.py_library_builder()
102+
base_impl = r.implementation()
103+
r.set_implementation(lambda ctx: _has_snakes_impl(ctx, base_impl))
104+
r.attrs["_checker"] = attrb.Label(
105+
default="//:checker",
106+
executable = True,
107+
)
108+
return r.build()
109+
has_snakes_library = create_has_snakes_rule()
110+
```
111+
112+
## Example: adding transitions
113+
114+
In this example, we derive from `py_binary` to force building for a particular
115+
platform. We do this by:
116+
117+
* Adding an additional output to the rule's cfg
118+
* Calling the base transition function
119+
* Returning the new transition outputs
120+
121+
```starlark
122+
123+
load("@rules_python//python/api:executables.bzl", "executables")
124+
125+
def _force_linux_impl(settings, attr, base_impl):
126+
settings = base_impl(settings, attr)
127+
settings["//command_line_option:platforms"] = ["//my/platforms:linux"]
128+
return settings
129+
130+
def create_rule():
131+
r = executables.py_binary_rule_builder()
132+
base_impl = r.cfg.implementation()
133+
r.cfg.set_implementation(
134+
lambda settings, attr: _force_linux_impl(settings, attr, base_impl)
135+
)
136+
r.cfg.add_output("//command_line_option:platforms")
137+
return r.build()
138+
139+
py_linux_binary = create_linux_binary_rule()
140+
```
141+
142+
Users can then use `py_linux_binary` the same as a regular py_binary. It will
143+
act as if `--platforms=//my/platforms:linux` was specified when building it.

docs/index.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ in this repository are simple aliases. On Bazel 7 and above `rules_python` uses
1313
a separate Starlark implementation,
1414
see {ref}`Migrating from the Bundled Rules` below.
1515

16-
Once rules_python 1.0 is released, they will follow
16+
This repository follows
1717
[semantic versioning](https://semver.org) and the breaking change policy
1818
outlined in the [support](support) page.
1919

@@ -101,6 +101,7 @@ pip
101101
coverage
102102
precompiling
103103
gazelle
104+
Extending <extending>
104105
Contributing <contributing>
105106
support
106107
Changelog <changelog>

examples/build_file_generation/gazelle_python.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# To update this file, run:
44
# bazel run //:gazelle_python_manifest.update
55

6+
---
67
manifest:
78
modules_mapping:
89
alabaster: alabaster

0 commit comments

Comments
 (0)