Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ bazel_dep(name = "bazel_skylib", version = "1.4.2")
bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "rules_cc", version = "0.2.16")
bazel_dep(name = "rules_pkg", version = "1.1.0")
bazel_dep(name = "rules_python", version = "1.9.0")

# TODO: when bumping to 1.9.0+, replace py/private/exec_tools/defs.bzl with
# rules_python's public py_exec_tools_toolchain and PyExecToolsInfo, and switch
# EXEC_TOOLS_TOOLCHAIN back to @rules_python//python:exec_tools_toolchain_type.
bazel_dep(name = "rules_python", version = "1.0.0")
bazel_dep(name = "rules_shell", version = "0.6.1")
bazel_dep(name = "tar.bzl", version = "0.5.5")
bazel_dep(name = "with_cfg.bzl", version = "0.14.1")
Expand Down Expand Up @@ -190,7 +194,7 @@ use_repo(version, "bazel_features_globals", "bazel_features_version")
# rules_oci and friends

# rules_python and friends
bazel_dep(name = "rules_python_gazelle_plugin", version = "1.9.0", dev_dependency = IS_RELEASE)
bazel_dep(name = "rules_python_gazelle_plugin", version = "1.0.0", dev_dependency = IS_RELEASE)

python = use_extension("@rules_python//python/extensions:python.bzl", "python", dev_dependency = IS_RELEASE)
python.toolchain(
Expand Down
2 changes: 1 addition & 1 deletion e2e/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ bazel_dep(name = "bazel_skylib", version = "1.4.2")
bazel_dep(name = "bazel_lib", version = "3.0.0")
bazel_dep(name = "rules_cc", version = "0.2.16")
bazel_dep(name = "tar.bzl", version = "0.5.5")
bazel_dep(name = "rules_python", version = "1.9.0")
bazel_dep(name = "rules_python", version = "1.0.0")
bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "toolchains_llvm_bootstrapped", version = "0.3.1")
bazel_dep(name = "rules_oci", version = "2.2.7")
Expand Down
6 changes: 6 additions & 0 deletions py/private/exec_tools/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
load(":defs.bzl", "current_interpreter_executable")

current_interpreter_executable(
name = "current_interpreter_executable",
visibility = ["//visibility:public"],
)
81 changes: 81 additions & 0 deletions py/private/exec_tools/defs.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Copyright 2024 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Exec-configured Python interpreter toolchain.

Hoisted from rules_python to avoid depending on its private API and to
support rules_python >= 1.0.0 (exec_runtime was added in 1.9.0).
"""

load("@bazel_skylib//lib:paths.bzl", "paths")
load("//py/private/toolchain:types.bzl", "PY_TOOLCHAIN")

PyExecToolsInfo = provider(
doc = "Build tools used as part of building Python programs.",
fields = {
"exec_runtime": "PyRuntimeInfo | None: the py3_runtime from the exec interpreter.",
},
)

def _py_exec_tools_toolchain_impl(ctx):
exec_interpreter = ctx.attr.exec_interpreter

exec_runtime = None
if exec_interpreter != None and platform_common.ToolchainInfo in exec_interpreter:
tc = exec_interpreter[platform_common.ToolchainInfo]
exec_runtime = getattr(tc, "py3_runtime", None)

return [platform_common.ToolchainInfo(
exec_tools = PyExecToolsInfo(
exec_runtime = exec_runtime,
),
)]

py_exec_tools_toolchain = rule(
implementation = _py_exec_tools_toolchain_impl,
attrs = {
"exec_interpreter": attr.label(
default = "//py/private/exec_tools:current_interpreter_executable",
providers = [DefaultInfo, platform_common.ToolchainInfo],
cfg = "exec",
),
},
)

def _current_interpreter_executable_impl(ctx):
toolchain = ctx.toolchains[PY_TOOLCHAIN]
runtime = toolchain.py3_runtime

# Name the output after the interpreter binary so tools like pyenv that
# use $0 to re-exec work correctly.
if runtime.interpreter:
executable = ctx.actions.declare_file(runtime.interpreter.basename)
ctx.actions.symlink(output = executable, target_file = runtime.interpreter, is_executable = True)
else:
executable = ctx.actions.declare_symlink(paths.basename(runtime.interpreter_path))
ctx.actions.symlink(output = executable, target_path = runtime.interpreter_path)

return [
toolchain,
DefaultInfo(
executable = executable,
runfiles = ctx.runfiles([executable], transitive_files = runtime.files),
),
]

current_interpreter_executable = rule(
implementation = _current_interpreter_executable_impl,
toolchains = [PY_TOOLCHAIN],
executable = True,
)
4 changes: 2 additions & 2 deletions py/private/interpreter/repository.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def _build_file_content(major, minor, micro, python_bin, is_windows):
return """\
load("@rules_python//python:py_runtime.bzl", "py_runtime")
load("@rules_python//python:py_runtime_pair.bzl", "py_runtime_pair")
load("@rules_python//python/private:py_exec_tools_toolchain.bzl", "py_exec_tools_toolchain")
load("@aspect_rules_py//py/private/exec_tools:defs.bzl", "py_exec_tools_toolchain")

