Skip to content

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

Open
ctcjab wants to merge 4 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 4 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

@aspect-workflows
Copy link
Copy Markdown

aspect-workflows Bot commented Mar 27, 2026

Bazel 8 (Test)

All tests were cache hits

123 tests (100.0%) were fully cached saving 60s.


Bazel 9 (Test)

All tests were cache hits

122 tests (100.0%) were fully cached saving 1m 5s.


Bazel 8 (Test)

e2e

All tests were cache hits

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


Bazel 9 (Test)

e2e

All tests were cache hits

59 tests (100.0%) were fully cached saving 1m 3s.


Bazel 8 (Test)

examples/uv_pip_compile

All tests were cache hits

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


Buildifier

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Mar 27, 2026

CLA assistant check
All committers have signed the CLA.

@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

@ctcjab
Copy link
Copy Markdown
Contributor Author

ctcjab commented Apr 23, 2026

Friendly bump (since I opened this a month ago and am hoping to avoid acquiring a merge conflict) - thanks in advance for any attention you can give this🙏

Comment thread py/private/interpreter/current_py_toolchain.bzl Outdated
Comment thread e2e/cases/current-py-toolchain-896/test.sh Outdated
Comment thread e2e/cases/current-py-toolchain-896/test.sh Outdated
Comment thread py/private/interpreter/current_py_toolchain.bzl
@jbedard
Copy link
Copy Markdown
Member

jbedard commented Apr 28, 2026

@codex

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 691ec6b122

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread py/private/interpreter/current_py_toolchain.bzl
ctcjab and others added 3 commits May 1, 2026 16:41
…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>
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>
- Use existing PY_TOOLCHAIN constant from types.bzl instead of
  duplicating the toolchain type string
- Add fail() when py3_runtime has neither interpreter nor
  interpreter_path
- Fix e2e test runfiles path to use ${TEST_SRCDIR}/_main/cases/...
  pattern consistent with other e2e tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ctcjab ctcjab force-pushed the current-py-toolchain-896 branch from 691ec6b to 38e785a Compare May 1, 2026 22:12
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ctcjab
Copy link
Copy Markdown
Contributor Author

ctcjab commented May 1, 2026

Thanks for the review @jbedard! I've addressed your feedback:

  • Using the existing PY_TOOLCHAIN constant from types.bzl
  • Added fail() for the case where py3_runtime has neither interpreter nor interpreter_path
  • Fixed the e2e test to use the correct ${TEST_SRCDIR}/_main/cases/... runfiles path pattern

Also rebased on latest main. CI is passing — would appreciate another look when you get a chance.

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

5 participants