Skip to content

Commit

Permalink
fix: use rules_python's py_runtime in generated toolchains (#1604)
Browse files Browse the repository at this point in the history
This makes rules_python compatible with disabling using the native rules
in Bazel.

While we're here, update some examples in docs to load py_runtime to
better make
clear the builtin py_runtime objects shouldn't be used.

Work towards #1069
  • Loading branch information
rickeylev authored Dec 15, 2023
1 parent bbec4c2 commit 94c89e6
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 5 deletions.
1 change: 1 addition & 0 deletions .bazelignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ examples/bzlmod_build_file_generation/bazel-bzlmod_build_file_generation
examples/pip_parse/bazel-pip_parse
examples/py_proto_library/bazel-py_proto_library
tests/ignore_root_user_error/bazel-ignore_root_user_error
tests/pip_repository_entry_points/bazel-pip_repository_entry_points
21 changes: 19 additions & 2 deletions python/config_settings/transition.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ them to the desired target platform.

load("@bazel_skylib//lib:dicts.bzl", "dicts")
load("//python:py_binary.bzl", _py_binary = "py_binary")
load("//python:py_info.bzl", "PyInfo")
load("//python:py_runtime_info.bzl", "PyRuntimeInfo")
load("//python:py_test.bzl", _py_test = "py_test")
load("//python/config_settings/private:py_args.bzl", "py_args")
load("//python/private:reexports.bzl", "BuiltinPyInfo", "BuiltinPyRuntimeInfo")

def _transition_python_version_impl(_, attr):
return {"//python/config_settings:python_version": str(attr.python_version)}
Expand Down Expand Up @@ -60,14 +63,28 @@ def _transition_py_impl(ctx):
for k, v in ctx.attr.env.items():
env[k] = ctx.expand_location(v)

if PyInfo in target:
py_info = target[PyInfo]
elif BuiltinPyInfo in target:
py_info = target[BuiltinPyInfo]
else:
fail("target {} does not have rules_python PyInfo or builtin PyInfo".format(target))

if PyRuntimeInfo in target:
py_runtime_info = target[PyRuntimeInfo]
elif BuiltinPyRuntimeInfo in target:
py_runtime_info = target[BuiltinPyRuntimeInfo]
else:
fail("target {} does not have rules_python PyRuntimeInfo or builtin PyRuntimeInfo".format(target))

providers = [
DefaultInfo(
executable = executable,
files = depset([zipfile_symlink] if zipfile_symlink else [], transitive = [target[DefaultInfo].files]),
runfiles = ctx.runfiles([zipfile_symlink] if zipfile_symlink else []).merge(target[DefaultInfo].default_runfiles),
),
target[PyInfo],
target[PyRuntimeInfo],
py_info,
py_runtime_info,
# Ensure that the binary we're wrapping is included in code coverage.
coverage_common.instrumented_files_info(
ctx,
Expand Down
2 changes: 2 additions & 0 deletions python/private/common/py_runtime_rule.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ interpreter.
# Example
```
load("@rules_python//python:py_runtime.bzl", "py_runtime")
py_runtime(
name = "python-2.7.12",
files = glob(["python-2.7.12/**"]),
Expand Down
3 changes: 2 additions & 1 deletion python/private/py_runtime_pair_rule.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ Example usage:
```python
# In your BUILD file...
load("@rules_python//python:defs.bzl", "py_runtime_pair")
load("@rules_python//python:py_runtime.bzl", "py_runtime")
load("@rules_python//python:py_runtime_pair.bzl", "py_runtime_pair")
py_runtime(
name = "my_py2_runtime",
Expand Down
3 changes: 2 additions & 1 deletion python/py_runtime_pair.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ def py_runtime_pair(name, py2_runtime = None, py3_runtime = None, **attrs):
```python
# In your BUILD file...
load("@rules_python//python:defs.bzl", "py_runtime_pair")
load("@rules_python//python:py_runtime.bzl", "py_runtime")
load("@rules_python//python:py_runtime_pair.bzl", "py_runtime_pair")
py_runtime(
name = "my_py3_runtime",
Expand Down
3 changes: 2 additions & 1 deletion python/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,8 @@ def _python_repository_impl(rctx):
build_content = """\
# Generated by python/repositories.bzl
load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair")
load("@rules_python//python:py_runtime.bzl", "py_runtime")
load("@rules_python//python:py_runtime_pair.bzl", "py_runtime_pair")
load("@rules_python//python/cc:py_cc_toolchain.bzl", "py_cc_toolchain")
package(default_visibility = ["//visibility:public"])
Expand Down
3 changes: 3 additions & 0 deletions tests/config_settings/transition/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
load(":multi_version_tests.bzl", "multi_version_test_suite")
load(":py_args_tests.bzl", "py_args_test_suite")

py_args_test_suite(name = "py_args_tests")

multi_version_test_suite(name = "multi_version_tests")
68 changes: 68 additions & 0 deletions tests/config_settings/transition/multi_version_tests.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Copyright 2023 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.
"""Tests for py_test."""

load("@rules_testing//lib:analysis_test.bzl", "analysis_test")
load("@rules_testing//lib:test_suite.bzl", "test_suite")
load("@rules_testing//lib:util.bzl", rt_util = "util")
load("//python:versions.bzl", "TOOL_VERSIONS")
load("//python/config_settings:transition.bzl", py_binary_transitioned = "py_binary", py_test_transitioned = "py_test")

_tests = []

def _test_py_test_with_transition(name):
rt_util.helper_target(
py_test_transitioned,
name = name + "_subject",
srcs = [name + "_subject.py"],
python_version = TOOL_VERSIONS.keys()[0],
)

analysis_test(
name = name,
target = name + "_subject",
impl = _test_py_test_with_transition_impl,
)

def _test_py_test_with_transition_impl(env, target):
# Nothing to assert; we just want to make sure it builds
_ = env, target # @unused

_tests.append(_test_py_test_with_transition)

def _test_py_binary_with_transition(name):
rt_util.helper_target(
py_binary_transitioned,
name = name + "_subject",
srcs = [name + "_subject.py"],
python_version = TOOL_VERSIONS.keys()[0],
)

analysis_test(
name = name,
target = name + "_subject",
impl = _test_py_binary_with_transition_impl,
)

def _test_py_binary_with_transition_impl(env, target):
# Nothing to assert; we just want to make sure it builds
_ = env, target # @unused

_tests.append(_test_py_binary_with_transition)

def multi_version_test_suite(name):
test_suite(
name = name,
tests = _tests,
)

0 comments on commit 94c89e6

Please sign in to comment.