diff --git a/gazelle/python/resolve.go b/gazelle/python/resolve.go index 7a2ec3d68a..2d5b683a23 100644 --- a/gazelle/python/resolve.go +++ b/gazelle/python/resolve.go @@ -55,6 +55,9 @@ func (*Resolver) Name() string { return languageName } // If nil is returned, the rule will not be indexed. If any non-nil slice is // returned, including an empty slice, the rule will be indexed. func (py *Resolver) Imports(c *config.Config, r *rule.Rule, f *rule.File) []resolve.ImportSpec { + if !indexPyBinaryImport(r, f) { + return nil + } cfgs := c.Exts[languageName].(pythonconfig.Configs) cfg := cfgs[f.Pkg] srcs := r.AttrStrings("srcs") @@ -317,3 +320,29 @@ func convertDependencySetToExpr(set *treeset.Set) bzl.Expr { } return &bzl.ListExpr{List: deps} } + +// indexPyBinaryImport returns whether the corresponding py_binary rule need to be indexed. +// To avoid multiple labels indexing the same import, +// check if there is a corresponding py_library rule with the same srcs. +func indexPyBinaryImport(r *rule.Rule, f *rule.File) bool { + // If the rule is not a py_binary, it should be indexed. + if r.Kind() != "py_binary" { + return true + } + pyBinarySrcs := r.AttrStrings("srcs") + if len(pyBinarySrcs) == 0 { + return false + } + for _, otherRule := range f.Rules { + if otherRule.Kind() != "py_library" { + continue + } + pyLibrarySrcs := otherRule.AttrStrings("srcs") + for _, src := range pyLibrarySrcs { + if src == pyBinarySrcs[0] { + return false + } + } + } + return true +} diff --git a/gazelle/python/testdata/import_with_same_srcs_library_and_binary/BUILD.in b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/BUILD.in new file mode 100644 index 0000000000..fc43208db2 --- /dev/null +++ b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/BUILD.in @@ -0,0 +1,3 @@ +# gazelle:python_extension enabled +# gazelle:python_library_naming_convention py_default_library +# gazelle:python_generation_mode package diff --git a/gazelle/python/testdata/import_with_same_srcs_library_and_binary/BUILD.out b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/BUILD.out new file mode 100644 index 0000000000..fc43208db2 --- /dev/null +++ b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/BUILD.out @@ -0,0 +1,3 @@ +# gazelle:python_extension enabled +# gazelle:python_library_naming_convention py_default_library +# gazelle:python_generation_mode package diff --git a/gazelle/python/testdata/import_with_same_srcs_library_and_binary/README.md b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/README.md new file mode 100644 index 0000000000..39095b5aff --- /dev/null +++ b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/README.md @@ -0,0 +1,2 @@ +# Import with same srcs for library and binary +This test case asserts a file with py_library and py_binary rules that include the same .py file in srcs will resolve to the py_library rule correctly. diff --git a/gazelle/python/testdata/import_with_same_srcs_library_and_binary/WORKSPACE b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/WORKSPACE new file mode 100644 index 0000000000..faff6af87a --- /dev/null +++ b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/WORKSPACE @@ -0,0 +1 @@ +# This is a Bazel workspace for the Gazelle test data. diff --git a/gazelle/python/testdata/import_with_same_srcs_library_and_binary/bar/BUILD.in b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/bar/BUILD.in new file mode 100644 index 0000000000..f976ef1c58 --- /dev/null +++ b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/bar/BUILD.in @@ -0,0 +1,8 @@ +load("@rules_python//python:defs.bzl", "py_library") + +py_library( + name = "bar", + srcs = ["bar.py"], + visibility = ["//:__subpackages__"], + deps = ["//foo"], +) diff --git a/gazelle/python/testdata/import_with_same_srcs_library_and_binary/bar/BUILD.out b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/bar/BUILD.out new file mode 100644 index 0000000000..a93d3710cb --- /dev/null +++ b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/bar/BUILD.out @@ -0,0 +1,8 @@ +load("@rules_python//python:defs.bzl", "py_library") + +py_library( + name = "bar", + srcs = ["bar.py"], + visibility = ["//:__subpackages__"], + deps = ["//foo:py_default_library"], +) diff --git a/gazelle/python/testdata/import_with_same_srcs_library_and_binary/bar/bar.py b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/bar/bar.py new file mode 100644 index 0000000000..9935a64811 --- /dev/null +++ b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/bar/bar.py @@ -0,0 +1 @@ +import foo.script diff --git a/gazelle/python/testdata/import_with_same_srcs_library_and_binary/foo/BUILD.in b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/foo/BUILD.in new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gazelle/python/testdata/import_with_same_srcs_library_and_binary/foo/BUILD.out b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/foo/BUILD.out new file mode 100644 index 0000000000..fe6482a492 --- /dev/null +++ b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/foo/BUILD.out @@ -0,0 +1,13 @@ +load("@rules_python//python:defs.bzl", "py_binary", "py_library") + +py_binary( + name = "script", + srcs = ["script.py"], + visibility = ["//:__subpackages__"], +) + +py_library( + name = "py_default_library", + srcs = ["script.py"], + visibility = ["//:__subpackages__"], +) diff --git a/gazelle/python/testdata/import_with_same_srcs_library_and_binary/foo/script.py b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/foo/script.py new file mode 100644 index 0000000000..165f69654f --- /dev/null +++ b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/foo/script.py @@ -0,0 +1,3 @@ + +if __name__ == "__main__": + print("Hello, world!") diff --git a/gazelle/python/testdata/import_with_same_srcs_library_and_binary/test.yaml b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/test.yaml new file mode 100644 index 0000000000..2410223e59 --- /dev/null +++ b/gazelle/python/testdata/import_with_same_srcs_library_and_binary/test.yaml @@ -0,0 +1,17 @@ +# Copyright 2023 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +--- +expect: + exit_code: 0