package(default_visibility = ["//visibility:public"])

Expand Down Expand Up @@ -325,7 +325,7 @@ toolchain(
name = "{name}_exec_tools",
exec_compatible_with = {target_compatible_with},
toolchain = "@{repo}//:exec_tools_toolchain",
toolchain_type = "@rules_python//python:exec_tools_toolchain_type",
toolchain_type = "@aspect_rules_py//py/private/toolchain:exec_tools_toolchain_type",
)
""".format(
name = info["name"],
Expand Down
5 changes: 5 additions & 0 deletions py/private/toolchain/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ toolchain_type(
name = "target_exec_toolchain_type",
)

toolchain_type(
name = "exec_tools_toolchain_type",
visibility = ["//visibility:public"],
)

# This creates a toolchain instance with exec_compatible_with placement
# constraints matching the target, backed by the Python toolchain already
# resolved for the target.
Expand Down
1 change: 1 addition & 0 deletions py/private/toolchain/types.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

PY_TOOLCHAIN = "@bazel_tools//tools/python:toolchain_type"
SH_TOOLCHAIN = "@bazel_tools//tools/sh:toolchain_type"
EXEC_TOOLS_TOOLCHAIN = "@aspect_rules_py//py/private/toolchain:exec_tools_toolchain_type"

# Toolchain type for the virtual env creation tools.
SHIM_TOOLCHAIN = "@aspect_rules_py//py/private/toolchain:shim_toolchain_type"
Expand Down
9 changes: 4 additions & 5 deletions uv/private/whl_install/rule.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
"""

load("@rules_python//python:defs.bzl", "PyInfo")
load("@rules_python//python/private:toolchain_types.bzl", "EXEC_TOOLS_TOOLCHAIN_TYPE")
load("//py/private/toolchain:types.bzl", "PY_TOOLCHAIN", "UNPACK_TOOLCHAIN")
load("//py/private/toolchain:types.bzl", "EXEC_TOOLS_TOOLCHAIN", "PY_TOOLCHAIN", "UNPACK_TOOLCHAIN")

def _whl_install(ctx):
py_toolchain = ctx.toolchains[PY_TOOLCHAIN].py3_runtime
Expand Down Expand Up @@ -40,11 +39,11 @@ def _whl_install(ctx):
transitive_inputs.append(depset(patch_files))

# Optional .pyc pre-compilation (runs after patching).
# Use the exec-configured interpreter from EXEC_TOOLS_TOOLCHAIN_TYPE so cross-arch
# Use the exec-configured interpreter from EXEC_TOOLS_TOOLCHAIN so cross-arch
# builds work (the target interpreter isn't runnable on the build host). This is
# safe because .pyc bytecode varies by Python version, not by architecture.
if ctx.attr.compile_pyc:
exec_runtime = ctx.toolchains[EXEC_TOOLS_TOOLCHAIN_TYPE].exec_tools.exec_runtime
exec_runtime = ctx.toolchains[EXEC_TOOLS_TOOLCHAIN].exec_tools.exec_runtime
arguments.add("--compile-pyc")
arguments.add("--pyc-invalidation-mode", ctx.attr.pyc_invalidation_mode)
arguments.add("--python", exec_runtime.interpreter)
Expand Down Expand Up @@ -130,7 +129,7 @@ lighter weight since the toolchain's files aren't inputs.
toolchains = [
PY_TOOLCHAIN,
UNPACK_TOOLCHAIN,
EXEC_TOOLS_TOOLCHAIN_TYPE,
EXEC_TOOLS_TOOLCHAIN,
],
provides = [
DefaultInfo,
Expand Down