Skip to content

Commit

Permalink
refactor: toolchainize py_proto_library (bazelbuild#1577)
Browse files Browse the repository at this point in the history
Enables use of `--incompatible_enable_proto_toolchain_resolution` flag
that launched in Bazel 7. This allows users to choose a pre-built
`protoc` or use the runtime from https://pypi.org/project/protobuf/
rather than be forced to use hard-coded values in Bazel core.

This change is also happening in other language rulesets that provide
first-class protobuf support, e.g.
bazel-contrib/rules_go#3895

No update to CHANGELOG.md in this PR as the feature is not yet
documented for end-users, this just makes it possible to enable the
flag. A follow-up PR will provide user instructions.

---------

Co-authored-by: Alex Eagle <[email protected]>
  • Loading branch information
thesayyn and alexeagle authored Apr 11, 2024
1 parent 24a910d commit 4be00a6
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 26 deletions.
2 changes: 1 addition & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ bazel_dep(name = "bazel_skylib", version = "1.3.0")
bazel_dep(name = "platforms", version = "0.0.4")

# Those are loaded only when using py_proto_library
bazel_dep(name = "rules_proto", version = "5.3.0-21.7")
bazel_dep(name = "rules_proto", version = "6.0.0-rc1")
bazel_dep(name = "protobuf", version = "21.7", repo_name = "com_google_protobuf")

internal_deps = use_extension("//python/private/bzlmod:internal_deps.bzl", "internal_deps")
Expand Down
33 changes: 17 additions & 16 deletions examples/py_proto_library/WORKSPACE
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
workspace(name = "rules_python_py_proto_library_example")
# NB: short workspace name is required to workaround PATH length limitation, see
# https://github.com/bazelbuild/bazel/issues/18683#issuecomment-1843857373
workspace(name = "p")

# The following local_path_override is only needed to run this example as part of our CI.
local_repository(
Expand All @@ -24,25 +26,24 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "rules_proto",
sha256 = "dc3fb206a2cb3441b485eb1e423165b231235a1ea9b031b4433cf7bc1fa460dd",
strip_prefix = "rules_proto-5.3.0-21.7",
urls = [
"https://github.com/bazelbuild/rules_proto/archive/refs/tags/5.3.0-21.7.tar.gz",
],
)

http_archive(
name = "com_google_protobuf",
sha256 = "75be42bd736f4df6d702a0e4e4d30de9ee40eac024c4b845d17ae4cc831fe4ae",
strip_prefix = "protobuf-21.7",
urls = [
"https://mirror.bazel.build/github.com/protocolbuffers/protobuf/archive/v21.7.tar.gz",
"https://github.com/protocolbuffers/protobuf/archive/v21.7.tar.gz",
],
sha256 = "904a8097fae42a690c8e08d805210e40cccb069f5f9a0f6727cf4faa7bed2c9c",
strip_prefix = "rules_proto-6.0.0-rc1",
url = "https://github.com/bazelbuild/rules_proto/releases/download/6.0.0-rc1/rules_proto-6.0.0-rc1.tar.gz",
)

load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")

rules_proto_dependencies()

rules_proto_toolchains()

http_archive(
name = "com_google_protobuf",
sha256 = "4fc5ff1b2c339fb86cd3a25f0b5311478ab081e65ad258c6789359cd84d421f8",
strip_prefix = "protobuf-26.1",
urls = ["https://github.com/protocolbuffers/protobuf/archive/v26.1.tar.gz"],
)

load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")

protobuf_deps()
8 changes: 3 additions & 5 deletions internal_deps.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,9 @@ def rules_python_internal_deps():

http_archive(
name = "rules_proto",
sha256 = "dc3fb206a2cb3441b485eb1e423165b231235a1ea9b031b4433cf7bc1fa460dd",
strip_prefix = "rules_proto-5.3.0-21.7",
urls = [
"https://github.com/bazelbuild/rules_proto/archive/refs/tags/5.3.0-21.7.tar.gz",
],
sha256 = "904a8097fae42a690c8e08d805210e40cccb069f5f9a0f6727cf4faa7bed2c9c",
strip_prefix = "rules_proto-6.0.0-rc1",
url = "https://github.com/bazelbuild/rules_proto/releases/download/6.0.0-rc1/rules_proto-6.0.0-rc1.tar.gz",
)

http_archive(
Expand Down
18 changes: 14 additions & 4 deletions python/private/proto/py_proto_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
load("@rules_proto//proto:defs.bzl", "ProtoInfo", "proto_common")
load("//python:defs.bzl", "PyInfo")

ProtoLangToolchainInfo = proto_common.ProtoLangToolchainInfo
PY_PROTO_TOOLCHAIN = "@rules_python//python/proto:toolchain_type"

_PyProtoInfo = provider(
doc = "Encapsulates information needed by the Python proto rules.",
Expand All @@ -35,6 +35,9 @@ _PyProtoInfo = provider(
def _filter_provider(provider, *attrs):
return [dep[provider] for attr in attrs for dep in attr if provider in dep]

def _incompatible_toolchains_enabled():
return getattr(proto_common, "INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION", False)

def _py_proto_aspect_impl(target, ctx):
"""Generates and compiles Python code for a proto_library.
Expand All @@ -51,7 +54,6 @@ def _py_proto_aspect_impl(target, ctx):
([_PyProtoInfo]) Providers collecting transitive information about
generated files.
"""

_proto_library = ctx.rule.attr

# Check Proto file names
Expand All @@ -61,7 +63,14 @@ def _py_proto_aspect_impl(target, ctx):
proto.path,
))

proto_lang_toolchain_info = ctx.attr._aspect_proto_toolchain[ProtoLangToolchainInfo]
if _incompatible_toolchains_enabled():
toolchain = ctx.toolchains[PY_PROTO_TOOLCHAIN]
if not toolchain:
fail("No toolchains registered for '%s'." % PY_PROTO_TOOLCHAIN)
proto_lang_toolchain_info = toolchain.proto
else:
proto_lang_toolchain_info = getattr(ctx.attr, "_aspect_proto_toolchain")[proto_common.ProtoLangToolchainInfo]

api_deps = [proto_lang_toolchain_info.runtime]

generated_sources = []
Expand Down Expand Up @@ -123,14 +132,15 @@ def _py_proto_aspect_impl(target, ctx):

_py_proto_aspect = aspect(
implementation = _py_proto_aspect_impl,
attrs = {
attrs = {} if _incompatible_toolchains_enabled() else {
"_aspect_proto_toolchain": attr.label(
default = ":python_toolchain",
),
},
attr_aspects = ["deps"],
required_providers = [ProtoInfo],
provides = [_PyProtoInfo],
toolchains = [PY_PROTO_TOOLCHAIN] if _incompatible_toolchains_enabled() else [],
)

def _py_proto_library_rule(ctx):
Expand Down

0 comments on commit 4be00a6

Please sign in to comment.