From c6b5adc1cca82393bfdbfa79dedede5313f79b4f Mon Sep 17 00:00:00 2001 From: Fahrzin Hemmati Date: Sat, 19 Nov 2022 14:45:38 -0800 Subject: [PATCH 1/4] Enable custom py_binary stub_template attribute (via py_runtime) Fixes #137, but unlike my approach in #6632, this adds an attribute to `py_runtime` rather than to `py_binary` Open to suggestions on the attribute name and documentation --- .../build/lib/bazel/rules/python/BUILD | 1 + .../rules/python/BazelPyRuleClasses.java | 7 ++++ .../rules/python/BazelPythonSemantics.java | 20 +++++++-- .../build/lib/rules/python/PyRuntime.java | 5 ++- .../build/lib/rules/python/PyRuntimeInfo.java | 41 +++++++++++++++---- .../build/lib/rules/python/PyRuntimeRule.java | 10 ++++- .../python/PyRuntimeInfoApi.java | 21 ++++++++++ src/main/starlark/builtins_bzl/BUILD | 1 + .../builtins_bzl/common/python/providers.bzl | 8 +++- .../common/python/py_runtime_rule.bzl | 25 ++++++++++- .../packages/util/BazelMockPythonSupport.java | 1 + .../lib/rules/python/PyRuntimeInfoTest.java | 9 +++- tools/python/BUILD.tools | 1 + .../python/python_bootstrap_template.txt | 0 14 files changed, 132 insertions(+), 18 deletions(-) rename src/main/java/com/google/devtools/build/lib/bazel/rules/python/python_stub_template.txt => tools/python/python_bootstrap_template.txt (100%) diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BUILD b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BUILD index 7493ceffc59c67..b1546d7c036672 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BUILD +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BUILD @@ -46,6 +46,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib/packages", "//src/main/java/com/google/devtools/build/lib/rules/cpp", "//src/main/java/com/google/devtools/build/lib/rules/python", + "//src/main/java/com/google/devtools/build/lib/util:filetype", "//src/main/java/com/google/devtools/build/lib/util:os", "//src/main/java/com/google/devtools/build/lib/vfs:pathfragment", "//src/main/java/com/google/devtools/common/options", diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java index fedc65cc494133..b6746ab0964a70 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java @@ -37,6 +37,8 @@ import com.google.devtools.build.lib.rules.python.PyInfo; import com.google.devtools.build.lib.rules.python.PyRuleClasses; import com.google.devtools.build.lib.rules.python.PythonVersion; +import com.google.devtools.build.lib.rules.python.PyRuntimeInfo; +import com.google.devtools.build.lib.util.FileTypeSet; /** * Bazel-specific rule definitions for Python rules. @@ -221,6 +223,11 @@ responsible for creating (possibly empty) __init__.py files and adding them to t .add( attr("$py_toolchain_type", NODEP_LABEL) .value(env.getToolsLabel("//tools/python:toolchain_type"))) + /* Only used when no py_runtime() is available. See #7901 + */ + .add( + attr("$default_bootstrap_template", LABEL) + .value(env.getToolsLabel(PyRuntimeInfo.DEFAULT_BOOTSTRAP_TEMPLATE))) .addToolchainTypes( ToolchainTypeRequirement.builder(env.getToolsLabel("//tools/python:toolchain_type")) .mandatory(true) diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java index 363098d6917604..c7f4097088e25f 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java @@ -23,6 +23,7 @@ import com.google.devtools.build.lib.actions.CommandLineItem; import com.google.devtools.build.lib.actions.ParamFileInfo; import com.google.devtools.build.lib.actions.ParameterFile; +import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException; import com.google.devtools.build.lib.analysis.AnalysisUtils; import com.google.devtools.build.lib.analysis.FilesToRunProvider; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; @@ -62,8 +63,6 @@ public class BazelPythonSemantics implements PythonSemantics { public static final Runfiles.EmptyFilesSupplier GET_INIT_PY_FILES = new PythonUtils.GetInitPyFiles((Predicate & Serializable) source -> false); - private static final Template STUB_TEMPLATE = - Template.forResource(BazelPythonSemantics.class, "python_stub_template.txt"); public static final PathFragment ZIP_RUNFILES_DIRECTORY_NAME = PathFragment.create("runfiles"); @@ -166,12 +165,14 @@ private static void createStubFile( attrVersion = config.getDefaultPythonVersion(); } + Artifact bootstrapTemplate = getBootstrapTemplate(ruleContext, common); + // Create the stub file. ruleContext.registerAction( new TemplateExpansionAction( ruleContext.getActionOwner(), + bootstrapTemplate, stubOutput, - STUB_TEMPLATE, ImmutableList.of( Substitution.of("%shebang%", getStubShebang(ruleContext, common)), Substitution.of("%main%", common.determineMainExecutableSource()), @@ -337,7 +338,7 @@ private static String getZipRunfilesPath( } // We put the whole runfiles tree under the ZIP_RUNFILES_DIRECTORY_NAME directory, by doing this // , we avoid the conflict between default workspace name "__main__" and __main__.py file. - // Note: This name has to be the same with the one in python_stub_template.txt. + // Note: This name has to be the same with the one in python_bootstrap_template.txt. return ZIP_RUNFILES_DIRECTORY_NAME.getRelative(zipRunfilesPath).toString(); } @@ -427,6 +428,17 @@ private static PyRuntimeInfo getRuntime(RuleContext ruleContext, PyCommon common : ruleContext.getPrerequisite(":py_interpreter", PyRuntimeInfo.PROVIDER); } + private static Artifact getBootstrapTemplate(RuleContext ruleContext, PyCommon common) { + PyRuntimeInfo provider = getRuntime(ruleContext, common); + if (provider != null) { + Artifact bootstrapTemplate = provider.getBootstrapTemplate(); + if (bootstrapTemplate != null) { + return bootstrapTemplate; + } + } + return ruleContext.getPrerequisiteArtifact("$default_bootstrap_template"); + } + private static void addRuntime( RuleContext ruleContext, PyCommon common, Runfiles.Builder builder) { PyRuntimeInfo provider = getRuntime(ruleContext, common); diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntime.java b/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntime.java index 5046be6ea52368..f0023bad3fd4b7 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntime.java +++ b/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntime.java @@ -110,13 +110,14 @@ public ConfiguredTarget create(RuleContext ruleContext) return null; } Preconditions.checkState(pythonVersion.isTargetValue()); + Artifact bootstrapTemplate = ruleContext.getPrerequisiteArtifact("bootstrap_template"); PyRuntimeInfo provider = hermetic ? PyRuntimeInfo.createForInBuildRuntime( - interpreter, files, coverageTool, coverageFiles, pythonVersion, stubShebang) + interpreter, files, coverageTool, coverageFiles, pythonVersion, stubShebang, bootstrapTemplate) : PyRuntimeInfo.createForPlatformRuntime( - interpreterPath, coverageTool, coverageFiles, pythonVersion, stubShebang); + interpreterPath, coverageTool, coverageFiles, pythonVersion, stubShebang, bootstrapTemplate); return new RuleConfiguredTargetBuilder(ruleContext) .setFilesToBuild(files) diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfo.java b/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfo.java index 5d812965b67075..c3d02d53d14b69 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfo.java +++ b/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfo.java @@ -32,6 +32,7 @@ import net.starlark.java.eval.Starlark; import net.starlark.java.eval.StarlarkThread; import net.starlark.java.syntax.Location; +import com.google.devtools.build.lib.analysis.configuredtargets.InputFileConfiguredTarget; /** * Instance of the provider type that describes Python runtimes. @@ -62,6 +63,7 @@ public final class PyRuntimeInfo implements Info, PyRuntimeInfoApi { private final PythonVersion pythonVersion; private final String stubShebang; + @Nullable private final Artifact bootstrapTemplate; private PyRuntimeInfo( @Nullable Location location, @@ -71,7 +73,8 @@ private PyRuntimeInfo( @Nullable Artifact coverageTool, @Nullable Depset coverageFiles, PythonVersion pythonVersion, - @Nullable String stubShebang) { + @Nullable String stubShebang, + @Nullable Artifact bootstrapTemplate) { Preconditions.checkArgument((interpreterPath == null) != (interpreter == null)); Preconditions.checkArgument((interpreter == null) == (files == null)); Preconditions.checkArgument((coverageTool == null) == (coverageFiles == null)); @@ -88,6 +91,7 @@ private PyRuntimeInfo( } else { this.stubShebang = PyRuntimeInfoApi.DEFAULT_STUB_SHEBANG; } + this.bootstrapTemplate = bootstrapTemplate; } @Override @@ -107,7 +111,8 @@ public static PyRuntimeInfo createForInBuildRuntime( @Nullable Artifact coverageTool, @Nullable NestedSet coverageFiles, PythonVersion pythonVersion, - @Nullable String stubShebang) { + @Nullable String stubShebang, + @Nullable Artifact bootstrapTemplate) { return new PyRuntimeInfo( /*location=*/ null, /*interpreterPath=*/ null, @@ -116,7 +121,8 @@ public static PyRuntimeInfo createForInBuildRuntime( coverageTool, coverageFiles == null ? null : Depset.of(Artifact.TYPE, coverageFiles), pythonVersion, - stubShebang); + stubShebang, + bootstrapTemplate); } /** Constructs an instance from native rule logic (built-in location) for a platform runtime. */ @@ -125,7 +131,8 @@ public static PyRuntimeInfo createForPlatformRuntime( @Nullable Artifact coverageTool, @Nullable NestedSet coverageFiles, PythonVersion pythonVersion, - @Nullable String stubShebang) { + @Nullable String stubShebang, + @Nullable Artifact bootstrapTemplate) { return new PyRuntimeInfo( /*location=*/ null, interpreterPath, @@ -134,7 +141,8 @@ public static PyRuntimeInfo createForPlatformRuntime( coverageTool, coverageFiles == null ? null : Depset.of(Artifact.TYPE, coverageFiles), pythonVersion, - stubShebang); + stubShebang, + bootstrapTemplate); } @Override @@ -202,6 +210,12 @@ public String getStubShebang() { return stubShebang; } + @Override + @Nullable + public Artifact getBootstrapTemplate() { + return bootstrapTemplate; + } + @Nullable public NestedSet getFiles() { try { @@ -264,11 +278,22 @@ public PyRuntimeInfo constructor( Object coverageFilesUncast, String pythonVersion, String stubShebang, + Object bootstrapTemplateUncast, StarlarkThread thread) throws EvalException { String interpreterPath = interpreterPathUncast == NONE ? null : (String) interpreterPathUncast; Artifact interpreter = interpreterUncast == NONE ? null : (Artifact) interpreterUncast; + Artifact bootstrapTemplate = null; + if (bootstrapTemplateUncast != NONE) { + if (bootstrapTemplateUncast instanceof InputFileConfiguredTarget) { + InputFileConfiguredTarget bootstrapTarget = (InputFileConfiguredTarget) bootstrapTemplateUncast; + bootstrapTemplate = bootstrapTarget.getArtifact(); + } else if (bootstrapTemplateUncast instanceof Artifact) { + // SourceArtifact, possibly only in tests? + bootstrapTemplate = (Artifact) bootstrapTemplateUncast; + } + } Depset filesDepset = null; if (filesUncast != NONE) { // Validate type of filesDepset. @@ -312,7 +337,8 @@ public PyRuntimeInfo constructor( coverageTool, coverageDepset, parsedPythonVersion, - stubShebang); + stubShebang, + bootstrapTemplate); } else { return new PyRuntimeInfo( loc, @@ -322,7 +348,8 @@ public PyRuntimeInfo constructor( coverageTool, coverageDepset, parsedPythonVersion, - stubShebang); + stubShebang, + bootstrapTemplate); } } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeRule.java b/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeRule.java index 1ec90325df7965..d94680f059bcc2 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeRule.java @@ -84,7 +84,7 @@

