Skip to content

Commit e3e56c7

Browse files
dwscopybara-github
authored andcommitted
Generate .pyi files in py_proto_library (#10366) (#21567)
We here adjust py_proto_library to produce `.pyi` files along with the `.py` files it already generates. This achieves the same effect as the gRPC py_proto_library. Per reviewer feedback, we here propagate the paths to the `.pyi` files via the `direct_pyi_files` and `transitive_pyi_files` members of `PyInfo` which are available starting in `rules_python` 1.1.0. Since this means that the files are not automatically in the runfiles of the `py_proto_library`, tooling to run mypy will need to be adjusted to add what is needed from these provider fields to the runfiles if that is what is wanted. Closes#10366. Closes#21567 COPYBARA_INTEGRATE_REVIEW=#21567 from dws:py_proto_library-pyi 37fbdc0 PiperOrigin-RevId: 778116905
1 parent ae0129f commit e3e56c7

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

‎bazel/py_proto_library.bzl‎

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ _PyProtoInfo = provider(
1717
(depset[File]) Files from the transitive closure implicit proto
1818
dependencies""",
1919
"transitive_sources": """(depset[File]) The Python sources.""",
20+
"direct_pyi_files": """
21+
(depset[File]) Type definition files (usually `.pyi` files)
22+
for the Python modules provided by this target.""",
23+
"transitive_pyi_files": """
24+
(depset[File]) The transitive set of type definition files
25+
(usually `.pyi` files) for the Python modules for this target
26+
and its transitive dependencies.""",
2027
},
2128
)
2229

@@ -61,6 +68,7 @@ def _py_proto_aspect_impl(target, ctx):
6168
api_deps= [proto_lang_toolchain_info.runtime]
6269

6370
generated_sources= []
71+
generated_stubs= []
6472
proto_info=target[ProtoInfo]
6573
proto_root=proto_info.proto_source_root
6674
ifproto_info.direct_sources:
@@ -72,6 +80,14 @@ def _py_proto_aspect_impl(target, ctx):
7280
name_mapper=lambdaname: name.replace("-", "_").replace(".", "/"),
7381
)
7482

83+
# Generate pyi files
84+
generated_stubs=proto_common.declare_generated_files(
85+
actions=ctx.actions,
86+
proto_info=proto_info,
87+
extension="_pb2.pyi",
88+
name_mapper=lambdaname: name.replace("-", "_").replace(".", "/"),
89+
)
90+
7591
# Handles multiple repository and virtual import cases
7692
ifproto_root.startswith(ctx.bin_dir.path):
7793
proto_root=proto_root[len(ctx.bin_dir.path) +1:]
@@ -84,12 +100,17 @@ def _py_proto_aspect_impl(target, ctx):
84100
else:
85101
proto_root=ctx.workspace_name+"/"+proto_root
86102

103+
additional_args=ctx.actions.args()
104+
ifgenerated_stubs:
105+
additional_args.add(plugin_output, format="--pyi_out=%s")
106+
87107
proto_common.compile(
88108
actions=ctx.actions,
89109
proto_info=proto_info,
90110
proto_lang_toolchain_info=proto_lang_toolchain_info,
91-
generated_files=generated_sources,
111+
generated_files=generated_sources+generated_stubs,
92112
plugin_output=plugin_output,
113+
additional_args=additional_args,
93114
)
94115

95116
# Generated sources == Python sources
@@ -104,6 +125,13 @@ def _py_proto_aspect_impl(target, ctx):
104125
direct=python_sources,
105126
transitive= [dep.transitive_sourcesfordepindeps],
106127
)
128+
direct_pyi_files=depset(
129+
direct=generated_stubs,
130+
)
131+
transitive_pyi_files=depset(
132+
direct=generated_stubs,
133+
transitive= [dep.transitive_pyi_filesfordepindeps],
134+
)
107135

108136
return [
109137
_PyProtoInfo(
@@ -119,6 +147,8 @@ def _py_proto_aspect_impl(target, ctx):
119147
),
120148
runfiles_from_proto_deps=runfiles_from_proto_deps,
121149
transitive_sources=transitive_sources,
150+
direct_pyi_files=direct_pyi_files,
151+
transitive_pyi_files=transitive_pyi_files,
122152
),
123153
]
124154

@@ -150,6 +180,13 @@ def _py_proto_library_rule(ctx):
150180
default_outputs=depset(
151181
transitive= [info.transitive_sourcesforinfoinpyproto_infos],
152182
)
183+
direct_pyi_files= []
184+
forinfoinpyproto_infos:
185+
direct_pyi_files.extend(info.direct_pyi_files.to_list())
186+
transitive_pyi_files=depset(
187+
direct=direct_pyi_files,
188+
transitive= [info.transitive_pyi_filesforinfoinpyproto_infos],
189+
)
153190

154191
return [
155192
DefaultInfo(
@@ -166,6 +203,8 @@ def _py_proto_library_rule(ctx):
166203
PyInfo(
167204
transitive_sources=default_outputs,
168205
imports=depset(transitive= [info.importsforinfoinpyproto_infos]),
206+
direct_pyi_files=depset(direct=direct_pyi_files),
207+
transitive_pyi_files=transitive_pyi_files,
169208
# Proto always produces 2- and 3- compatible source files
170209
has_py2_only_sources=False,
171210
has_py3_only_sources=False,

0 commit comments

Comments
(0)