`@rules_python//python/config_settings:python_version` does not control toolchain
🐞 bug report
Affected Rule
The issue is caused by the rule: `python_register_multi_toolchains`Is this a regression?
I think this has always been a bug.
Description
A clear and concise description of the problem...@rules_python//python/config_settings:python_version does not control the of the python toolchain that's used when paired with python_register_multi_toolchains
🔬 Minimal Reproduction
Using a simple WORKSPACE like the one below, I'm able to invoke the following to see the version of python printed does not match the version specified in the command line
bazel run //:example --@rules_python//python/config_settings:python_version=3.11.4
WORKSPACE.bazel
workspace(name = "example")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_python",
sha256 = "d71d2c67e0bce986e1c5a7731b4693226867c45bfe0b7c5e0067228a536fc580",
strip_prefix = "rules_python-0.29.0",
url = "https://github.com/bazelbuild/rules_python/releases/download/0.29.0/rules_python-0.29.0.tar.gz",
)
load("@rules_python//python:repositories.bzl", "py_repositories")
py_repositories()
load("@rules_python//python:repositories.bzl", "python_register_multi_toolchains")
python_register_multi_toolchains(
name = "python",
default_version = "3.11",
python_versions = [
"3.8",
"3.11",
],
register_coverage_tool = True,
)
BUILD.bazel
load("@rules_python//python:defs.bzl", "py_binary")
py_binary(
name = "example",
srcs = ["example.py"],
)
example.py
import sys
print(sys.version)
🔥 Exception or Error
The example above will print py3.11.6, the newest available toolchain, but not the one specified on the command line.
🌍 Your Environment
Operating System:
Linux, MacOS, Windows
Output of bazel version:
7.0.1
Rules_python version:
0.29.0
Anything else relevant?
I think that something related to this got fixed in bzlmod by us starting to use is_python_x.y instead of is_python_x.y.z config_settings in the hub repos. That might be still present in the WORKSPACE multi-version plumbing.
I wonder if there are other things that need fixing here as well.
If you explicitly register a 3.11.4 version it will work. But because you haven't, 3.11.4 does not match any registered toolchains and the default version is selected (3.11.6, since that's the latest in the 3.11 series in rules_python 0.29).
My expectation is that if I register 3.11, I would get all versions of py311 available registered as toolchains and gated by target_settings where each toolchain is constrained by the full version (e.g. 3.11.4) and for only major+minor versions (e.g. 3.11) an extra toolchain would be registered only for the latest available version with this as a target_setting. That way if I specify in my bazelrc that I want 3.11.4, I would correctly match it. I would rather not need to specify full versions when registering toolchains in hopes that I would continue to have all versions available to me and let either bazelrc flags and transitions decide what python is desired.
Right now the behaviour is that you get the latest. With bzlmod, you should be able to specify it in the .bazelrc and get what you would expect, I think.
I think you would still need to register the desired toolchain version in MODULE.bazel before selecting it in .bazelrc.
We could do away with having to explicitly ask for the versions by just always registering everything. That should be relatively cheap because bzlmod won't actually instantiate those repos unless they're actually used.
It's too bad flags can't be used in bzlmod or repo phases. The closest we could get is an environment variable to control things, which is awkward. Could be useful as an optimization to limit how many unnecessary versions get registered.
Maybe a happy medium is to register 3.11.* if someone asks for 3.11? Otherwise the list of registered repos grows forever.
Or maybe that's what you're suggesting?
Yeah. Or maybe always register the latest version of each?
Something I've been seeing library modules doing is using list comps in their MODULE files to request every version available. They don't know which version will ultimately be used, so they just have to list every version. Which is annoying for them. Plus when a new version is added, they'll have to update again. So double annoying.
I agree that we should probably just register the latest versions by default.