Skip to content

Commit

Permalink
Implement most of py_runtime in Starlark
Browse files Browse the repository at this point in the history
Work towards bazelbuild#15897

PiperOrigin-RevId: 483722548
Change-Id: Ieee7859e516a946286eeb07f9a86d1ea2b159aa0
  • Loading branch information
rickeylev authored and Lucas Ripoche committed Jun 13, 2023
1 parent 87e7581 commit 8eb6bf3
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 2 deletions.
Expand Up @@ -25,6 +25,7 @@
import com.google.devtools.common.options.TriState;
import javax.annotation.Nullable;
import net.starlark.java.annot.StarlarkBuiltin;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.StarlarkValue;

/**
Expand Down Expand Up @@ -95,6 +96,14 @@ public PythonVersion getDefaultPythonVersion() {
return defaultVersion;
}

@StarlarkMethod(
name = "default_python_version",
structField = true,
doc = "The default python version from --incompatible_py3_is_default")
public String getDefaultPythonVersionForStarlark() {
return defaultVersion.name();
}

@Override
@Nullable
public String getOutputDirectoryName() {
Expand Down Expand Up @@ -140,6 +149,10 @@ public boolean buildTransitiveRunfilesTrees() {
* Returns true if executable Python rules should obtain their runtime from the Python toolchain
* rather than legacy flags.
*/
@StarlarkMethod(
name = "use_toolchains",
structField = true,
doc = "The value from the --incompatible_use_python_toolchains flag")
public boolean useToolchains() {
return useToolchains;
}
Expand Down
65 changes: 63 additions & 2 deletions src/main/starlark/builtins_bzl/common/python/py_runtime_rule.bzl
Expand Up @@ -13,9 +13,70 @@
# limitations under the License.
"""Implementation of py_runtime rule."""

load(":common/paths.bzl", "paths")

_PyRuntimeInfo = _builtins.toplevel.PyRuntimeInfo

def _py_runtime_impl(ctx):
_ = ctx # @unused
fail("not implemented")
interpreter_path = ctx.attr.interpreter_path
interpreter = ctx.file.interpreter
if (interpreter_path and interpreter) or (not interpreter_path and not interpreter):
fail("exactly one of the 'interpreter' or 'interpreter_path' attributes must be specified")

hermetic = bool(interpreter)
runtime_files = ctx.attr.files[DefaultInfo].files
if not hermetic:
if runtime_files:
fail("if 'interpreter_path' is given then 'files' must be empty")
if not paths.is_absolute(interpreter_path):
fail("interpreter_path must be an absolute path")

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]
elif coverage_di.files_to_run and coverage_di.files_to_run.executable:
coverage_tool = coverage_di.files_to_run.executable
else:
fail("coverage_tool must be an executable target or must produce exactly one file.")

coverage_files = depset(transitive = [
coverage_di.files,
coverage_di.default_runfiles.files,
])
else:
coverage_tool = None
coverage_files = None

python_version = ctx.attr.python_version
if python_version == "_INTERNAL_SENTINEL":
if ctx.fragments.py.use_toolchains:
fail(
"When using Python toolchains, this attribute must be set explicitly to either 'PY2' " +
"or 'PY3'. See https://github.com/bazelbuild/bazel/issues/7899 for more " +
"information. You can temporarily avoid this error by reverting to the legacy " +
"Python runtime mechanism (`--incompatible_use_python_toolchains=false`).",
)
else:
python_version = ctx.fragments.default_python_version

return [
_PyRuntimeInfo(
files = runtime_files,
coverage_tool = coverage_tool,
coverage_files = coverage_files,
python_version = python_version,
stub_shebang = ctx.attr.stub_shebang,
),
DefaultInfo(
files = runtime_files,
runfiles = ctx.runfiles(),
),
]

# Bind to the name "py_runtime" to preserve the kind/rule_class it shows up
# as elsewhere.
Expand Down

0 comments on commit 8eb6bf3

Please sign in to comment.