Skip to content

Commit

Permalink
fix: Propagate testonly et al for wheel .dist targets (#1064)
Browse files Browse the repository at this point in the history
* Propagate testonly et al for wheel `.dist` targets

The `.dist` target depends on the wheel, so it must copy the
`testonly` setting as well as some others.

* Also adds a utility function to do this, since the multi-version
  rules also do this copying.

Fixes #1057

* fixup! Allow building with unreleased Bazel versions. (#1063)
  • Loading branch information
rickeylev authored Feb 16, 2023
1 parent 767b050 commit 2893d85
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ bzl_library(
"//python/private:py_package.bzl",
"//python/private:py_wheel.bzl",
"//python/private:stamp.bzl",
"//python/private:util.bzl",
],
)

Expand Down
7 changes: 7 additions & 0 deletions examples/wheel/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

load("@bazel_skylib//rules:build_test.bzl", "build_test")
load("//examples/wheel/private:wheel_utils.bzl", "directory_writer")
load("//python:defs.bzl", "py_library", "py_test")
load("//python:packaging.bzl", "py_package", "py_wheel")
Expand Down Expand Up @@ -50,6 +51,7 @@ directory_writer(
# Package just a specific py_libraries, without their dependencies
py_wheel(
name = "minimal_with_py_library",
testonly = True, # Set this to verify the generated .dist target doesn't break things
# Package data. We're building "example_minimal_library-0.0.1-py3-none-any.whl"
distribution = "example_minimal_library",
python_tag = "py3",
Expand All @@ -60,6 +62,11 @@ py_wheel(
],
)

build_test(
name = "dist_build_tests",
targets = [":minimal_with_py_library.dist"],
)

# Package just a specific py_libraries, without their dependencies
py_wheel(
name = "minimal_with_py_library_with_stamp",
Expand Down
2 changes: 2 additions & 0 deletions python/packaging.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

load("//python/private:py_package.bzl", "py_package_lib")
load("//python/private:py_wheel.bzl", _PyWheelInfo = "PyWheelInfo", _py_wheel = "py_wheel")
load("//python/private:util.bzl", "copy_propagating_kwargs")

# Re-export as public API
PyWheelInfo = _PyWheelInfo
Expand Down Expand Up @@ -148,6 +149,7 @@ def py_wheel(name, twine = None, **kwargs):
name = _dist_target,
wheel = name,
out = kwargs.pop("dist_folder", "{}_dist".format(name)),
**copy_propagating_kwargs(kwargs)
)

_py_wheel(name = name, **kwargs)
Expand Down
1 change: 1 addition & 0 deletions python/private/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ exports_files(
"py_wheel.bzl",
"reexports.bzl",
"stamp.bzl",
"util.bzl",
],
visibility = ["//docs:__pkg__"],
)
Expand Down
31 changes: 31 additions & 0 deletions python/private/util.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""Functionality shared by multiple pieces of code."""

def copy_propagating_kwargs(from_kwargs, into_kwargs = None):
"""Copies args that must be compatible between two targets with a dependency relationship.
This is intended for when one target depends on another, so they must have
compatible settings such as `testonly` and `compatible_with`. This usually
happens when a macro generates multiple targets, some of which depend
on one another, so their settings must be compatible.
Args:
from_kwargs: keyword args dict whose common kwarg will be copied.
into_kwargs: optional keyword args dict that the values from `from_kwargs`
will be copied into. The values in this dict will take precedence
over the ones in `from_kwargs` (i.e., if this has `testonly` already
set, then it won't be overwritten).
NOTE: THIS WILL BE MODIFIED IN-PLACE.
Returns:
Keyword args to use for the depender target derived from the dependency
target. If `into_kwargs` was passed in, then that same object is
returned; this is to facilitate easy `**` expansion.
"""
if into_kwargs == None:
into_kwargs = {}

# Include tags because people generally expect tags to propagate.
for attr in ("testonly", "tags", "compatible_with", "restricted_to"):
if attr in from_kwargs and attr not in into_kwargs:
into_kwargs[attr] = from_kwargs[attr]
return into_kwargs

0 comments on commit 2893d85

Please sign in to comment.