Skip to content

Commit fcf7221

Browse files
jimmyt857Jimmy Tanner
and
Jimmy Tanner
authored
fix: Gazelle bug with merging py_binary targets in per-file mode and partial update (bazel-contrib#2619)
This PR adds a new unit test. Currently, this is just a failing test without a fix, and I am still trying to understand the code well enough to find the root cause of the issue. Our team uses Python+Gazelle in a monorepo, and we have a handful of directories with multiple `.py` files containing `if __name__ == "__main__"`. Most of the time these are present for convenience or ad-hoc invocation. We're aware of the [recommendation to split these into separate files](https://github.com/bazelbuild/rules_python/tree/main/gazelle#binaries), but that can cause clutter, and it is non-obvious to most engineers what to do when encountering this issue, which presents either as a misleading error message or a no-op without creating the appropriate targets. **Update** This bug occurs when ALL of the following are true: * `python_generation_mode` is set to `file`. * Multiple python binary files (files with `if __name__ == "__main__"`) exist in the same directory. * The directory has no `__main__.py` file. * The `BUILD` file in the directory is partially complete, i.e. it contains `py_binary` targets for some of the python files, but not others. In this situation, previously absent `py_binary` targets are merged into existing `py_binary` targets instead of being created as new targets. --------- Co-authored-by: Jimmy Tanner <[email protected]>
1 parent fa88281 commit fcf7221

File tree

9 files changed

+53
-1
lines changed

9 files changed

+53
-1
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ Unreleased changes template.
5757
{#v0-0-0-fixed}
5858
### Fixed
5959
* (pypi) The `ppc64le` is now pointing to the right target in the `platforms` package.
60+
* (gazelle) No longer incorrectly merge `py_binary` targets during partial updates in
61+
`file` generation mode. Fixed in [#2619](https://github.com/bazelbuild/rules_python/pull/2619).
6062

6163
{#v0-0-0-added}
6264
### Added

gazelle/python/kinds.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ func (*Python) Kinds() map[string]rule.KindInfo {
3232

3333
var pyKinds = map[string]rule.KindInfo{
3434
pyBinaryKind: {
35-
MatchAny: true,
35+
MatchAny: false,
36+
MatchAttrs: []string{"srcs"},
3637
NonEmptyAttrs: map[string]bool{
3738
"deps": true,
3839
"main": true,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
load("@rules_python//python:defs.bzl", "py_binary")
2+
3+
# gazelle:python_generation_mode file
4+
5+
py_binary(
6+
name = "a",
7+
srcs = ["a.py"],
8+
visibility = ["//:__subpackages__"],
9+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
load("@rules_python//python:defs.bzl", "py_binary")
2+
3+
# gazelle:python_generation_mode file
4+
5+
py_binary(
6+
name = "a",
7+
srcs = ["a.py"],
8+
visibility = ["//:__subpackages__"],
9+
)
10+
11+
py_binary(
12+
name = "b",
13+
srcs = ["b.py"],
14+
visibility = ["//:__subpackages__"],
15+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Partial update with multiple per-file binaries
2+
3+
This test case asserts that when there are multiple binaries in a package, and no __main__.py, and the BUILD file already includes a py_binary for one of the files, a py_binary is generated for the other file.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# This is a Bazel workspace for the Gazelle test data.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
if __name__ == "__main__":
2+
print("Hello, world!")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
if __name__ == "__main__":
2+
print("Hello, world!")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright 2025 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
---
16+
expect:
17+
exit_code: 0

0 commit comments

Comments
 (0)