fix(PyRuntimeInfo): use builtin PyRuntimeInfo unless pystar is enabled. (#1748)
This fixes the bug where the PyRuntimeInfo symbol rules_python exported
wasn't matching the provider identity that `py_binary` actually
provided.
The basic problem was, when pystar is disabled:
* PyRuntimeInfo is the rules_python defined provider
* py_binary is `native.py_binary`, which provides only the builtin
PyRuntimeInfo provider.
Thus, when users loaded the rules_python PyRuntimeInfo symbol, it was
referring to a provider that the underlying py_binary didn't actually
provide. Pystar is always disabled on Bazel 6.4,
and enabling it for Bazel 7 will happen eminently.
This typically showed up when users had a custom rule with an attribute
definition that used the rules_python PyRuntimeInfo.
To fix, only use the rules_python define PyRuntimeInfo if pystar is
enabled. This ensures the providers the underlying rules are providing
match the symbols that rules_python is exported.
* Also fixes `py_binary` and `py_test` to also return the builtin
PyRuntimeInfo. This
should make the transition from the builtin symbols to the rules_python
symbols a bit
easier.
Fixes https://github.com/bazelbuild/rules_python/issues/1732
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5923c5e..6338e9c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -48,6 +48,11 @@
* (toolchain) Changed the `host_toolchain` to symlink all files to support
Windows host environments without symlink support.
+* (PyRuntimeInfo) Switch back to builtin PyRuntimeInfo for Bazel 6.4 and when
+ pystar is disabled. This fixes an error about `target ... does not have ...
+ PyRuntimeInfo`.
+ ([#1732](https://github.com/bazelbuild/rules_python/issues/1732))
+
### Added
* (py_wheel) Added `requires_file` and `extra_requires_files` attributes.
diff --git a/python/private/common/py_executable.bzl b/python/private/common/py_executable.bzl
index a0720c1..410fb1d 100644
--- a/python/private/common/py_executable.bzl
+++ b/python/private/common/py_executable.bzl
@@ -14,6 +14,7 @@
"""Common functionality between test/binary executables."""
load("@bazel_skylib//lib:dicts.bzl", "dicts")
+load("//python/private:reexports.bzl", "BuiltinPyRuntimeInfo")
load(
":attributes.bzl",
"AGNOSTIC_EXECUTABLE_ATTRS",
@@ -771,7 +772,28 @@
# TODO(b/265840007): Make this non-conditional once Google enables
# --incompatible_use_python_toolchains.
if runtime_details.toolchain_runtime:
- providers.append(runtime_details.toolchain_runtime)
+ py_runtime_info = runtime_details.toolchain_runtime
+ providers.append(py_runtime_info)
+
+ # Re-add the builtin PyRuntimeInfo for compatibility to make
+ # transitioning easier, but only if it isn't already added because
+ # returning the same provider type multiple times is an error.
+ # NOTE: The PyRuntimeInfo from the toolchain could be a rules_python
+ # PyRuntimeInfo or a builtin PyRuntimeInfo -- a user could have used the
+ # builtin py_runtime rule or defined their own. We can't directly detect
+ # the type of the provider object, but the rules_python PyRuntimeInfo
+ # object has an extra attribute that the builtin one doesn't.
+ if hasattr(py_runtime_info, "interpreter_version_info"):
+ providers.append(BuiltinPyRuntimeInfo(
+ interpreter_path = py_runtime_info.interpreter_path,
+ interpreter = py_runtime_info.interpreter,
+ files = py_runtime_info.files,
+ coverage_tool = py_runtime_info.coverage_tool,
+ coverage_files = py_runtime_info.coverage_files,
+ python_version = py_runtime_info.python_version,
+ stub_shebang = py_runtime_info.stub_shebang,
+ bootstrap_template = py_runtime_info.bootstrap_template,
+ ))
# TODO(b/163083591): Remove the PyCcLinkParamsProvider once binaries-in-deps
# are cleaned up.
diff --git a/python/py_runtime_info.bzl b/python/py_runtime_info.bzl
index c0a9288..e88e0c0 100644
--- a/python/py_runtime_info.bzl
+++ b/python/py_runtime_info.bzl
@@ -14,8 +14,8 @@
"""Public entry point for PyRuntimeInfo."""
+load("@rules_python_internal//:rules_python_config.bzl", "config")
load("//python/private:reexports.bzl", "BuiltinPyRuntimeInfo")
-load("//python/private:util.bzl", "IS_BAZEL_6_OR_HIGHER")
load("//python/private/common:providers.bzl", _starlark_PyRuntimeInfo = "PyRuntimeInfo")
-PyRuntimeInfo = _starlark_PyRuntimeInfo if IS_BAZEL_6_OR_HIGHER else BuiltinPyRuntimeInfo
+PyRuntimeInfo = _starlark_PyRuntimeInfo if config.enable_pystar else BuiltinPyRuntimeInfo
diff --git a/tests/base_rules/py_executable_base_tests.bzl b/tests/base_rules/py_executable_base_tests.bzl
index 3960579..ce86eca 100644
--- a/tests/base_rules/py_executable_base_tests.bzl
+++ b/tests/base_rules/py_executable_base_tests.bzl
@@ -13,6 +13,7 @@
# limitations under the License.
"""Tests common to py_binary and py_test (executable rules)."""
+load("@rules_python//python:py_runtime_info.bzl", RulesPythonPyRuntimeInfo = "PyRuntimeInfo")
load("@rules_python_internal//:rules_python_config.bzl", rp_config = "config")
load("@rules_testing//lib:analysis_test.bzl", "analysis_test")
load("@rules_testing//lib:truth.bzl", "matching")
@@ -21,6 +22,8 @@
load("//tests/base_rules:util.bzl", "WINDOWS_ATTR", pt_util = "util")
load("//tests/support:test_platforms.bzl", "WINDOWS")
+_BuiltinPyRuntimeInfo = PyRuntimeInfo
+
_tests = []
def _test_basic_windows(name, config):
@@ -275,6 +278,28 @@
matching.str_matches("name must not end in*.py"),
)
+def _test_py_runtime_info_provided(name, config):
+ rt_util.helper_target(
+ config.rule,
+ name = name + "_subject",
+ srcs = [name + "_subject.py"],
+ )
+ analysis_test(
+ name = name,
+ impl = _test_py_runtime_info_provided_impl,
+ target = name + "_subject",
+ )
+
+def _test_py_runtime_info_provided_impl(env, target):
+ # Make sure that the rules_python loaded symbol is provided.
+ env.expect.that_target(target).has_provider(RulesPythonPyRuntimeInfo)
+
+ # For compatibility during the transition, the builtin PyRuntimeInfo should
+ # also be provided.
+ env.expect.that_target(target).has_provider(_BuiltinPyRuntimeInfo)
+
+_tests.append(_test_py_runtime_info_provided)
+
# Can't test this -- mandatory validation happens before analysis test
# can intercept it
# TODO(#1069): Once re-implemented in Starlark, modify rule logic to make this