-
Notifications
You must be signed in to change notification settings - Fork 548
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: use rules_python implemented py_runtime, py_runtime_pair, PyRuntimeInfo #1574
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,14 +13,15 @@ | |
# limitations under the License. | ||
"""Providers for Python rules.""" | ||
|
||
load("@rules_python_internal//:rules_python_config.bzl", "config") | ||
load("//python/private:util.bzl", "IS_BAZEL_6_OR_HIGHER") | ||
|
||
# TODO: load CcInfo from rules_cc | ||
_CcInfo = CcInfo | ||
|
||
DEFAULT_STUB_SHEBANG = "#!/usr/bin/env python3" | ||
|
||
DEFAULT_BOOTSTRAP_TEMPLATE = "@bazel_tools//tools/python:python_bootstrap_template.txt" | ||
DEFAULT_BOOTSTRAP_TEMPLATE = Label("//python/private:python_bootstrap_template.txt") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this mean we can have a custom template on bazel 6? I think that no, but I am not sure if this was just a fixup of previously broken code due to migration. |
||
|
||
_PYTHON_VERSION_VALUES = ["PY2", "PY3"] | ||
|
||
# Helper to make the provider definitions not crash under Bazel 5.4: | ||
|
@@ -31,7 +32,7 @@ _PYTHON_VERSION_VALUES = ["PY2", "PY3"] | |
# This isn't actually used under Bazel 5.4, so just stub out the values | ||
# to get past the loading phase. | ||
def _define_provider(doc, fields, **kwargs): | ||
if not config.enable_pystar: | ||
if not IS_BAZEL_6_OR_HIGHER: | ||
return provider("Stub, not used", fields = []), None | ||
return provider(doc = doc, fields = fields, **kwargs) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,15 +15,15 @@ | |
|
||
load("@bazel_skylib//lib:dicts.bzl", "dicts") | ||
load("@bazel_skylib//lib:paths.bzl", "paths") | ||
load("//python/private:reexports.bzl", "BuiltinPyRuntimeInfo") | ||
load("//python/private:util.bzl", "IS_BAZEL_7_OR_HIGHER") | ||
load(":attributes.bzl", "NATIVE_RULES_ALLOWLIST_ATTRS") | ||
load(":common.bzl", "check_native_allowed") | ||
load(":providers.bzl", "DEFAULT_BOOTSTRAP_TEMPLATE", "DEFAULT_STUB_SHEBANG", _PyRuntimeInfo = "PyRuntimeInfo") | ||
load(":providers.bzl", "DEFAULT_BOOTSTRAP_TEMPLATE", "DEFAULT_STUB_SHEBANG", "PyRuntimeInfo") | ||
load(":py_internal.bzl", "py_internal") | ||
|
||
_py_builtins = py_internal | ||
|
||
def _py_runtime_impl(ctx): | ||
check_native_allowed(ctx) | ||
interpreter_path = ctx.attr.interpreter_path or None # Convert empty string to None | ||
interpreter = ctx.file.interpreter | ||
if (interpreter_path and interpreter) or (not interpreter_path and not interpreter): | ||
|
@@ -44,7 +44,7 @@ def _py_runtime_impl(ctx): | |
if ctx.attr.coverage_tool: | ||
coverage_di = ctx.attr.coverage_tool[DefaultInfo] | ||
|
||
if _py_builtins.is_singleton_depset(coverage_di.files): | ||
if _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 | ||
|
@@ -60,39 +60,45 @@ def _py_runtime_impl(ctx): | |
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.py.default_python_version | ||
|
||
# TODO: Uncomment this after --incompatible_python_disable_py2 defaults to true | ||
# if ctx.fragments.py.disable_py2 and python_version == "PY2": | ||
# fail("Using Python 2 is not supported and disabled; see " + | ||
# "https://github.com/bazelbuild/bazel/issues/15684") | ||
|
||
py_runtime_info_kwargs = dict( | ||
interpreter_path = interpreter_path or None, | ||
interpreter = interpreter, | ||
files = runtime_files if hermetic else None, | ||
coverage_tool = coverage_tool, | ||
coverage_files = coverage_files, | ||
python_version = python_version, | ||
stub_shebang = ctx.attr.stub_shebang, | ||
bootstrap_template = ctx.file.bootstrap_template, | ||
) | ||
builtin_py_runtime_info_kwargs = dict(py_runtime_info_kwargs) | ||
if not IS_BAZEL_7_OR_HIGHER: | ||
builtin_py_runtime_info_kwargs.pop("bootstrap_template") | ||
return [ | ||
_PyRuntimeInfo( | ||
interpreter_path = interpreter_path or None, | ||
interpreter = interpreter, | ||
files = runtime_files if hermetic else None, | ||
coverage_tool = coverage_tool, | ||
coverage_files = coverage_files, | ||
python_version = python_version, | ||
stub_shebang = ctx.attr.stub_shebang, | ||
bootstrap_template = ctx.file.bootstrap_template, | ||
), | ||
PyRuntimeInfo(**py_runtime_info_kwargs), | ||
# Return the builtin provider for better compatibility. | ||
# 1. There is a legacy code path in py_binary that | ||
# checks for the provider when toolchains aren't used | ||
# 2. It makes it easier to transition from builtins to rules_python | ||
BuiltinPyRuntimeInfo(**builtin_py_runtime_info_kwargs), | ||
DefaultInfo( | ||
files = runtime_files, | ||
runfiles = ctx.runfiles(), | ||
), | ||
] | ||
|
||
def _is_singleton_depset(files): | ||
# Bazel 6 doesn't have this helper to optimize detecting singleton depsets. | ||
if _py_builtins: | ||
return _py_builtins.is_singleton_depset(files) | ||
else: | ||
return len(files.to_list()) == 1 | ||
|
||
# Bind to the name "py_runtime" to preserve the kind/rule_class it shows up | ||
# as elsewhere. | ||
py_runtime = rule( | ||
|
@@ -189,8 +195,8 @@ For a platform runtime, this is the absolute path of a Python interpreter on | |
the target platform. For an in-build runtime this attribute must not be set. | ||
"""), | ||
"python_version": attr.string( | ||
default = "_INTERNAL_SENTINEL", | ||
values = ["PY2", "PY3", "_INTERNAL_SENTINEL"], | ||
default = "PY3", | ||
values = ["PY2", "PY3"], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: I thought we are not supporting PY2? |
||
doc = """ | ||
Whether this runtime is for Python major version 2 or 3. Valid values are `"PY2"` | ||
and `"PY3"`. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit, what about using bazel_features package for this? I know that this adds an extra dep, but we are already using that on with bzlmod setups.