Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 3 additions & 2 deletions gazelle/python/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
# STDIN receives parse requests, one per line. It outputs the parsed modules and
# comments from all the files from each request.

import parse
import std_modules
import sys

import python.parse as parse
import python.std_modules as std_modules
Comment thread
siddharthab marked this conversation as resolved.
Outdated

if __name__ == "__main__":
if len(sys.argv) < 2:
sys.exit("Please provide subcommand, either print or std_modules")
Expand Down
39 changes: 33 additions & 6 deletions gazelle/python/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"io/fs"
"log"
"os"
pathpkg "path"
"path/filepath"
"strings"

Expand Down Expand Up @@ -252,18 +253,31 @@ 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{}) {
var pyLibraryTargetName string
if filename == pyLibraryEntrypointFilename {
stat, err := os.Stat(filepath.Join(args.Dir, filename.(string)))
if err != nil {
log.Fatalf("ERROR: %v\n", err)
if !nonEmptyInit {
return // ignore empty __init__.py.
}
if stat.Size() == 0 {
return // ignore empty __init__.py
if args.File.Pkg == "" {
// As per Python spec, an __init__.py file does not make sense without
// a package name, but someone can technically configure the Bazel
// workspace as the Python package (i.e. parent of the Bazel workspace
// is part of PYTHONPATH), in which case this should be the workspace
// name, but there is no mechanism to obtain that here. So let's just
// call it "__init__".
pyLibraryTargetName = "__init__"
} else {
pyLibraryTargetName = pathpkg.Base(args.File.Pkg)
}
} else {
pyLibraryTargetName = strings.TrimSuffix(filepath.Base(filename.(string)), ".py")
}
srcs := treeset.NewWith(godsutils.StringComparator, filename)
pyLibraryTargetName := strings.TrimSuffix(filepath.Base(filename.(string)), ".py")
if hasInit && nonEmptyInit {
srcs.Add(pyLibraryEntrypointFilename)
}
appendPyLibrary(srcs, pyLibraryTargetName)
})
} else if !pyLibraryFilenames.Empty() {
Expand Down Expand Up @@ -463,6 +477,19 @@ func hasEntrypointFile(dir string) bool {
return false
}

// hasLibraryEntrypointFile returns if the given directory has the library
// entrypoint file, and if it is non-empty.
func hasLibraryEntrypointFile(dir string) (bool, bool) {
stat, err := os.Stat(filepath.Join(dir, pyLibraryEntrypointFilename))
if os.IsNotExist(err) {
return false, false
}
if err != nil {
log.Fatalf("ERROR: %v\n", err)
}
return true, stat.Size() != 0
}

// isEntrypointFile returns whether the given path is an entrypoint file. The
// given path can be absolute or relative.
func isEntrypointFile(path string) bool {
Expand Down
14 changes: 10 additions & 4 deletions gazelle/python/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,17 @@ func (py *Resolver) Imports(c *config.Config, r *rule.Rule, f *rule.File) []reso
provides := make([]resolve.ImportSpec, 0, len(srcs)+1)
for _, src := range srcs {
ext := filepath.Ext(src)
if ext == ".py" {
pythonProjectRoot := cfg.PythonProjectRoot()
provide := importSpecFromSrc(pythonProjectRoot, f.Pkg, src)
provides = append(provides, provide)
if ext != ".py" {
continue
}
if cfg.PerFileGeneration() && len(srcs) > 1 && src == pyLibraryEntrypointFilename {
// Do not provide import spec from __init__.py when it is being included as
// part of another module.
continue
}
pythonProjectRoot := cfg.PythonProjectRoot()
provide := importSpecFromSrc(pythonProjectRoot, f.Pkg, src)
provides = append(provides, provide)
}
if len(provides) == 0 {
return nil
Expand Down
5 changes: 4 additions & 1 deletion gazelle/python/testdata/per_file_non_empty_init/BUILD.out
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ py_library(

py_library(
name = "foo",
srcs = ["foo.py"],
srcs = [
"__init__.py",
Comment thread
siddharthab marked this conversation as resolved.
"foo.py",
],
visibility = ["//:__subpackages__"],
)
2 changes: 1 addition & 1 deletion gazelle/python/testdata/per_file_subdirs/BUILD.out
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ py_library(
name = "foo",
srcs = ["foo.py"],
visibility = ["//:__subpackages__"],
deps = ["//bar:__init__"],
deps = ["//bar"],
)
7 changes: 5 additions & 2 deletions gazelle/python/testdata/per_file_subdirs/bar/BUILD.out
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
load("@rules_python//python:defs.bzl", "py_library", "py_test")

py_library(
Comment thread
siddharthab marked this conversation as resolved.
name = "__init__",
name = "bar",
srcs = ["__init__.py"],
visibility = ["//:__subpackages__"],
)

py_library(
name = "foo",
srcs = ["foo.py"],
srcs = [
"__init__.py",
"foo.py",
],
visibility = ["//:__subpackages__"],
)

Expand Down