Skip to content

Unexpected interaction between toolchain resolution and bzlmod #20354

@lberki

Description

@lberki

Description of the bug:

When bzlmod is enabled (as it is the case in Bazel 7.0.0), toolchain registered by default can unexpectedly shadow toolchains declared in the WORKSPACE file. This makes the oucome of toolchain resolution dependent on whether bzlmod is enabled, even if the MODULE.bazel file of the main repository is empty (as it is by default)

The root cause seems to be different from #17289 : there, AFAIU that one is caused by a subtle interaction between label mapping and toolchain resolution, here it's much more straightforward.

Some debugging indicates that what happens is that RegisteredToolchainsFunction creates the list of registered toolchains by concatenating two lists: those from bzlmod, then those from the WORKSPACE file. rules_python is by default and immutably (except if bzlmod is disabled) a bzlmod module and it registers @bazel_tools//tools/python:_autodetecting_py_runtime_pair as a Python toolchain. Since that toolchain doesn't have any exec or target constraints, it seems to win toolchain selection by default, regardless of what other toolchains come after.

Therefore, no matter what is written in the WORKSPACE file, one gets the autodetecting Python toolchain.

I'm not sure if this is WAI; it could be construed as such, but it sure is surprising and a hindrance to migration to bzlmod.

Which category does this issue belong to?

No response

What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

cat > WORKSPACE <<'EOF'
register_toolchains("//tc:py_toolchain")
EOF

cat > BUILD <<'EOF'
py_binary(
    name = "py",
    srcs = ["py.py"],
)
EOF

cat > py.py <<'EOF'
print("Hello, Python!")
EOF

mkdir tc

cat > tc/BUILD <<'EOF'
load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair")

py_runtime(
    name = "python2",
    files = ["ok.py2"],
    interpreter = "ok.py2",
    python_version = "PY2",
)

py_runtime(
    name = "python3",
    files = ["ok.py3"],
    interpreter = "ok.py3",
    python_version = "PY3",
)

py_runtime_pair(
    name = "pair",
    py2_runtime = ":python2",
    py3_runtime = ":python3",
)

toolchain(
    name = "py_toolchain",
    toolchain = ":pair",
    toolchain_type = "@bazel_tools//tools/python:toolchain_type",
)
EOF

bazel run --enable_bzlmod :py  # BUG: Prints "Hello, Python!", ignoring the toolchain
bazel run --noenable_bzlmod :py  # WORKS: Fails to find the dummy interpreter defined above

Which operating system are you running Bazel on?

Linux

What is the output of bazel info release?

development version

If bazel info release returns development version or (@non-git), tell us how you built Bazel.

From sources

What's the output of git remote get-url origin; git rev-parse master; git rev-parse HEAD ?

4a29f0851d1cde0240793cdc7a2e2cab926d31b7

Is this a regression? If yes, please try to identify the Bazel commit where the bug was introduced.

Pretty obviously when --enable_bzlmod was flipped to true.

Have you found anything relevant by searching the web?

There are a number of pertinent bugs:

Any other information, logs, or outputs that you want to share?

No response

Metadata

Metadata

Assignees

Labels

P2We'll consider working on this in future. (Assignee optional)area-BzlmodBzlmod-specific PRs, issues, and feature requeststeam-ExternalDepsExternal dependency handling, remote repositiories, WORKSPACE file.type: bug

Type

No type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions