Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 4862a8d

Browse filesBrowse files
authored
internal(pystar): Make py_runtime_pair and autodetecting toolchain mostly loadable. (bazel-contrib#1439)
They aren't quite usable yet. This mostly fixes references and adds surrounding infrastructure to make this mostly loadable and somewhat runnable. Note that the "autodetecting" name is misleading: it doesn't really autodetect anything. But it's the established name and part of the public API. The autodetecting toolchain is trimmed down from what Bazel does. The Bazel version has a Python 2 variant and a "non strict" mode to support that. With Python 2 no longer supported, that code is removed. * Also alphabetically sorts the bzl_libraries in //python/private Work towards bazel-contrib#1069
1 parent 0c1ce6f commit 4862a8d
Copy full SHA for 4862a8d

5 files changed

+130
-81
lines changed

‎python/private/BUILD.bazel

Copy file name to clipboardExpand all lines: python/private/BUILD.bazel
+39-15Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,12 @@ filegroup(
4444
)
4545

4646
bzl_library(
47-
name = "reexports_bzl",
48-
srcs = ["reexports.bzl"],
49-
visibility = [
50-
"//docs:__pkg__",
51-
"//python:__pkg__",
47+
name = "autodetecting_toolchain_bzl",
48+
srcs = ["autodetecting_toolchain.bzl"],
49+
deps = [
50+
"//python:py_runtime_bzl",
51+
"//python:py_runtime_pair_bzl",
5252
],
53-
deps = [":bazel_tools_bzl"],
5453
)
5554

5655
bzl_library(
@@ -63,15 +62,6 @@ bzl_library(
6362
deps = ["@bazel_skylib//lib:types"],
6463
)
6564

66-
bzl_library(
67-
name = "which_bzl",
68-
srcs = ["which.bzl"],
69-
visibility = [
70-
"//docs:__subpackages__",
71-
"//python:__subpackages__",
72-
],
73-
)
74-
7565
bzl_library(
7666
name = "py_cc_toolchain_bzl",
7767
srcs = [
@@ -112,6 +102,21 @@ bzl_library(
112102
visibility = ["//:__subpackages__"],
113103
)
114104

105+
bzl_library(
106+
name = "py_runtime_pair_macro_bzl",
107+
srcs = ["py_runtime_pair_rule.bzl"],
108+
deps = [":py_runtime_pair_rule_bzl"],
109+
)
110+
111+
bzl_library(
112+
name = "py_runtime_pair_rule_bzl",
113+
srcs = ["py_runtime_pair_rule.bzl"],
114+
deps = [
115+
"//python:py_runtime_bzl",
116+
"//python:py_runtime_info_bzl",
117+
],
118+
)
119+
115120
bzl_library(
116121
name = "py_wheel_bzl",
117122
srcs = ["py_wheel.bzl"],
@@ -122,12 +127,31 @@ bzl_library(
122127
],
123128
)
124129

130+
bzl_library(
131+
name = "reexports_bzl",
132+
srcs = ["reexports.bzl"],
133+
visibility = [
134+
"//docs:__pkg__",
135+
"//python:__pkg__",
136+
],
137+
deps = [":bazel_tools_bzl"],
138+
)
139+
125140
bzl_library(
126141
name = "stamp_bzl",
127142
srcs = ["stamp.bzl"],
128143
visibility = ["//:__subpackages__"],
129144
)
130145

146+
bzl_library(
147+
name = "which_bzl",
148+
srcs = ["which.bzl"],
149+
visibility = [
150+
"//docs:__subpackages__",
151+
"//python:__subpackages__",
152+
],
153+
)
154+
131155
# @bazel_tools can't define bzl_library itself, so we just put a wrapper around it.
132156
bzl_library(
133157
name = "bazel_tools_bzl",

‎python/private/autodetecting_toolchain.bzl

Copy file name to clipboardExpand all lines: python/private/autodetecting_toolchain.bzl
+4-61Lines changed: 4 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -14,51 +14,21 @@
1414

1515
"""Definitions related to the Python toolchain."""
1616

17-
load(":utils.bzl", "expand_pyversion_template")
17+
load("//python:py_runtime.bzl", "py_runtime")
18+
load("//python:py_runtime_pair.bzl", "py_runtime_pair")
1819

19-
def define_autodetecting_toolchain(
20-
name,
21-
pywrapper_template,
22-
windows_config_setting):
20+
def define_autodetecting_toolchain(name):
2321
"""Defines the autodetecting Python toolchain.
2422
25-
This includes both strict and non-strict variants.
26-
27-
For use only by @bazel_tools//tools/python:BUILD; see the documentation
28-
comment there.
29-
3023
Args:
3124
name: The name of the toolchain to introduce. Must have value
3225
"autodetecting_toolchain". This param is present only to make the
3326
BUILD file more readable.
34-
pywrapper_template: The label of the pywrapper_template.txt file.
35-
windows_config_setting: The label of a config_setting that matches when
36-
the platform is windows, in which case the toolchain is configured
37-
in a way that triggers a workaround for #7844.
3827
"""
39-
if native.package_name() != "tools/python":
40-
fail("define_autodetecting_toolchain() is private to " +
41-
"@bazel_tools//tools/python")
4228
if name != "autodetecting_toolchain":
4329
fail("Python autodetecting toolchain must be named " +
4430
"'autodetecting_toolchain'")
4531

46-
expand_pyversion_template(
47-
name = "_generate_wrappers",
48-
template = pywrapper_template,
49-
out2 = ":py2wrapper.sh",
50-
out3 = ":py3wrapper.sh",
51-
out2_nonstrict = ":py2wrapper_nonstrict.sh",
52-
out3_nonstrict = ":py3wrapper_nonstrict.sh",
53-
visibility = ["//visibility:private"],
54-
)
55-
56-
# Note that the pywrapper script is a .sh file, not a sh_binary target. If
57-
# we needed to make it a proper shell target, e.g. because it needed to
58-
# access runfiles and needed to depend on the runfiles library, then we'd
59-
# have to use a workaround to allow it to be depended on by py_runtime. See
60-
# https://github.com/bazelbuild/bazel/issues/4286#issuecomment-475661317.
61-
6232
# buildifier: disable=native-py
6333
py_runtime(
6434
name = "_autodetecting_py3_runtime",
@@ -68,15 +38,6 @@ def define_autodetecting_toolchain(
6838
visibility = ["//visibility:private"],
6939
)
7040

71-
# buildifier: disable=native-py
72-
py_runtime(
73-
name = "_autodetecting_py3_runtime_nonstrict",
74-
interpreter = ":py3wrapper_nonstrict.sh",
75-
python_version = "PY3",
76-
stub_shebang = "#!/usr/bin/env python3",
77-
visibility = ["//visibility:private"],
78-
)
79-
8041
# This is a dummy runtime whose interpreter_path triggers the native rule
8142
# logic to use the legacy behavior on Windows.
8243
# TODO(#7844): Remove this target.
@@ -95,33 +56,15 @@ def define_autodetecting_toolchain(
9556
# that we attempted to use the autodetecting toolchain and need to
9657
# switch back to legacy behavior.
9758
# TODO(#7844): Remove this hack.
98-
windows_config_setting: ":_magic_sentinel_runtime",
59+
"@platforms//os:windows": ":_magic_sentinel_runtime",
9960
"//conditions:default": ":_autodetecting_py3_runtime",
10061
}),
10162
visibility = ["//visibility:public"],
10263
)
10364

104-
py_runtime_pair(
105-
name = "_autodetecting_py_runtime_pair_nonstrict",
106-
py3_runtime = select({
107-
# Same hack as above.
108-
# TODO(#7844): Remove this hack.
109-
windows_config_setting: ":_magic_sentinel_runtime",
110-
"//conditions:default": ":_autodetecting_py3_runtime_nonstrict",
111-
}),
112-
visibility = ["//visibility:public"],
113-
)
114-
11565
native.toolchain(
11666
name = name,
11767
toolchain = ":_autodetecting_py_runtime_pair",
11868
toolchain_type = ":toolchain_type",
11969
visibility = ["//visibility:public"],
12070
)
121-
122-
native.toolchain(
123-
name = name + "_nonstrict",
124-
toolchain = ":_autodetecting_py_runtime_pair_nonstrict",
125-
toolchain_type = ":toolchain_type",
126-
visibility = ["//visibility:public"],
127-
)
+57Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/bin/sh
2+
3+
# Don't set -e because we don't have robust trapping and printing of errors.
4+
set -u
5+
6+
# We use /bin/sh rather than /bin/bash for portability. See discussion here:
7+
# https://groups.google.com/forum/?nomobile=true#!topic/bazel-dev/4Ql_7eDcLC0
8+
# We do lose the ability to set -o pipefail.
9+
10+
FAILURE_HEADER="\
11+
Error occurred while attempting to use the default Python toolchain \
12+
(@rules_python//python:autodetecting_toolchain)."
13+
14+
die() {
15+
echo "$FAILURE_HEADER" 1>&2
16+
echo "$1" 1>&2
17+
exit 1
18+
}
19+
20+
# We use `which` to locate the Python interpreter command on PATH. `command -v`
21+
# is another option, but it doesn't check whether the file it finds has the
22+
# executable bit.
23+
#
24+
# A tricky situation happens when this wrapper is invoked as part of running a
25+
# tool, e.g. passing a py_binary target to `ctx.actions.run()`. Bazel will unset
26+
# the PATH variable. Then the shell will see there's no PATH and initialize its
27+
# own, sometimes without exporting it. This causes `which` to fail and this
28+
# script to think there's no Python interpreter installed. To avoid this we
29+
# explicitly pass PATH to each `which` invocation. We can't just export PATH
30+
# because that would modify the environment seen by the final user Python
31+
# program.
32+
#
33+
# See also:
34+
#
35+
# https://github.com/bazelbuild/continuous-integration/issues/578
36+
# https://github.com/bazelbuild/bazel/issues/8414
37+
# https://github.com/bazelbuild/bazel/issues/8415
38+
39+
# Try the "python3" command name first, then fall back on "python".
40+
PYTHON_BIN="$(PATH="$PATH" which python3 2> /dev/null)"
41+
if [ -z "${PYTHON_BIN:-}" ]; then
42+
PYTHON_BIN="$(PATH="$PATH" which python 2>/dev/null)"
43+
fi
44+
if [ -z "${PYTHON_BIN:-}" ]; then
45+
die "Neither 'python3' nor 'python' were found on the target \
46+
platform's PATH, which is:
47+
48+
$PATH
49+
50+
Please ensure an interpreter is available on this platform (and marked \
51+
executable), or else register an appropriate Python toolchain as per the \
52+
documentation for py_runtime_pair \
53+
(https://github.com/bazelbuild/rules_python/blob/master/docs/python.md#py_runtime_pair)."
54+
fi
55+
56+
exec "$PYTHON_BIN" "$@"
57+
+27Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright 2023 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Implementation of py_runtime_pair macro portion."""
16+
17+
load(":py_runtime_pair_rule.bzl", _py_runtime_pair = "py_runtime_pair")
18+
19+
# A fronting macro is used because macros have user-observable behavior;
20+
# using one from the onset avoids introducing those changes in the future.
21+
def py_runtime_pair(**kwargs):
22+
"""Creates a py_runtime_pair target.
23+
24+
Args:
25+
**kwargs: Keyword args to pass onto underlying rule.
26+
"""
27+
_py_runtime_pair(**kwargs)

‎python/private/py_runtime_pair.bzl renamed to ‎python/private/py_runtime_pair_rule.bzl

Copy file name to clipboardExpand all lines: python/private/py_runtime_pair_rule.bzl
+3-5Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414

1515
"""Implementation of py_runtime_pair."""
1616

17-
# TODO: move py_runtime_pair into rules_python (and the rest of @bazel_tools//python)
18-
# py_runtime should be loaded from rules_python, but this creates a circular dep, because py_runtime_pair is imported there.
19-
py_runtime = native.py_runtime
17+
load("//python:py_runtime_info.bzl", "PyRuntimeInfo")
2018

2119
def _py_runtime_pair_impl(ctx):
2220
if ctx.attr.py2_runtime != None:
@@ -47,9 +45,9 @@ def _py_runtime_pair_impl(ctx):
4745

4846
# buildifier: disable=unused-variable
4947
def _is_py2_disabled(ctx):
50-
# In Google, this file isn't bundled with Bazel, so we have to conditionally
48+
# Because this file isn't bundled with Bazel, so we have to conditionally
5149
# check for this flag.
52-
# TODO: Remove this once a build with the flag is released in Google
50+
# TODO: Remove this once all supported Balze versions have this flag.
5351
if not hasattr(ctx.fragments.py, "disable_py"):
5452
return False
5553
return ctx.fragments.py.disable_py2

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.