Skip to content

Commit 104f4bc

Browse files
committed
fix[gazelle]: handle auto-included __init__.py when generating py_binary targets.
Fixes bazel-contrib#3729
1 parent 1c8ca73 commit 104f4bc

5 files changed

Lines changed: 35 additions & 7 deletions

File tree

gazelle/python/generate.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,10 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
258258
// Create a validFilesMap of mainModules to validate if python macros have valid srcs.
259259
validFilesMap := make(map[string]struct{})
260260

261+
// Determine whether we have an __init__.py file in this package and whether we'll implicitly include it in srcs.
262+
hasInit, nonEmptyInit := hasLibraryEntrypointFile(args.Dir)
263+
autoIncludeInit := cfg.PerFileGenerationIncludeInit() && hasInit && nonEmptyInit
264+
261265
appendPyLibrary := func(srcs *treeset.Set, pyLibraryTargetName string) {
262266
allDeps, mainModules, annotations, err := parser.parse(srcs)
263267
for name := range mainModules {
@@ -277,6 +281,10 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
277281
// that we don't also generate a py_library target for it.
278282
if cfg.PerFileGeneration() {
279283
srcs.Remove(name)
284+
// Also remove the __init__.py that was added earlier.
285+
if autoIncludeInit {
286+
srcs.Remove(pyLibraryEntrypointFilename)
287+
}
280288
}
281289
}
282290

@@ -294,15 +302,20 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
294302
filenames := treeset.NewWith(godsutils.StringComparator, filename)
295303
pyiSrcs, _ := getPyiFilenames(filenames, cfg.GeneratePyiSrcs(), args.Dir)
296304

297-
pyBinary := newTargetBuilder(pyBinaryKind, pyBinaryTargetName, pythonProjectRoot, args.Rel, pyFileNames, cfg.ResolveSiblingImports()).
305+
pyBinaryBuilder := newTargetBuilder(pyBinaryKind, pyBinaryTargetName, pythonProjectRoot, args.Rel, pyFileNames, cfg.ResolveSiblingImports()).
298306
addVisibility(visibility).
299307
addSrc(filename).
300308
addPyiSrcs(pyiSrcs).
301309
addModuleDependencies(mainModules[filename]).
302310
addResolvedDependencies(annotations.includeDeps).
303311
generateImportsAttribute().
304-
setAnnotations(*annotations).
305-
build()
312+
setAnnotations(*annotations)
313+
314+
if autoIncludeInit {
315+
pyBinaryBuilder.addSrc(pyLibraryEntrypointFilename)
316+
}
317+
318+
pyBinary := pyBinaryBuilder.build()
306319
result.Gen = append(result.Gen, pyBinary)
307320
result.Imports = append(result.Imports, pyBinary.PrivateAttr(config.GazelleImportsKey))
308321
}
@@ -357,15 +370,15 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
357370
result.Imports = append(result.Imports, pyLibrary.PrivateAttr(config.GazelleImportsKey))
358371
}
359372
}
373+
360374
if cfg.PerFileGeneration() {
361-
hasInit, nonEmptyInit := hasLibraryEntrypointFile(args.Dir)
362375
pyLibraryFilenames.Each(func(index int, filename interface{}) {
363376
pyLibraryTargetName := strings.TrimSuffix(filepath.Base(filename.(string)), ".py")
364377
if filename == pyLibraryEntrypointFilename && !nonEmptyInit {
365378
return // ignore empty __init__.py.
366379
}
367380
srcs := treeset.NewWith(godsutils.StringComparator, filename)
368-
if cfg.PerFileGenerationIncludeInit() && hasInit && nonEmptyInit {
381+
if autoIncludeInit {
369382
srcs.Add(pyLibraryEntrypointFilename)
370383
}
371384
appendPyLibrary(srcs, pyLibraryTargetName)

gazelle/python/testdata/per_file_non_empty_init/BUILD.out

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
load("@rules_python//python:defs.bzl", "py_library")
1+
load("@rules_python//python:defs.bzl", "py_binary", "py_library")
22

33
# gazelle:python_generation_mode file
44
# gazelle:python_generation_mode_per_file_include_init true
@@ -18,3 +18,13 @@ py_library(
1818
],
1919
visibility = ["//:__subpackages__"],
2020
)
21+
22+
py_binary(
23+
name = "foobin",
24+
srcs = [
25+
"__init__.py",
26+
"foobin.py",
27+
],
28+
visibility = ["//:__subpackages__"],
29+
deps = [":foo"],
30+
)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# Per-file generation
22

3-
This test case generates one `py_library` per file, including `__init__.py`.
3+
This test case generates one `py_library` or `py_binary` per file, including `__init__.py`.

gazelle/python/testdata/per_file_non_empty_init/foo.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@
1313
# limitations under the License.
1414

1515
# For test purposes only.
16+
BAR = "baz"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from foo import BAR
2+
3+
if __name__ == "__main__":
4+
print(BAR)

0 commit comments

Comments
 (0)