The entry point for the tool must be loadable by a python interpreter (e.g. a .allowedValues(PyRuleClasses.TARGET_PYTHON_ATTR_VALUE_SET)) /* - "Shebang" expression prepended to the bootstrapping Python stub script + "Shebang" expression prepended to the bootstrapping Python script used when executing py_binary targets.

See issue 8685 for @@ -93,6 +93,14 @@

The entry point for the tool must be loadable by a python interpreter (e.g. a

Does not apply to Windows. */ .add(attr("stub_shebang", STRING).value(PyRuntimeInfo.DEFAULT_STUB_SHEBANG)) + + /* + Previously referred to as the "Python stub script", this is the + entrypoint to every Python executable target. + */ + .add(attr("bootstrap_template", LABEL) + .value(env.getToolsLabel(PyRuntimeInfo.DEFAULT_BOOTSTRAP_TEMPLATE)) + .allowedFileTypes(FileTypeSet.ANY_FILE).singleArtifact()) .add(attr("output_licenses", LICENSE)) .build(); } diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java index 3aa47673d0ea3c..16ba609dd8b30e 100644 --- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java @@ -17,6 +17,7 @@ import com.google.devtools.build.docgen.annot.DocCategory; import com.google.devtools.build.docgen.annot.StarlarkConstructor; import com.google.devtools.build.lib.collect.nestedset.Depset; +import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.starlarkbuildapi.FileApi; import com.google.devtools.build.lib.starlarkbuildapi.core.ProviderApi; import javax.annotation.Nullable; @@ -46,6 +47,7 @@ public interface PyRuntimeInfoApi extends StarlarkValue { static final String DEFAULT_STUB_SHEBANG = "#!/usr/bin/env python3"; + static final String DEFAULT_BOOTSTRAP_TEMPLATE = "//tools/python:python_bootstrap_template.txt"; @StarlarkMethod( name = "interpreter_path", @@ -119,6 +121,15 @@ public interface PyRuntimeInfoApi extends StarlarkValue { + "to Windows.") String getStubShebang(); + @StarlarkMethod( + name = "bootstrap_template", + structField = true, + doc = + "The stub script template file to use. Should have %python_binary%, " + + "%workspace_name%, %main%, and %imports%. See " + + "@bazel_tools//tools/python:python_bootstrap_template.txt for more variables.") + FileT getBootstrapTemplate(); + /** Provider type for {@link PyRuntimeInfoApi} objects. */ @StarlarkBuiltin(name = "Provider", documented = false, doc = "") interface PyRuntimeInfoProviderApi extends ProviderApi { @@ -204,6 +215,15 @@ interface PyRuntimeInfoProviderApi extends ProviderApi { + "Default is " + DEFAULT_STUB_SHEBANG + "."), + @Param( + name = "bootstrap_template", + // allowedTypes = { + // @ParamType(type = FileApi.class), + // }, + positional = false, + named = true, + defaultValue = "None", + doc = ""), }, useStarlarkThread = true, selfCall = true) @@ -216,6 +236,7 @@ PyRuntimeInfoApi constructor( Object coverageFilesUncast, String pythonVersion, String stubShebang, + Object bootstrapTemplate, StarlarkThread thread) throws EvalException; } diff --git a/src/main/starlark/builtins_bzl/BUILD b/src/main/starlark/builtins_bzl/BUILD index 50cd2d9df378b4..ed83be545525b5 100644 --- a/src/main/starlark/builtins_bzl/BUILD +++ b/src/main/starlark/builtins_bzl/BUILD @@ -21,6 +21,7 @@ genrule( cmd = "$(location //src:zip_builtins)" + " ''" + # system zip " $@ src/main/starlark/builtins_bzl $(SRCS)", + message = "Building builtins_bzl.zip", output_to_bindir = 1, tools = ["//src:zip_builtins"], visibility = [ diff --git a/src/main/starlark/builtins_bzl/common/python/providers.bzl b/src/main/starlark/builtins_bzl/common/python/providers.bzl index 2e9bad6891ed42..3b9e4b3b60eb07 100644 --- a/src/main/starlark/builtins_bzl/common/python/providers.bzl +++ b/src/main/starlark/builtins_bzl/common/python/providers.bzl @@ -14,6 +14,7 @@ """Providers for Python rules.""" DEFAULT_STUB_SHEBANG = "#!/usr/bin/env python3" +DEFAULT_BOOTSTRAP_TEMPLATE = "@bazel_tools//tools/python:python_bootstrap_template.txt" _PYTHON_VERSION_VALUES = ["PY2", "PY3"] def _PyRuntimeInfo_init( @@ -24,7 +25,8 @@ def _PyRuntimeInfo_init( coverage_tool = None, coverage_files = None, python_version, - stub_shebang = None): + stub_shebang = None, + bootstrap_template = None): if (interpreter_path == None) == (interpreter == None): fail("exactly one of interpreter_path or interpreter must be set") if (interpreter == None) != (files == None): @@ -46,6 +48,7 @@ def _PyRuntimeInfo_init( "coverage_files": coverage_files, "python_version": python_version, "stub_shebang": stub_shebang, + "bootstrap_template": bootstrap_template, } # TODO(#15897): Rename this to PyRuntimeInfo when we're ready to replace the Java @@ -98,6 +101,9 @@ the same conventions as the standard CPython interpreter. "script used when executing `py_binary` targets. Does not " + "apply to Windows." ), + "bootstrap_template": ( + "See py_runtime_rule.bzl%py_runtime.bootstrap_template for docs." + ), }, ) 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 ec293019d56513..81a7a374e011d4 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 @@ -14,7 +14,7 @@ """Implementation of py_runtime rule.""" load(":common/paths.bzl", "paths") -load(":common/python/providers.bzl", "DEFAULT_STUB_SHEBANG", _PyRuntimeInfo = "PyRuntimeInfo") +load(":common/python/providers.bzl", "DEFAULT_STUB_SHEBANG", "DEFAULT_BOOTSTRAP_TEMPLATE", _PyRuntimeInfo = "PyRuntimeInfo") _py_builtins = _builtins.internal.py_builtins @@ -75,6 +75,7 @@ def _py_runtime_impl(ctx): coverage_files = coverage_files, python_version = python_version, stub_shebang = ctx.attr.stub_shebang, + bootstrap_template = ctx.attr.bootstrap_template, ), DefaultInfo( files = runtime_files, @@ -177,6 +178,28 @@ See https://github.com/bazelbuild/bazel/issues/8685 for motivation. Does not apply to Windows. +""", + ), + "bootstrap_template": attr.label( + allow_single_file = True, + default = DEFAULT_BOOTSTRAP_TEMPLATE, + doc = """ +The bootstrap script template file to use. Should have %python_binary%, +%workspace_name%, %main%, and %imports%. + +This template, after expansion, becomes the executable file used to start the +process, so it is responsible for initial bootstrapping actions such as finding +the Python interpreter, runfiles, and constructing an environment to run the +intended Python application. + +While this attribute is currently optional, it will become required when the +Python rules are moved out of Bazel itself. + +The exact variable names expanded is an unstable API and is subject to change. +The API will become more stable when the Python rules are moved out of Bazel +itself. + +See @bazel_tools//tools/python:python_bootstrap_template.txt for more variables. """, ), }, diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/BazelMockPythonSupport.java b/src/test/java/com/google/devtools/build/lib/packages/util/BazelMockPythonSupport.java index a95f2464a0c25e..ab4e3ef8a4559c 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/util/BazelMockPythonSupport.java +++ b/src/test/java/com/google/devtools/build/lib/packages/util/BazelMockPythonSupport.java @@ -39,6 +39,7 @@ public void setup(MockToolsConfig config) throws IOException { addTool(config, "tools/python/toolchain.bzl"); addTool(config, "tools/python/utils.bzl"); addTool(config, "tools/python/private/defs.bzl"); + addTool(config, "tools/python/python_bootstrap_template.txt"); config.create( TestConstants.TOOLS_REPOSITORY_SCRATCH + "tools/python/BUILD", diff --git a/src/test/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfoTest.java b/src/test/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfoTest.java index 3d51090fbb171c..aabeccc2b21de7 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfoTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfoTest.java @@ -59,7 +59,7 @@ public void factoryMethod_InBuildRuntime() throws Exception { NestedSet files = NestedSetBuilder.create(Order.STABLE_ORDER, dummyFile); PyRuntimeInfo inBuildRuntime = PyRuntimeInfo.createForInBuildRuntime( - dummyInterpreter, files, null, null, PythonVersion.PY2, null); + dummyInterpreter, files, null, null, PythonVersion.PY2, null, dummyFile); assertThat(inBuildRuntime.getCreationLocation()).isEqualTo(Location.BUILTIN); assertThat(inBuildRuntime.getInterpreterPath()).isNull(); @@ -76,7 +76,7 @@ public void factoryMethod_InBuildRuntime() throws Exception { public void factoryMethod_PlatformRuntime() { PathFragment path = PathFragment.create("/system/interpreter"); PyRuntimeInfo platformRuntime = - PyRuntimeInfo.createForPlatformRuntime(path, null, null, PythonVersion.PY2, null); + PyRuntimeInfo.createForPlatformRuntime(path, null, null, PythonVersion.PY2, null, dummyFile); assertThat(platformRuntime.getCreationLocation()).isEqualTo(Location.BUILTIN); assertThat(platformRuntime.getInterpreterPath()).isEqualTo(path); @@ -96,6 +96,7 @@ public void starlarkConstructor_InBuildRuntime() throws Exception { " interpreter = dummy_interpreter,", " files = depset([dummy_file]),", " python_version = 'PY2',", + " bootstrap_template = dummy_file,", ")"); PyRuntimeInfo info = (PyRuntimeInfo) ev.lookup("info"); assertThat(info.getCreationLocation().toString()).isEqualTo(":1:21"); @@ -104,6 +105,7 @@ public void starlarkConstructor_InBuildRuntime() throws Exception { assertHasOrderAndContainsExactly(info.getFiles(), Order.STABLE_ORDER, dummyFile); assertThat(info.getPythonVersion()).isEqualTo(PythonVersion.PY2); assertThat(info.getStubShebang()).isEqualTo(PyRuntimeInfo.DEFAULT_STUB_SHEBANG); + assertThat(info.getBootstrapTemplate()).isEqualTo(dummyFile); } @Test @@ -112,6 +114,7 @@ public void starlarkConstructor_PlatformRuntime() throws Exception { "info = PyRuntimeInfo(", // " interpreter_path = '/system/interpreter',", " python_version = 'PY2',", + " bootstrap_template = dummy_file,", ")"); PyRuntimeInfo info = (PyRuntimeInfo) ev.lookup("info"); assertThat(info.getCreationLocation().toString()).isEqualTo(":1:21"); @@ -129,6 +132,7 @@ public void starlarkConstructor_CustomShebang() throws Exception { " interpreter_path = '/system/interpreter',", " python_version = 'PY2',", " stub_shebang = '#!/usr/bin/custom',", + " bootstrap_template = dummy_file,", ")"); PyRuntimeInfo info = (PyRuntimeInfo) ev.lookup("info"); assertThat(info.getStubShebang()).isEqualTo("#!/usr/bin/custom"); @@ -140,6 +144,7 @@ public void starlarkConstructor_FilesDefaultsToEmpty() throws Exception { "info = PyRuntimeInfo(", // " interpreter = dummy_interpreter,", " python_version = 'PY2',", + " bootstrap_template = dummy_file,", ")"); PyRuntimeInfo info = (PyRuntimeInfo) ev.lookup("info"); assertHasOrderAndContainsExactly(info.getFiles(), Order.STABLE_ORDER); diff --git a/tools/python/BUILD.tools b/tools/python/BUILD.tools index 5031ee9fe14390..076c182914c34f 100644 --- a/tools/python/BUILD.tools +++ b/tools/python/BUILD.tools @@ -24,6 +24,7 @@ package(default_visibility = ["//visibility:public"]) # don't have access to Skylib here. See # https://github.com/bazelbuild/skydoc/issues/166. exports_files([ + "python_bootstrap_template.txt", "python_version.bzl", "srcs_version.bzl", "toolchain.bzl", diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/python_stub_template.txt b/tools/python/python_bootstrap_template.txt similarity index 100% rename from src/main/java/com/google/devtools/build/lib/bazel/rules/python/python_stub_template.txt rename to tools/python/python_bootstrap_template.txt From 8f221ed14b68d3ee9dffd812860b056eb51f15a1 Mon Sep 17 00:00:00 2001 From: Fahrzin Hemmati Date: Wed, 30 Nov 2022 13:46:04 -0800 Subject: [PATCH 2/4] ctx.attr => ctx.file fixes so many things --- .../devtools/build/lib/rules/python/PyRuntimeInfo.java | 8 +------- .../lib/starlarkbuildapi/python/PyRuntimeInfoApi.java | 6 +++--- .../builtins_bzl/common/python/py_runtime_rule.bzl | 2 +- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfo.java b/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfo.java index c3d02d53d14b69..2cb160f8fc0c1f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfo.java +++ b/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfo.java @@ -286,13 +286,7 @@ public PyRuntimeInfo constructor( Artifact interpreter = interpreterUncast == NONE ? null : (Artifact) interpreterUncast; Artifact bootstrapTemplate = null; if (bootstrapTemplateUncast != NONE) { - if (bootstrapTemplateUncast instanceof InputFileConfiguredTarget) { - InputFileConfiguredTarget bootstrapTarget = (InputFileConfiguredTarget) bootstrapTemplateUncast; - bootstrapTemplate = bootstrapTarget.getArtifact(); - } else if (bootstrapTemplateUncast instanceof Artifact) { - // SourceArtifact, possibly only in tests? - bootstrapTemplate = (Artifact) bootstrapTemplateUncast; - } + bootstrapTemplate = (Artifact) bootstrapTemplateUncast; } Depset filesDepset = null; if (filesUncast != NONE) { diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java index 16ba609dd8b30e..2196a221f21560 100644 --- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java @@ -217,9 +217,9 @@ interface PyRuntimeInfoProviderApi extends ProviderApi { + "."), @Param( name = "bootstrap_template", - // allowedTypes = { - // @ParamType(type = FileApi.class), - // }, + allowedTypes = { + @ParamType(type = FileApi.class), + }, positional = false, named = true, defaultValue = "None", 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 81a7a374e011d4..48868f6d3f030e 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 @@ -75,7 +75,7 @@ def _py_runtime_impl(ctx): coverage_files = coverage_files, python_version = python_version, stub_shebang = ctx.attr.stub_shebang, - bootstrap_template = ctx.attr.bootstrap_template, + bootstrap_template = ctx.file.bootstrap_template, ), DefaultInfo( files = runtime_files, From 2e4d9985ccb7866cdee34579b162c2fd23257d8e Mon Sep 17 00:00:00 2001 From: Fahrzin Hemmati Date: Wed, 21 Dec 2022 13:00:31 -0800 Subject: [PATCH 3/4] rickeylev review: removing unused code and using TOOLS_REPO --- .../google/devtools/build/lib/rules/python/PyRuntimeInfo.java | 1 - .../build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java | 2 +- src/main/starlark/builtins_bzl/common/python/providers.bzl | 4 +++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfo.java b/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfo.java index 2cb160f8fc0c1f..5d72a64ea9999e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfo.java +++ b/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeInfo.java @@ -32,7 +32,6 @@ import net.starlark.java.eval.Starlark; import net.starlark.java.eval.StarlarkThread; import net.starlark.java.syntax.Location; -import com.google.devtools.build.lib.analysis.configuredtargets.InputFileConfiguredTarget; /** * Instance of the provider type that describes Python runtimes. diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java index 2196a221f21560..96ff1c6b361ce5 100644 --- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java @@ -47,7 +47,6 @@ public interface PyRuntimeInfoApi extends StarlarkValue { static final String DEFAULT_STUB_SHEBANG = "#!/usr/bin/env python3"; - static final String DEFAULT_BOOTSTRAP_TEMPLATE = "//tools/python:python_bootstrap_template.txt"; @StarlarkMethod( name = "interpreter_path", @@ -219,6 +218,7 @@ interface PyRuntimeInfoProviderApi extends ProviderApi { name = "bootstrap_template", allowedTypes = { @ParamType(type = FileApi.class), + @ParamType(type = NoneType.class), }, positional = false, named = true, diff --git a/src/main/starlark/builtins_bzl/common/python/providers.bzl b/src/main/starlark/builtins_bzl/common/python/providers.bzl index 3b9e4b3b60eb07..813bc595f118fd 100644 --- a/src/main/starlark/builtins_bzl/common/python/providers.bzl +++ b/src/main/starlark/builtins_bzl/common/python/providers.bzl @@ -13,8 +13,10 @@ # limitations under the License. """Providers for Python rules.""" +load(":common/python/semantics.bzl", "TOOLS_REPO") + DEFAULT_STUB_SHEBANG = "#!/usr/bin/env python3" -DEFAULT_BOOTSTRAP_TEMPLATE = "@bazel_tools//tools/python:python_bootstrap_template.txt" +DEFAULT_BOOTSTRAP_TEMPLATE = "@" + TOOLS_REPO + "//tools/python:python_bootstrap_template.txt" _PYTHON_VERSION_VALUES = ["PY2", "PY3"] def _PyRuntimeInfo_init( From 32d61933f025efd7fcbe80b801da6af1de25ea6a Mon Sep 17 00:00:00 2001 From: Fahrzin Hemmati Date: Wed, 21 Dec 2022 13:04:04 -0800 Subject: [PATCH 4/4] add back DEFAULT_BOOTSTRAP_TEMPLATE string --- .../build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java index 96ff1c6b361ce5..c074f076ac55c6 100644 --- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/python/PyRuntimeInfoApi.java @@ -47,6 +47,8 @@ public interface PyRuntimeInfoApi extends StarlarkValue { static final String DEFAULT_STUB_SHEBANG = "#!/usr/bin/env python3"; + // Must call getToolsLabel() when using this. + static final String DEFAULT_BOOTSTRAP_TEMPLATE = "//tools/python:python_bootstrap_template.txt"; @StarlarkMethod( name = "interpreter_path",