Skip to content

Commit 5946109

Browse files
committed
fix(transitions): correctly default 'main' arg for transition rules
Before the change the version-aware py_binary and py_test rules would not default the 'main' argument correctly and this change adds unit tests and a helper function to do the defaulting. Work towards #1262
1 parent a547d34 commit 5946109

File tree

7 files changed

+156
-9
lines changed

7 files changed

+156
-9
lines changed

examples/multi_python_versions/tests/BUILD.bazel

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
1+
load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
12
load("@python//3.10:defs.bzl", py_binary_3_10 = "py_binary", py_test_3_10 = "py_test")
23
load("@python//3.11:defs.bzl", py_binary_3_11 = "py_binary", py_test_3_11 = "py_test")
34
load("@python//3.8:defs.bzl", py_binary_3_8 = "py_binary", py_test_3_8 = "py_test")
45
load("@python//3.9:defs.bzl", py_binary_3_9 = "py_binary", py_test_3_9 = "py_test")
56
load("@rules_python//python:defs.bzl", "py_binary", "py_test")
67

8+
copy_file(
9+
name = "copy_version",
10+
src = "version.py",
11+
out = "version_default.py",
12+
is_executable = True,
13+
)
14+
15+
# NOTE: We are testing that the `main` is an optional param as per official
16+
# docs https://bazel.build/reference/be/python#py_binary.main
717
py_binary(
818
name = "version_default",
9-
srcs = ["version.py"],
10-
main = "version.py",
19+
srcs = ["version_default.py"],
1120
)
1221

1322
py_binary_3_8(
@@ -69,11 +78,17 @@ py_test_3_11(
6978
deps = ["//libs/my_lib"],
7079
)
7180

81+
copy_file(
82+
name = "copy_version_test",
83+
src = "version_test.py",
84+
out = "version_default_test.py",
85+
is_executable = True,
86+
)
87+
7288
py_test(
7389
name = "version_default_test",
74-
srcs = ["version_test.py"],
90+
srcs = ["version_default_test.py"],
7591
env = {"VERSION_CHECK": "3.9"}, # The default defined in the WORKSPACE.
76-
main = "version_test.py",
7792
)
7893

7994
py_test_3_8(

python/config_settings/private/BUILD.bazel

Whitespace-only changes.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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+
"A helper to extract default args for the transition rule"
16+
17+
def py_args(name, kwargs):
18+
"""A helper to extract common py_binary and py_test args
19+
20+
See https://bazel.build/reference/be/python#py_binary and
21+
https://bazel.build/reference/be/python#py_test for the list
22+
that should be returned
23+
24+
Args:
25+
name: The name of the target.
26+
kwargs: The kwargs to be extracted from.
27+
28+
Returns:
29+
A dict with the extracted arguments
30+
"""
31+
return dict(
32+
args = kwargs.pop("args", None),
33+
data = kwargs.pop("data", None),
34+
env = kwargs.pop("env", None),
35+
srcs = kwargs.pop("srcs", None),
36+
deps = kwargs.pop("deps", None),
37+
# See https://bazel.build/reference/be/python#py_binary.main
38+
# for default logic.
39+
main = kwargs.pop("main", name),
40+
)

python/config_settings/transition.bzl

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ them to the desired target platform.
1818

1919
load("@bazel_skylib//lib:dicts.bzl", "dicts")
2020
load("//python:defs.bzl", _py_binary = "py_binary", _py_test = "py_test")
21+
load("//python/config_settings/private:py_args.bzl", "py_args")
2122

2223
def _transition_python_version_impl(_, attr):
2324
return {"//python/config_settings:python_version": str(attr.python_version)}
@@ -138,11 +139,13 @@ _transition_py_test = rule(
138139
)
139140

140141
def _py_rule(rule_impl, transition_rule, name, python_version, **kwargs):
141-
args = kwargs.pop("args", None)
142-
data = kwargs.pop("data", None)
143-
env = kwargs.pop("env", None)
144-
srcs = kwargs.pop("srcs", None)
145-
deps = kwargs.pop("deps", None)
142+
pyargs = py_args(name, kwargs)
143+
args = pyargs["args"]
144+
data = pyargs["data"]
145+
env = pyargs["env"]
146+
srcs = pyargs["srcs"]
147+
deps = pyargs["deps"]
148+
main = pyargs["main"]
146149

147150
# Attributes common to all build rules.
148151
# https://bazel.build/reference/be/common-definitions#common-attributes
@@ -197,6 +200,7 @@ def _py_rule(rule_impl, transition_rule, name, python_version, **kwargs):
197200
deps = deps,
198201
env = env,
199202
srcs = srcs,
203+
main = main,
200204
tags = ["manual"] + (tags if tags else []),
201205
visibility = ["//visibility:private"],
202206
**dicts.add(common_attrs, kwargs)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Defs required for entry_point transitions, for PRIVATE USE ONLY.
2+
3+
@generated by rules_python pip.parse extension.
4+
5+
We use this method as opposed handling it in whl_library definition
6+
because not everybody is using version-aware toolchains and doing that
7+
in whl_library may lead to a lot of code otherwise.
8+
"""
9+
10+
load("@@%%RULES_PYTHON%%//python/config_settings:transition.bzl", _py_binary = "py_binary")
11+
12+
def py_binary(name, **kwargs):
13+
_py_binary(
14+
name = name,
15+
python_version = "%%FULL_VERSION%%",
16+
**kwargs,
17+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
load(":py_args_tests.bzl", "py_args_test_suite")
2+
3+
py_args_test_suite(name = "py_args_tests")
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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+
""
16+
17+
load("@rules_testing//lib:test_suite.bzl", "test_suite")
18+
load("//python/config_settings/private:py_args.bzl", "py_args") # buildifier: disable=bzl-visibility
19+
20+
_tests = []
21+
22+
def _test_py_args_default(env):
23+
actual = py_args("foo", {})
24+
25+
want = {
26+
"args": None,
27+
"data": None,
28+
"deps": None,
29+
"env": None,
30+
"main": "foo",
31+
"srcs": None,
32+
}
33+
env.expect.that_dict(actual).contains_exactly(want)
34+
35+
_tests.append(_test_py_args_default)
36+
37+
def _test_kwargs_get_consumed(env):
38+
kwargs = {
39+
"args": ["some", "args"],
40+
"data": ["data"],
41+
"deps": ["deps"],
42+
"env": {"key": "value"},
43+
"main": "__main__.py",
44+
"srcs": ["__main__.py"],
45+
"visibility": ["//visibility:public"],
46+
}
47+
actual = py_args("bar_bin", kwargs)
48+
49+
want = {
50+
"args": ["some", "args"],
51+
"data": ["data"],
52+
"deps": ["deps"],
53+
"env": {"key": "value"},
54+
"main": "__main__.py",
55+
"srcs": ["__main__.py"],
56+
}
57+
env.expect.that_dict(actual).contains_exactly(want)
58+
env.expect.that_dict(kwargs).keys().contains_exactly(["visibility"])
59+
60+
_tests.append(_test_kwargs_get_consumed)
61+
62+
def py_args_test_suite(name):
63+
"""Create the test suite.
64+
65+
Args:
66+
name: the name of the test suite
67+
"""
68+
test_suite(name = name, basic_tests = _tests)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy