Skip to content

feat(interpreter): add current_py_toolchain rule for Make variable support#897

Open
ctcjab wants to merge 2 commits intoaspect-build:mainfrom
chicagotrading:current-py-toolchain-896
Open

feat(interpreter): add current_py_toolchain rule for Make variable support#897
ctcjab wants to merge 2 commits intoaspect-build:mainfrom
chicagotrading:current-py-toolchain-896

Conversation

@ctcjab
Copy link
Copy Markdown
Contributor

@ctcjab ctcjab commented Mar 27, 2026

Summary

Closes #896.

Adds a current_py_toolchain rule that resolves the active Python toolchain and exposes $(PYTHON3) and $(PYTHON3_ROOTPATH) Make variables via TemplateVariableInfo. This enables bazel_env and genrule integration without depending on rules_python.

  • Auto-instantiated in the python_interpreters hub repo at @python_interpreters//:current_py_toolchain
  • Also exported from @aspect_rules_py//py:defs.bzl and @aspect_rules_py//py:current_py_toolchain.bzl for standalone use
  • Handles both hermetic (PBS) and local system interpreters
  • Includes e2e test verifying $(PYTHON3) expansion via genrule

Usage

# With bazel_env:
bazel_env(
    name = "bazel_env",
    toolchains = {
        "python": "@python_interpreters//:current_py_toolchain",
    },
    tools = {
        "python": "$(PYTHON3)",
    },
)

# With genrule:
genrule(
    name = "run_python",
    outs = ["output.txt"],
    cmd = "$(PYTHON3) -c 'print(42)' > $@",
    toolchains = ["@python_interpreters//:current_py_toolchain"],
)

Test plan

  • e2e test //e2e/cases/current-py-toolchain-896:test passes
  • Existing e2e tests unaffected
  • buildifier and buildifier-lint pass

🤖 Generated with Claude Code

…pport (aspect-build#896)

Provide $(PYTHON3) and $(PYTHON3_ROOTPATH) Make variables via a
current_py_toolchain rule, enabling bazel_env and genrule integration
without depending on rules_python.

The rule is auto-instantiated in the python_interpreters hub repo
at @python_interpreters//:current_py_toolchain, and also exported
from @aspect_rules_py//py:defs.bzl for standalone use.

Closes aspect-build#896

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@aspect-workflows
Copy link
Copy Markdown

aspect-workflows bot commented Mar 27, 2026

Bazel 8 (Test)

All tests were cache hits

107 tests (100.0%) were fully cached saving 47s.


Bazel 9 (Test)

All tests were cache hits

107 tests (100.0%) were fully cached saving 1m 16s.


Bazel 8 (Test)

e2e

All tests were cache hits

46 tests (100.0%) were fully cached saving 55s.


Bazel 9 (Test)

e2e

All tests were cache hits

46 tests (100.0%) were fully cached saving 54s.


Bazel 8 (Test)

examples/uv_pip_compile

All tests were cache hits

1 test (100.0%) was fully cached saving 444ms.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Mar 27, 2026

CLA assistant check
All committers have signed the CLA.

The starlark_doc_extract rule (auto-generated by bzl_library) needs
a bzl_library target for the private .bzl file, and the public
bzl_library targets need to declare the dep.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ctcjab
Copy link
Copy Markdown
Contributor Author

ctcjab commented Mar 27, 2026

The pre-commit / conclusion GitHub Actions failures are unrelated to this PR — the workflow's checkout step tries to fetch refs/heads/current-py-toolchain-896 from aspect-build/rules_py, but the branch lives on the chicagotrading fork. It fails with git fetch ... exit code 1 after 3 retries.

The Buildkite CI (which does handle fork PRs correctly) is the relevant check here — it passed on the previous push after the bzl_library fix.

@arrdem
Copy link
Copy Markdown
Contributor

arrdem commented Mar 27, 2026

https://github.com/bazel-contrib/rules_python/blob/d0b9baadc43eff92b3b9df0a04343e7ca653c44a/python/current_py_toolchain.bzl#L47 Hm. This is how rules_python does it too, which I don't love. I thought there was a way to associate the make vars directly with the toolchain type rather than having to have a wrapper rule which generates the variable info.

@ctcjab
Copy link
Copy Markdown
Contributor Author

ctcjab commented Mar 28, 2026

There was a fix in Bazel 8.3.0 (bazelbuild/bazel@0e876b1, referenced in bazelbuild/bazel#14009) that allows genrule.toolchains to accept toolchain_type targets directly. However, looking at the implementation, it's genrule-specific — it explicitly gates on !ruleClass.isStarlark() && ruleClass.getName().equals("genrule"), so custom Starlark rules like bazel_env can't benefit from it.

The wrapper rule pattern (as used by rules_java's current_java_runtime and rules_python's current_py_toolchain) still seems to be the only option for the general case.

@ctcjab
Copy link
Copy Markdown
Contributor Author

ctcjab commented Apr 9, 2026

In light of the above, is it worth merging this, and if Bazel ever provides something better rules_py can take advantage of that then? @arrdem @gregmagolan et al.

@gregmagolan
Copy link
Copy Markdown
Member

cc @xangcastle

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR]: python_interpreters: provide Make variable (e.g. $(PYTHON3)) for the resolved interpreter

4 participants