aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Levasseur <rlevasseur@google.com>2023-06-12 07:52:01 -0700
committerGitHub <noreply@github.com>2023-06-12 14:52:01 +0000
commit2c28e61232cd77c25d1eb09cf63283f62b942558 (patch)
tree234196b6dbe4d8ed6bcaeda806b7247354a959d1
parent1f58f4c9fb5a5f17f35482b0ec7f8bc5448afb59 (diff)
downloadbazelbuild-rules_python-2c28e61232cd77c25d1eb09cf63283f62b942558.tar.gz
feat(bzlmod): Register a default toolchain (#1259)upstream/0.23.0
This makes rules_python always provide a default toolchain when using bzlmod. Note that, unlike workspace builds, the default is not the local system Python (`@bazel_tools//tools/python:autodetecting_toolchain`). Instead, the default is a hermetic runtime, but no guarantees are made about the particular version used. In practice, it will be the latest available Python version. Work towards #1233
-rwxr-xr-x.github/workflows/create_archive_and_notes.sh14
-rw-r--r--BZLMOD_SUPPORT.md24
-rw-r--r--MODULE.bazel9
-rw-r--r--README.md37
-rw-r--r--python/extensions/python.bzl19
5 files changed, 75 insertions, 28 deletions
diff --git a/.github/workflows/create_archive_and_notes.sh b/.github/workflows/create_archive_and_notes.sh
index 0c0c4ac..02279bc 100755
--- a/.github/workflows/create_archive_and_notes.sh
+++ b/.github/workflows/create_archive_and_notes.sh
@@ -40,20 +40,6 @@ pip.parse(
)
use_repo(pip, "pip")
-
-# (Optional) Register a specific python toolchain instead of using the host version
-python = use_extension("@rules_python//python:extensions.bzl", "python")
-
-python.toolchain(
- name = "python3_9",
- python_version = "3.9",
-)
-
-use_repo(python, "python3_9_toolchains")
-
-register_toolchains(
- "@python3_9_toolchains//:all",
-)
\`\`\`
## Using WORKSPACE
diff --git a/BZLMOD_SUPPORT.md b/BZLMOD_SUPPORT.md
index 8efd0df..dbe5238 100644
--- a/BZLMOD_SUPPORT.md
+++ b/BZLMOD_SUPPORT.md
@@ -35,3 +35,27 @@ This rule set does not have full feature partity with the older `WORKSPACE` type
2. Gazelle does not support finding deps in sub-modules. For instance we can have a dep like ` "@our_other_module//other_module/pkg:lib",` in a `py_test` definition.
Check ["issues"](/bazelbuild/rules_python/issues) for an up to date list.
+
+## Differences in behavior from WORKSPACE
+
+### Default toolchain is not the local system Python
+
+Under bzlmod, the default toolchain is no longer based on the locally installed
+system Python. Instead, a recent Python version using the pre-built,
+standalone runtimes are used.
+
+If you need the local system Python to be your toolchain, then it's suggested
+that you setup and configure your own toolchain and register it. Note that using
+the local system's Python is not advised because will vary between users and
+platforms.
+
+If you want to use the same toolchain as what WORKSPACE used, then manually
+register the builtin Bazel Python toolchain by doing
+`register_toolchains("@bazel_tools//tools/python:autodetecting_toolchain")`.
+**IMPORTANT: this should only be done in a root module, and may intefere with
+the toolchains rules_python registers**.
+
+NOTE: Regardless of your toolchain, due to
+[#691](https://github.com/bazelbuild/rules_python/issues/691), `rules_python`
+still relies on a local Python being available to bootstrap the program before
+handing over execution to the toolchain Python.
diff --git a/MODULE.bazel b/MODULE.bazel
index 5381ba1..6729d09 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -51,6 +51,15 @@ use_repo(
# We need to do another use_extension call to expose the "pythons_hub"
# repo.
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
+
+# The default toolchain to use if nobody configures a toolchain.
+# NOTE: This is not a stable version. It is provided for convenience, but will
+# change frequently to track the most recent Python version.
+# NOTE: The root module can override this.
+python.toolchain(
+ is_default = True,
+ python_version = "3.11",
+)
use_repo(python, "pythons_hub")
# This call registers the Python toolchains.
diff --git a/README.md b/README.md
index 6893a1d..cf4b04e 100644
--- a/README.md
+++ b/README.md
@@ -45,31 +45,52 @@ the older way of configuring bazel with a `WORKSPACE` file.
### Using bzlmod
+NOTE: bzlmod support is still experimental; APIs subject to change.
+
To import rules_python in your project, you first need to add it to your
`MODULE.bazel` file, using the snippet provided in the
[release you choose](https://github.com/bazelbuild/rules_python/releases).
+Once the dependency is added, a Python toolchain will be automatically
+registered and you'll be able to create runnable programs and tests.
+
+
#### Toolchain registration with bzlmod
-To register a hermetic Python toolchain rather than rely on a system-installed interpreter for runtime execution, you can add to the `MODULE.bazel` file:
+NOTE: bzlmod support is still experimental; APIs subject to change.
+
+A default toolchain is automatically configured for by depending on
+`rules_python`. Note, however, the version used tracks the most recent Python
+release and will change often.
+
+If you want to register specific Python versions, then use
+`python.toolchain()` for each version you need:
```starlark
-# Find the latest version number here: https://github.com/bazelbuild/rules_python/releases
-# and change the version number if needed in the line below.
-bazel_dep(name = "rules_python", version = "0.21.0")
+python = use_extension("@rules_python//python:extensions.bzl", "python")
+
+python.toolchain(
+ python_version = "3.9",
+)
+```
+
+### Using pip with bzlmod
+NOTE: bzlmod support is still experimental; APIs subject to change.
+
+To use dependencies from PyPI, the `pip.parse()` extension is used to
+convert a requirements file into Bazel dependencies.
+
+```starlark
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
python.toolchain(
- name = "python",
- configure_coverage_tool = True,
- is_default = True,
python_version = "3.9",
)
interpreter = use_extension("@rules_python//python/extensions:interpreter.bzl", "interpreter")
interpreter.install(
name = "interpreter",
- python_name = "python",
+ python_name = "python_3_9",
)
use_repo(interpreter, "interpreter")
diff --git a/python/extensions/python.bzl b/python/extensions/python.bzl
index bed6230..d7a466a 100644
--- a/python/extensions/python.bzl
+++ b/python/extensions/python.bzl
@@ -98,12 +98,20 @@ def _python_impl(module_ctx):
module_name = mod.name,
)
- # Only the root module is allowed to set the default toolchain
- # to prevent submodules from clobbering each other.
- # A single toolchain in the root module is treated as the default
- # because it's unambigiuous.
+ # Only the root module and rules_python are allowed to specify the default
+ # toolchain for a couple reasons:
+ # * It prevents submodules from specifying different defaults and only
+ # one of them winning.
+ # * rules_python needs to set a soft default in case the root module doesn't,
+ # e.g. if the root module doesn't use Python itself.
+ # * The root module is allowed to override the rules_python default.
if mod.is_root:
+ # A single toolchain is treated as the default because it's unambiguous.
is_default = toolchain_attr.is_default or len(mod.tags.toolchain) == 1
+ elif mod.name == "rules_python" and not default_toolchain:
+ # We don't do the len() check because we want the default that rules_python
+ # sets to be clearly visible.
+ is_default = toolchain_attr.is_default
else:
is_default = False
@@ -129,8 +137,7 @@ def _python_impl(module_ctx):
# A default toolchain is required so that the non-version-specific rules
# are able to match a toolchain.
if default_toolchain == None:
- fail("No default toolchain found: exactly one toolchain must have " +
- "is_default=True set")
+ fail("No default Python toolchain configured. Is rules_python missing `is_default=True`?")
# The last toolchain in the BUILD file is set as the default
# toolchain. We need the default last.