Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ END_UNRELEASED_TEMPLATE

{#v0-0-0-fixed}
### Fixed
* Nothing fixed.
* (gazelle) Fixed handling of auto-included `__init__.py` files when generating `py_binary`
targets ([#3729](https://github.com/bazel-contrib/rules_python/issues/3729)).

{#v0-0-0-added}
### Added
Expand Down
30 changes: 24 additions & 6 deletions gazelle/python/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,15 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
// Create a validFilesMap of mainModules to validate if python macros have valid srcs.
validFilesMap := make(map[string]struct{})

// Determine whether we have an __init__.py file in this package and whether we'll implicitly include it in srcs.
var hasPopulatedInit bool
var autoIncludeInit bool
if cfg.PerFileGeneration() {
var hasInit bool
hasInit, hasPopulatedInit = hasLibraryEntrypointFile(args.Dir)
autoIncludeInit = cfg.PerFileGenerationIncludeInit() && hasInit && hasPopulatedInit
}

appendPyLibrary := func(srcs *treeset.Set, pyLibraryTargetName string) {
allDeps, mainModules, annotations, err := parser.parse(srcs)
for name := range mainModules {
Expand All @@ -277,6 +286,10 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
// that we don't also generate a py_library target for it.
if cfg.PerFileGeneration() {
srcs.Remove(name)
// Also remove the __init__.py that was added earlier.
if autoIncludeInit {
srcs.Remove(pyLibraryEntrypointFilename)
}
}
}

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

pyBinary := newTargetBuilder(pyBinaryKind, pyBinaryTargetName, pythonProjectRoot, args.Rel, pyFileNames, cfg.ResolveSiblingImports()).
pyBinaryBuilder := newTargetBuilder(pyBinaryKind, pyBinaryTargetName, pythonProjectRoot, args.Rel, pyFileNames, cfg.ResolveSiblingImports()).
addVisibility(visibility).
addSrc(filename).
addPyiSrcs(pyiSrcs).
addModuleDependencies(mainModules[filename]).
addResolvedDependencies(annotations.includeDeps).
generateImportsAttribute().
setAnnotations(*annotations).
build()
setAnnotations(*annotations)

if autoIncludeInit {
pyBinaryBuilder.addSrc(pyLibraryEntrypointFilename)
}

pyBinary := pyBinaryBuilder.build()
result.Gen = append(result.Gen, pyBinary)
result.Imports = append(result.Imports, pyBinary.PrivateAttr(config.GazelleImportsKey))
}
Expand Down Expand Up @@ -357,15 +375,15 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
result.Imports = append(result.Imports, pyLibrary.PrivateAttr(config.GazelleImportsKey))
}
}

if cfg.PerFileGeneration() {
hasInit, nonEmptyInit := hasLibraryEntrypointFile(args.Dir)
pyLibraryFilenames.Each(func(index int, filename interface{}) {
pyLibraryTargetName := strings.TrimSuffix(filepath.Base(filename.(string)), ".py")
if filename == pyLibraryEntrypointFilename && !nonEmptyInit {
if filename == pyLibraryEntrypointFilename && !hasPopulatedInit {
return // ignore empty __init__.py.
}
srcs := treeset.NewWith(godsutils.StringComparator, filename)
if cfg.PerFileGenerationIncludeInit() && hasInit && nonEmptyInit {
if autoIncludeInit {
srcs.Add(pyLibraryEntrypointFilename)
}
appendPyLibrary(srcs, pyLibraryTargetName)
Expand Down
12 changes: 11 additions & 1 deletion gazelle/python/testdata/per_file_non_empty_init/BUILD.out
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("@rules_python//python:defs.bzl", "py_library")
load("@rules_python//python:defs.bzl", "py_binary", "py_library")

# gazelle:python_generation_mode file
# gazelle:python_generation_mode_per_file_include_init true
Expand All @@ -18,3 +18,13 @@ py_library(
],
visibility = ["//:__subpackages__"],
)

py_binary(
name = "foobin",
srcs = [
"__init__.py",
"foobin.py",
],
visibility = ["//:__subpackages__"],
deps = [":foo"],
)
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Per-file generation

This test case generates one `py_library` per file, including `__init__.py`.
This test case generates one `py_library` or `py_binary` per file, including `__init__.py`.
1 change: 1 addition & 0 deletions gazelle/python/testdata/per_file_non_empty_init/foo.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
# limitations under the License.

# For test purposes only.
BAR = "baz"
4 changes: 4 additions & 0 deletions gazelle/python/testdata/per_file_non_empty_init/foobin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from foo import BAR

if __name__ == "__main__":
print(BAR)