Skip to content

Commit 4be00a6

Browse files
thesayynalexeagle
andauthored
refactor: toolchainize py_proto_library (bazel-contrib#1577)
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]>
1 parent 24a910d commit 4be00a6

File tree

4 files changed

+35
-26
lines changed

4 files changed

+35
-26
lines changed

MODULE.bazel

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ bazel_dep(name = "bazel_skylib", version = "1.3.0")
99
bazel_dep(name = "platforms", version = "0.0.4")
1010

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

1515
internal_deps = use_extension("//python/private/bzlmod:internal_deps.bzl", "internal_deps")

examples/py_proto_library/WORKSPACE

+17-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
workspace(name = "rules_python_py_proto_library_example")
1+
# NB: short workspace name is required to workaround PATH length limitation, see
2+
# https://github.com/bazelbuild/bazel/issues/18683#issuecomment-1843857373
3+
workspace(name = "p")
24

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

2527
http_archive(
2628
name = "rules_proto",
27-
sha256 = "dc3fb206a2cb3441b485eb1e423165b231235a1ea9b031b4433cf7bc1fa460dd",
28-
strip_prefix = "rules_proto-5.3.0-21.7",
29-
urls = [
30-
"https://github.com/bazelbuild/rules_proto/archive/refs/tags/5.3.0-21.7.tar.gz",
31-
],
32-
)
33-
34-
http_archive(
35-
name = "com_google_protobuf",
36-
sha256 = "75be42bd736f4df6d702a0e4e4d30de9ee40eac024c4b845d17ae4cc831fe4ae",
37-
strip_prefix = "protobuf-21.7",
38-
urls = [
39-
"https://mirror.bazel.build/github.com/protocolbuffers/protobuf/archive/v21.7.tar.gz",
40-
"https://github.com/protocolbuffers/protobuf/archive/v21.7.tar.gz",
41-
],
29+
sha256 = "904a8097fae42a690c8e08d805210e40cccb069f5f9a0f6727cf4faa7bed2c9c",
30+
strip_prefix = "rules_proto-6.0.0-rc1",
31+
url = "https://github.com/bazelbuild/rules_proto/releases/download/6.0.0-rc1/rules_proto-6.0.0-rc1.tar.gz",
4232
)
4333

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

4636
rules_proto_dependencies()
4737

4838
rules_proto_toolchains()
39+
40+
http_archive(
41+
name = "com_google_protobuf",
42+
sha256 = "4fc5ff1b2c339fb86cd3a25f0b5311478ab081e65ad258c6789359cd84d421f8",
43+
strip_prefix = "protobuf-26.1",
44+
urls = ["https://github.com/protocolbuffers/protobuf/archive/v26.1.tar.gz"],
45+
)
46+
47+
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
48+
49+
protobuf_deps()

internal_deps.bzl

+3-5
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,9 @@ def rules_python_internal_deps():
166166

167167
http_archive(
168168
name = "rules_proto",
169-
sha256 = "dc3fb206a2cb3441b485eb1e423165b231235a1ea9b031b4433cf7bc1fa460dd",
170-
strip_prefix = "rules_proto-5.3.0-21.7",
171-
urls = [
172-
"https://github.com/bazelbuild/rules_proto/archive/refs/tags/5.3.0-21.7.tar.gz",
173-
],
169+
sha256 = "904a8097fae42a690c8e08d805210e40cccb069f5f9a0f6727cf4faa7bed2c9c",
170+
strip_prefix = "rules_proto-6.0.0-rc1",
171+
url = "https://github.com/bazelbuild/rules_proto/releases/download/6.0.0-rc1/rules_proto-6.0.0-rc1.tar.gz",
174172
)
175173

176174
http_archive(

python/private/proto/py_proto_library.bzl

+14-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
load("@rules_proto//proto:defs.bzl", "ProtoInfo", "proto_common")
1818
load("//python:defs.bzl", "PyInfo")
1919

20-
ProtoLangToolchainInfo = proto_common.ProtoLangToolchainInfo
20+
PY_PROTO_TOOLCHAIN = "@rules_python//python/proto:toolchain_type"
2121

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

38+
def _incompatible_toolchains_enabled():
39+
return getattr(proto_common, "INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION", False)
40+
3841
def _py_proto_aspect_impl(target, ctx):
3942
"""Generates and compiles Python code for a proto_library.
4043
@@ -51,7 +54,6 @@ def _py_proto_aspect_impl(target, ctx):
5154
([_PyProtoInfo]) Providers collecting transitive information about
5255
generated files.
5356
"""
54-
5557
_proto_library = ctx.rule.attr
5658

5759
# Check Proto file names
@@ -61,7 +63,14 @@ def _py_proto_aspect_impl(target, ctx):
6163
proto.path,
6264
))
6365

64-
proto_lang_toolchain_info = ctx.attr._aspect_proto_toolchain[ProtoLangToolchainInfo]
66+
if _incompatible_toolchains_enabled():
67+
toolchain = ctx.toolchains[PY_PROTO_TOOLCHAIN]
68+
if not toolchain:
69+
fail("No toolchains registered for '%s'." % PY_PROTO_TOOLCHAIN)
70+
proto_lang_toolchain_info = toolchain.proto
71+
else:
72+
proto_lang_toolchain_info = getattr(ctx.attr, "_aspect_proto_toolchain")[proto_common.ProtoLangToolchainInfo]
73+
6574
api_deps = [proto_lang_toolchain_info.runtime]
6675

6776
generated_sources = []
@@ -123,14 +132,15 @@ def _py_proto_aspect_impl(target, ctx):
123132

124133
_py_proto_aspect = aspect(
125134
implementation = _py_proto_aspect_impl,
126-
attrs = {
135+
attrs = {} if _incompatible_toolchains_enabled() else {
127136
"_aspect_proto_toolchain": attr.label(
128137
default = ":python_toolchain",
129138
),
130139
},
131140
attr_aspects = ["deps"],
132141
required_providers = [ProtoInfo],
133142
provides = [_PyProtoInfo],
143+
toolchains = [PY_PROTO_TOOLCHAIN] if _incompatible_toolchains_enabled() else [],
134144
)
135145

136146
def _py_proto_library_rule(ctx):

0 commit comments

Comments
 (0)