Skip to content

Commit 49fe23a

Browse files
committed
Switch back from grpc_python to self-written py_proto_library
The upstream patch to grpc-python adds the pyi files to the srcs field of the py_library. This is incorrect and results in errors during type checking (library found twice). Add and use grpc-python-inspired rules that add the pyi files to the correct field. CMK-20994 Change-Id: I6c4e9ce4c6598e7aadcfec8a9a6181cd5b3c507b
1 parent 0ae2fb7 commit 49fe23a

8 files changed

+1449
-1919
lines changed

MODULE.bazel

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ bazel_dep(name = "rules_cc", version = "0.0.17")
2424
bazel_dep(name = "rules_multitool", version = "0.4.0")
2525
bazel_dep(name = "rules_rust", version = "0.49.3")
2626
bazel_dep(name = "rules_python", version = "1.1.0")
27+
single_version_override(
28+
module_name = "rules_python",
29+
patch_strip = 1,
30+
patches = [
31+
"//bazel/patches:rules_python-py_wheel-package_pyi_files.patch",
32+
"//bazel/patches:rules_python-py_wheel-filter_out_virtual_imports.patch",
33+
],
34+
)
2735
bazel_dep(name = "rules_uv", version = "0.44.0")
2836
single_version_override(
2937
module_name = "rules_uv",
@@ -102,19 +110,6 @@ bazel_dep(
102110
version = "0.3.7",
103111
)
104112
bazel_dep(name = "rules_proto_grpc", version = "5.0.1")
105-
bazel_dep(name = "rules_proto_grpc_python", version = "5.0.1")
106-
single_version_override(
107-
module_name = "rules_proto_grpc_python",
108-
patch_strip = 3,
109-
patches = [
110-
# https://github.com/rules-proto-grpc/rules_proto_grpc/commit/155b8fe1028d9284670ff9fa0cb9168c72faf6e6
111-
"//bazel/patches:rules_proto_grpc_python-generate_pyi.patch",
112-
# Provide our own `requirement("protobuf")` dependency to avoid
113-
# package collisions.
114-
# See also: https://github.com/rules-proto-grpc/rules_proto_grpc/issues/394
115-
"//bazel/patches:rules_proto_grpc_python-no_protobuf_dep.patch",
116-
],
117-
)
118113

119114
fork_cc_toolchain_config = use_repo_rule("//bazel/toolchains/cc:fork_cc_toolchain_config.bzl", "fork_cc_toolchain_config")
120115

MODULE.bazel.lock

Lines changed: 1315 additions & 1831 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bazel/patches/rules_proto_grpc_python-generate_pyi.patch

Lines changed: 0 additions & 54 deletions
This file was deleted.

bazel/patches/rules_proto_grpc_python-no_protobuf_dep.patch

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
commit 136a8d919256542107d90053a388263f7ac41860
2+
Author: Mathias Laurin <[email protected]>
3+
Date: Thu Feb 6 12:19:55 2025 +0100
4+
5+
Do not package _virtual_imports
6+
7+
diff --git a/python/private/py_wheel.bzl b/python/private/py_wheel.bzl
8+
index c196ca6a..1b534f84 100644
9+
--- a/python/private/py_wheel.bzl
10+
+++ b/python/private/py_wheel.bzl
11+
@@ -325,8 +325,10 @@ def _py_wheel_impl(ctx):
12+
if PyInfo in dep:
13+
direct_pyi_files.extend(dep[PyInfo].direct_pyi_files.to_list())
14+
15+
+ direct_files = [dep for dep in ctx.files.deps if "/_virtual_imports/" not in dep.short_path]
16+
+
17+
inputs_to_package = depset(
18+
- direct = ctx.files.deps + direct_pyi_files,
19+
+ direct = direct_files + direct_pyi_files,
20+
)
21+
22+
# Inputs to this rule which are not to be packaged.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
commit 0d432d7455edc3ff00404403de59ecfd20936c92
2+
Author: Mathias Laurin <[email protected]>
3+
Date: Thu Feb 6 11:26:29 2025 +0100
4+
5+
Package pyi files in wheel
6+
7+
diff --git a/python/private/py_wheel.bzl b/python/private/py_wheel.bzl
8+
index b5fbec9c..c196ca6a 100644
9+
--- a/python/private/py_wheel.bzl
10+
+++ b/python/private/py_wheel.bzl
11+
@@ -14,6 +14,7 @@
12+
13+
"Implementation of py_wheel rule"
14+
15+
+load(":py_info.bzl", "PyInfo")
16+
load(":py_package.bzl", "py_package_lib")
17+
load(":py_wheel_normalize_pep440.bzl", "normalize_pep440")
18+
load(":stamp.bzl", "is_stamping_enabled")
19+
@@ -319,8 +320,13 @@ def _py_wheel_impl(ctx):
20+
21+
name_file = ctx.actions.declare_file(ctx.label.name + ".name")
22+
23+
+ direct_pyi_files = []
24+
+ for dep in ctx.attr.deps:
25+
+ if PyInfo in dep:
26+
+ direct_pyi_files.extend(dep[PyInfo].direct_pyi_files.to_list())
27+
+
28+
inputs_to_package = depset(
29+
- direct = ctx.files.deps,
30+
+ direct = ctx.files.deps + direct_pyi_files,
31+
)
32+
33+
# Inputs to this rule which are not to be packaged.

bazel/rules/private/proto/BUILD

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
load("@cmk_requirements//:requirements.bzl", "requirement")
2+
load("@rules_proto_grpc//:defs.bzl", "proto_plugin")
3+
load("@rules_python//python/entry_points:py_console_script_binary.bzl", "py_console_script_binary")
4+
5+
py_console_script_binary(
6+
name = "protoc-gen-mypy",
7+
pkg = requirement("mypy-protobuf"),
8+
script = "protoc-gen-mypy",
9+
)
10+
11+
proto_plugin(
12+
name = "pyi_plugin",
13+
exclusions = ["google/protobuf"],
14+
outputs = ["{protopath|python}_pb2.pyi"],
15+
# protoc_plugin_name = "pyi",
16+
tool = ":protoc-gen-mypy",
17+
visibility = ["//visibility:public"],
18+
)

bazel/rules/proto.bzl

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
load(
2+
"@rules_proto_grpc//:defs.bzl",
3+
"ProtoPluginInfo",
4+
"proto_compile_attrs",
5+
"proto_compile_impl",
6+
"proto_compile_toolchains",
7+
)
8+
load("@rules_python//python:defs.bzl", _py_library = "py_library")
9+
load("@rules_python//python:proto.bzl", _py_proto_library = "py_proto_library")
10+
11+
py_proto_compile = rule(
12+
implementation = proto_compile_impl,
13+
attrs = dict(
14+
proto_compile_attrs,
15+
_plugins = attr.label_list(
16+
providers = [ProtoPluginInfo],
17+
default = [Label("//bazel/rules/private/proto:pyi_plugin")],
18+
cfg = "exec",
19+
doc = "List of protoc plugins to apply",
20+
),
21+
),
22+
toolchains = proto_compile_toolchains,
23+
)
24+
25+
def py_proto_library(name, protos, output_mode = None, **kwargs):
26+
"""py_proto_library generates Python code from proto and creates a py_library for them.
27+
28+
Args:
29+
name: the name of the target.
30+
protos: the proto files.
31+
output_mode: "PREFIX" or "NO_PREFIX".
32+
**kwargs: arguments forwarded to the py_library.
33+
"""
34+
name_pb = name + "_pb"
35+
_py_proto_library(
36+
name = name_pb,
37+
deps = protos,
38+
)
39+
40+
name_pyi = name + "_pyi"
41+
py_proto_compile(
42+
name = name_pyi,
43+
output_mode = output_mode,
44+
protos = protos,
45+
)
46+
47+
_py_library(
48+
name = name,
49+
srcs = [name_pb],
50+
pyi_srcs = [name_pyi],
51+
imports = ["."],
52+
**kwargs
53+
)

0 commit comments

Comments
 (0)