Skip to content

Commit bee35ef

Browse files
linzhpaignas
andauthored
fix: allowing to import code generated from proto with strip_import_prefix (#1406)
When the `proto_library` has `strip_import_prefix`, the py files from proto are generated into a directory like `bazel-bin/tests/py_proto_library/proto/_virtual_imports` and symlinked in the runfiles as `<runfilesroot>/<workspace name>/tests/py_proto_library/proto/_virtual_imports`. We need to add `<workspace name>/tests/py_proto_library/proto/_virtual_imports` to the `imports` of `_PyProtoInfo`, so it will be appended to `PYTHONPATH`. Modified an existing example to demonstrate the scenario and verify the fix. --------- Co-authored-by: Ignas Anikevicius <[email protected]>
1 parent 669e81e commit bee35ef

File tree

7 files changed

+28
-22
lines changed

7 files changed

+28
-22
lines changed

.bazelrc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
# This lets us glob() up all the files inside the examples to make them inputs to tests
44
# (Note, we cannot use `common --deleted_packages` because the bazel version command doesn't support it)
55
# To update these lines, run tools/bazel_integration_test/update_deleted_packages.sh
6-
build --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,tests/compile_pip_requirements,tests/compile_pip_requirements_test_from_external_workspace,tests/ignore_root_user_error,tests/pip_repository_entry_points
7-
query --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,tests/compile_pip_requirements,tests/compile_pip_requirements_test_from_external_workspace,tests/ignore_root_user_error,tests/pip_repository_entry_points
6+
build --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/proto,tests/compile_pip_requirements,tests/compile_pip_requirements_test_from_external_workspace,tests/ignore_root_user_error,tests/pip_repository_entry_points
7+
query --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/proto,tests/compile_pip_requirements,tests/compile_pip_requirements_test_from_external_workspace,tests/ignore_root_user_error,tests/pip_repository_entry_points
88

99
test --test_output=errors
1010

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ A brief description of the categories of changes:
2424
* Skip aliases for unloaded toolchains. Some Python versions that don't have full
2525
platform support, and referencing their undefined repositories can break operations
2626
like `bazel query rdeps(...)`.
27+
* Python code generated from `proto_library` with `strip_import_prefix` can be imported now.
2728

2829
## [0.26.0] - 2023-10-06
2930

examples/py_proto_library/BUILD.bazel

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,10 @@
1-
load("@rules_proto//proto:defs.bzl", "proto_library")
21
load("@rules_python//python:defs.bzl", "py_test")
3-
load("@rules_python//python:proto.bzl", "py_proto_library")
4-
5-
py_proto_library(
6-
name = "pricetag_proto_py_pb2",
7-
deps = [":pricetag_proto"],
8-
)
9-
10-
proto_library(
11-
name = "pricetag_proto",
12-
srcs = ["pricetag.proto"],
13-
)
142

153
py_test(
164
name = "pricetag_test",
175
srcs = ["test.py"],
186
main = "test.py",
197
deps = [
20-
":pricetag_proto_py_pb2",
8+
"//example.com/proto:pricetag_proto_py_pb2",
219
],
2210
)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
load("@rules_proto//proto:defs.bzl", "proto_library")
2+
load("@rules_python//python:proto.bzl", "py_proto_library")
3+
4+
py_proto_library(
5+
name = "pricetag_proto_py_pb2",
6+
visibility = ["//visibility:public"],
7+
deps = [":pricetag_proto"],
8+
)
9+
10+
proto_library(
11+
name = "pricetag_proto",
12+
srcs = ["pricetag.proto"],
13+
# https://bazel.build/reference/be/protocol-buffer#proto_library.strip_import_prefix
14+
strip_import_prefix = "/example.com",
15+
)

examples/py_proto_library/test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import sys
22
import unittest
33

4-
import pricetag_pb2
4+
from proto import pricetag_pb2
55

66

77
class TestCase(unittest.TestCase):

python/private/proto/py_proto_library.bzl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def _py_proto_aspect_impl(target, ctx):
6666

6767
generated_sources = []
6868
proto_info = target[ProtoInfo]
69+
proto_root = proto_info.proto_source_root
6970
if proto_info.direct_sources:
7071
# Generate py files
7172
generated_sources = proto_common.declare_generated_files(
@@ -76,14 +77,11 @@ def _py_proto_aspect_impl(target, ctx):
7677
)
7778

7879
# Handles multiple repository and virtual import cases
79-
proto_root = proto_info.proto_source_root
8080
if proto_root.startswith(ctx.bin_dir.path):
81-
plugin_output = proto_root
82-
else:
83-
plugin_output = ctx.bin_dir.path + "/" + proto_root
81+
proto_root = proto_root[len(ctx.bin_dir.path) + 1:]
8482

85-
if plugin_output == ".":
86-
plugin_output = ctx.bin_dir.path
83+
plugin_output = ctx.bin_dir.path + "/" + proto_root
84+
proto_root = ctx.workspace_name + "/" + proto_root
8785

8886
proto_common.compile(
8987
actions = ctx.actions,
@@ -109,6 +107,10 @@ def _py_proto_aspect_impl(target, ctx):
109107
return [
110108
_PyProtoInfo(
111109
imports = depset(
110+
# Adding to PYTHONPATH so the generated modules can be imported.
111+
# This is necessary when there is strip_import_prefix, the Python
112+
# modules are generated under _virtual_imports.
113+
[proto_root],
112114
transitive = [dep[PyInfo].imports for dep in api_deps],
113115
),
114116
runfiles_from_proto_deps = runfiles_from_proto_deps,

0 commit comments

Comments
 (0)