Add `is_singleton_depset` to optimize how `py_runtime` finds the coverage tool.
Work towards #15897
PiperOrigin-RevId: 485161913
Change-Id: I65128d9371a3e2124b2a82143530d88ba23e49b7
diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PyBuiltins.java b/src/main/java/com/google/devtools/build/lib/rules/python/PyBuiltins.java
index 5c81813..ca87b89 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/python/PyBuiltins.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/python/PyBuiltins.java
@@ -13,11 +13,29 @@
// limitations under the License.
package com.google.devtools.build.lib.rules.python;
+import com.google.devtools.build.lib.collect.nestedset.Depset;
+import net.starlark.java.annot.Param;
import net.starlark.java.annot.StarlarkBuiltin;
+import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.StarlarkValue;
/** Bridge to allow builtins bzl code to call Java code. */
@StarlarkBuiltin(name = "py_builtins", documented = false)
public abstract class PyBuiltins implements StarlarkValue {
public static final String NAME = "py_builtins";
+
+ @StarlarkMethod(
+ name = "is_singleton_depset",
+ doc = "Efficiently checks if the depset is a singleton.",
+ parameters = {
+ @Param(
+ name = "value",
+ positional = true,
+ named = false,
+ defaultValue = "unbound",
+ doc = "depset to check for being a singleton")
+ })
+ public boolean isSingletonDepset(Depset depset) {
+ return depset.getSet().isSingleton();
+ }
}
diff --git a/src/main/starlark/builtins_bzl/common/python/py_internal.bzl b/src/main/starlark/builtins_bzl/common/python/py_internal.bzl
index 9b4d4cb..5b437a4 100644
--- a/src/main/starlark/builtins_bzl/common/python/py_internal.bzl
+++ b/src/main/starlark/builtins_bzl/common/python/py_internal.bzl
@@ -14,6 +14,8 @@
"""PYTHON RULE IMPLEMENTATION ONLY: Do not use outside of the rule implementations and their tests.
Various builtin Starlark defined objects exposed for non-builtin Starlark.
+
+These may change at any time and are closely coupled to the rule implementation.
"""
# This replaces the Java-defined name using exports.bzl toplevels mapping.
diff --git a/src/main/starlark/builtins_bzl/common/python/py_runtime_rule.bzl b/src/main/starlark/builtins_bzl/common/python/py_runtime_rule.bzl
index 77c9458..b59aaee 100644
--- a/src/main/starlark/builtins_bzl/common/python/py_runtime_rule.bzl
+++ b/src/main/starlark/builtins_bzl/common/python/py_runtime_rule.bzl
@@ -17,6 +17,8 @@
_PyRuntimeInfo = _builtins.toplevel.PyRuntimeInfo
+_py_builtins = _builtins.internal.py_builtins
+
def _py_runtime_impl(ctx):
interpreter_path = ctx.attr.interpreter_path or None # Convert empty string to None
interpreter = ctx.file.interpreter
@@ -38,11 +40,8 @@
if ctx.attr.coverage_tool:
coverage_di = ctx.attr.coverage_tool[DefaultInfo]
- # TODO(b/254866025): Use a Java helper to call NestedSet.isSingleton
- # instead of always flattening to a list
- coverage_di_files = coverage_di.files.to_list()
- if len(coverage_di_files) == 1:
- coverage_tool = coverage_di_files[0]
+ if _py_builtins.is_singleton_depset(coverage_di.files):
+ coverage_tool = coverage_di.files.to_list()[0]
elif coverage_di.files_to_run and coverage_di.files_to_run.executable:
coverage_tool = coverage_di.files_to_run.executable
else: