Skip to content

Commit 0e49623

Browse files
committed
Merge branch 'main' into martani/no-sibling-import
2 parents e66010b + e6bba92 commit 0e49623

File tree

24 files changed

+344
-8
lines changed

24 files changed

+344
-8
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ END_UNRELEASED_TEMPLATE
9191
* Multi-line python imports (e.g. with escaped newlines) are now correctly processed by Gazelle.
9292
* (toolchains) `local_runtime_repo` works with multiarch Debian with Python 3.8
9393
([#3099](https://github.com/bazel-contrib/rules_python/issues/3099)).
94+
* (pypi) Expose pypi packages only common to all Python versions in `all_requirements`
95+
([#2921](https://github.com/bazel-contrib/rules_python/issues/2921)).
96+
* (repl) Normalize the path for the `REPL` stub to make it possible to use the
97+
default stub template from outside `rules_python` ({gh-issue}`3101`).
9498

9599
{#v0-0-0-added}
96100
### Added
@@ -116,6 +120,8 @@ END_UNRELEASED_TEMPLATE
116120
dep is not added to the {obj}`py_test` target.
117121
* (gazelle) New directive `gazelle:python_generate_proto`; when `true`,
118122
Gazelle generates `py_proto_library` rules for `proto_library`. `false` by default.
123+
* (gazelle) New directive `gazelle:python_proto_naming_convention`; controls
124+
naming of `py_proto_library` rules.
119125
* (gazelle) Added directive `# gazelle:python_resolve_sibling_imports` (default
120126
`enabled` for backwards-compatibility). When enabled, gazelle will allow absolute
121127
imports to be resolved to sibling modules (Python 2's behavior without

docs/requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,9 +350,9 @@ sphinxcontrib-serializinghtml==2.0.0 \
350350
--hash=sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 \
351351
--hash=sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d
352352
# via sphinx
353-
typing-extensions==4.13.2 \
354-
--hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c \
355-
--hash=sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef
353+
typing-extensions==4.14.1 \
354+
--hash=sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36 \
355+
--hash=sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76
356356
# via
357357
# rules-python-docs (docs/pyproject.toml)
358358
# sphinx-autodoc2

gazelle/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ Python-specific directives are as follows:
208208
| Controls the `py_binary` naming convention. Follows the same interpolation rules as `python_library_naming_convention`. | |
209209
| `# gazelle:python_test_naming_convention` | `$package_name$_test` |
210210
| Controls the `py_test` naming convention. Follows the same interpolation rules as `python_library_naming_convention`. | |
211+
| [`# gazelle:python_proto_naming_convention`](#directive-python_proto_naming_convention) | `$proto_name$_py_pb2` |
212+
| Controls the `py_proto_library` naming convention. It interpolates `$proto_name$` with the proto_library rule name, minus any trailing _proto. E.g. if the proto_library name is `foo_proto`, setting this to `$proto_name$_my_lib` would render to `foo_my_lib`. | |
211213
| `# gazelle:resolve py ...` | n/a |
212214
| Instructs the plugin what target to add as a dependency to satisfy a given import statement. The syntax is `# gazelle:resolve py import-string label` where `import-string` is the symbol in the python `import` statement, and `label` is the Bazel label that Gazelle should write in `deps`. | |
213215
| [`# gazelle:python_default_visibility labels`](#directive-python_default_visibility) | |
@@ -264,6 +266,31 @@ py_libary(
264266

265267
[python-packaging-user-guide]: https://github.com/pypa/packaging.python.org/blob/4c86169a/source/tutorials/packaging-projects.rst
266268

269+
#### Directive: `python_proto_naming_convention`:
270+
271+
Set this directive to a string pattern to control how the generated `py_proto_library` targets are named. When generating new `py_proto_library` rules, Gazelle will replace `$proto_name$` in the pattern with the name of the `proto_library` rule, stripping out a trailing `_proto`. For example:
272+
273+
```starlark
274+
# gazelle:python_generate_proto true
275+
# gazelle:python_proto_naming_convention my_custom_$proto_name$_pattern
276+
277+
proto_library(
278+
name = "foo_proto",
279+
srcs = ["foo.proto"],
280+
)
281+
```
282+
283+
produces the following `py_proto_library` rule:
284+
```starlark
285+
py_proto_library(
286+
name = "my_custom_foo_pattern",
287+
deps = [":foo_proto"],
288+
)
289+
```
290+
291+
The default naming convention is `$proto_name$_pb2_py`, so by default in the above example Gazelle would generate `foo_pb2_py`. Any pre-existing rules are left in place and not renamed.
292+
293+
Note that the Python library will always be imported as `foo_pb2` in Python code, regardless of the naming convention. Also note that Gazelle is currently not able to map said imports, e.g. `import foo_pb2`, to fill in `py_proto_library` targets as dependencies of other rules. See [this issue](https://github.com/bazel-contrib/rules_python/issues/1703).
267294

268295
#### Directive: `python_default_visibility`:
269296

gazelle/python/configure.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ func (py *Configurer) KnownDirectives() []string {
6363
pythonconfig.LibraryNamingConvention,
6464
pythonconfig.BinaryNamingConvention,
6565
pythonconfig.TestNamingConvention,
66+
pythonconfig.ProtoNamingConvention,
6667
pythonconfig.DefaultVisibilty,
6768
pythonconfig.Visibility,
6869
pythonconfig.TestFilePattern,
@@ -180,6 +181,8 @@ func (py *Configurer) Configure(c *config.Config, rel string, f *rule.File) {
180181
config.SetBinaryNamingConvention(strings.TrimSpace(d.Value))
181182
case pythonconfig.TestNamingConvention:
182183
config.SetTestNamingConvention(strings.TrimSpace(d.Value))
184+
case pythonconfig.ProtoNamingConvention:
185+
config.SetProtoNamingConvention(strings.TrimSpace(d.Value))
183186
case pythonconfig.DefaultVisibilty:
184187
switch directiveArg := strings.TrimSpace(d.Value); directiveArg {
185188
case "NONE":

gazelle/python/generate.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
227227
result.Gen = make([]*rule.Rule, 0)
228228

229229
if cfg.GenerateProto() {
230-
generateProtoLibraries(args, pythonProjectRoot, visibility, &result)
230+
generateProtoLibraries(args, cfg, pythonProjectRoot, visibility, &result)
231231
}
232232

233233
collisionErrors := singlylinkedlist.New()
@@ -569,7 +569,7 @@ func ensureNoCollision(file *rule.File, targetName, kind string) error {
569569
return nil
570570
}
571571

572-
func generateProtoLibraries(args language.GenerateArgs, pythonProjectRoot string, visibility []string, res *language.GenerateResult) {
572+
func generateProtoLibraries(args language.GenerateArgs, cfg *pythonconfig.Config, pythonProjectRoot string, visibility []string, res *language.GenerateResult) {
573573
// First, enumerate all the proto_library in this package.
574574
var protoRuleNames []string
575575
for _, r := range args.OtherGen {
@@ -582,18 +582,29 @@ func generateProtoLibraries(args language.GenerateArgs, pythonProjectRoot string
582582

583583
// Next, enumerate all the pre-existing py_proto_library in this package, so we can delete unnecessary rules later.
584584
pyProtoRules := map[string]bool{}
585+
pyProtoRulesForProto := map[string]string{}
585586
if args.File != nil {
586587
for _, r := range args.File.Rules {
587588
if r.Kind() == "py_proto_library" {
588589
pyProtoRules[r.Name()] = false
590+
591+
protos := r.AttrStrings("deps")
592+
for _, proto := range protos {
593+
pyProtoRulesForProto[strings.TrimPrefix(proto, ":")] = r.Name()
594+
}
589595
}
590596
}
591597
}
592598

593599
emptySiblings := treeset.Set{}
594600
// Generate a py_proto_library for each proto_library.
595601
for _, protoRuleName := range protoRuleNames {
596-
pyProtoLibraryName := strings.TrimSuffix(protoRuleName, "_proto") + "_py_pb2"
602+
pyProtoLibraryName := cfg.RenderProtoName(protoRuleName)
603+
if ruleName, ok := pyProtoRulesForProto[protoRuleName]; ok {
604+
// There exists a pre-existing py_proto_library for this proto. Keep this name.
605+
pyProtoLibraryName = ruleName
606+
}
607+
597608
pyProtoLibrary := newTargetBuilder(pyProtoLibraryKind, pyProtoLibraryName, pythonProjectRoot, args.Rel, &emptySiblings, false).
598609
addVisibility(visibility).
599610
addResolvedDependency(":" + protoRuleName).
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Directive: `python_proto_naming_convention`
2+
3+
This test case asserts that the `# gazelle:python_proto_naming_convention` directive
4+
correctly:
5+
6+
1. Has no effect on pre-existing `py_proto_library` when `gazelle:python_generate_proto` is disabled.
7+
2. Uses the default value when proto generation is on and `python_proto_naming_convention` is not set.
8+
3. Uses the provided naming convention when proto generation is on and `python_proto_naming_convention` is set.
9+
4. With a pre-existing `py_proto_library` not following a given naming convention, keeps it intact and does not rename it.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# This is a Bazel workspace for the Gazelle test data.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
---
2+
expect:
3+
exit_code: 0
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
load("@com_google_protobuf//bazel:py_proto_library.bzl", "py_proto_library")
2+
load("@rules_proto//proto:defs.bzl", "proto_library")
3+
4+
# gazelle:python_generate_proto false
5+
# gazelle:python_proto_naming_convention some_$proto_name$_value
6+
7+
proto_library(
8+
name = "foo_proto",
9+
srcs = ["foo.proto"],
10+
visibility = ["//:__subpackages__"],
11+
)
12+
13+
py_proto_library(
14+
name = "foo_proto_custom_name",
15+
visibility = ["//:__subpackages__"],
16+
deps = [":foo_proto"],
17+
)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
load("@com_google_protobuf//bazel:py_proto_library.bzl", "py_proto_library")
2+
load("@rules_proto//proto:defs.bzl", "proto_library")
3+
4+
# gazelle:python_generate_proto false
5+
# gazelle:python_proto_naming_convention some_$proto_name$_value
6+
7+
proto_library(
8+
name = "foo_proto",
9+
srcs = ["foo.proto"],
10+
visibility = ["//:__subpackages__"],
11+
)
12+
13+
py_proto_library(
14+
name = "foo_proto_custom_name",
15+
visibility = ["//:__subpackages__"],
16+
deps = [":foo_proto"],
17+
)

0 commit comments

Comments
 (0)