From 6d5c9298eb9f9f9abcc0c4c46b33a87148910c05 Mon Sep 17 00:00:00 2001 From: Zhongpeng Lin Date: Tue, 31 Jan 2023 15:44:23 -0800 Subject: [PATCH 1/4] Resolving sibling modules with absolute imports (#1029) * Resolving sibling modules with absolute imports * unconditionally importing conftest * handle from statements * adding tests * adding readme for the new test case Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> --- gazelle/python/generate.go | 19 +++--------- gazelle/python/resolve.go | 11 ------- gazelle/python/target.go | 27 +++++++---------- .../generated_test_entrypoint/BUILD.out | 5 +--- .../testdata/naming_convention/__main__.py | 1 + .../testdata/naming_convention/__test__.py | 1 + .../naming_convention/dont_rename/__main__.py | 1 + .../naming_convention/dont_rename/__test__.py | 1 + .../resolve_conflict/__main__.py | 1 + .../resolve_conflict/__test__.py | 1 + .../real_test.py | 1 + .../test_reality.py | 1 + .../python/testdata/sibling_imports/README.md | 3 ++ .../python/testdata/sibling_imports/WORKSPACE | 1 + .../testdata/sibling_imports/pkg/BUILD.in | 0 .../testdata/sibling_imports/pkg/BUILD.out | 29 +++++++++++++++++++ .../testdata/sibling_imports/pkg/__init__.py | 0 .../python/testdata/sibling_imports/pkg/a.py | 0 .../python/testdata/sibling_imports/pkg/b.py | 2 ++ .../testdata/sibling_imports/pkg/test_util.py | 0 .../testdata/sibling_imports/pkg/unit_test.py | 3 ++ .../python/testdata/sibling_imports/test.yaml | 1 + .../simple_binary_with_library/__main__.py | 1 + .../subdir_sources/foo/has_main/__main__.py | 1 + .../subdir_sources/foo/has_test/__test__.py | 1 + .../with_third_party_requirements/BUILD.out | 2 +- 26 files changed, 66 insertions(+), 48 deletions(-) create mode 100644 gazelle/python/testdata/sibling_imports/README.md create mode 100644 gazelle/python/testdata/sibling_imports/WORKSPACE create mode 100644 gazelle/python/testdata/sibling_imports/pkg/BUILD.in create mode 100644 gazelle/python/testdata/sibling_imports/pkg/BUILD.out create mode 100644 gazelle/python/testdata/sibling_imports/pkg/__init__.py create mode 100644 gazelle/python/testdata/sibling_imports/pkg/a.py create mode 100644 gazelle/python/testdata/sibling_imports/pkg/b.py create mode 100644 gazelle/python/testdata/sibling_imports/pkg/test_util.py create mode 100644 gazelle/python/testdata/sibling_imports/pkg/unit_test.py create mode 100644 gazelle/python/testdata/sibling_imports/test.yaml diff --git a/gazelle/python/generate.go b/gazelle/python/generate.go index 4ebb40f6bb..74e5f66509 100644 --- a/gazelle/python/generate.go +++ b/gazelle/python/generate.go @@ -224,7 +224,6 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes } pyLibrary = newTargetBuilder(pyLibraryKind, pyLibraryTargetName, pythonProjectRoot, args.Rel, pyLibraryFilenames.Union(pyTestFilenames)). - setUUID(label.New("", args.Rel, pyLibraryTargetName).String()). addVisibility(visibility). addSrcs(pyLibraryFilenames). addModuleDependencies(deps). @@ -267,10 +266,6 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes addModuleDependencies(deps). generateImportsAttribute() - if pyLibrary != nil { - pyBinaryTarget.addModuleDependency(module{Name: pyLibrary.PrivateAttr(uuidKey).(string)}) - } - pyBinary := pyBinaryTarget.build() result.Gen = append(result.Gen, pyBinary) @@ -301,7 +296,6 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes } conftestTarget := newTargetBuilder(pyLibraryKind, conftestTargetname, pythonProjectRoot, args.Rel, pyLibraryFilenames.Union(pyTestFilenames)). - setUUID(label.New("", args.Rel, conftestTargetname).String()). addSrc(conftestFilename). addModuleDependencies(deps). addVisibility(visibility). @@ -315,8 +309,8 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes } var pyTestTargets []*targetBuilder - newPyTestTargetBuilder := func(pyTestFilenames *treeset.Set, pyTestTargetName string) *targetBuilder { - deps, err := parser.parse(pyTestFilenames) + newPyTestTargetBuilder := func(srcs *treeset.Set, pyTestTargetName string) *targetBuilder { + deps, err := parser.parse(srcs) if err != nil { log.Fatalf("ERROR: %v\n", err) } @@ -337,7 +331,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes } } return newTargetBuilder(pyTestKind, pyTestTargetName, pythonProjectRoot, args.Rel, pyLibraryFilenames.Union(pyTestFilenames)). - addSrcs(pyTestFilenames). + addSrcs(srcs). addModuleDependencies(deps). generateImportsAttribute() } @@ -371,14 +365,9 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes } for _, pyTestTarget := range pyTestTargets { - if pyLibrary != nil { - pyTestTarget.addModuleDependency(module{Name: pyLibrary.PrivateAttr(uuidKey).(string)}) - } - if conftest != nil { - pyTestTarget.addModuleDependency(module{Name: conftest.PrivateAttr(uuidKey).(string)}) + pyTestTarget.addModuleDependency(module{Name: strings.TrimSuffix(conftestFilename, ".py")}) } - pyTest := pyTestTarget.build() result.Gen = append(result.Gen, pyTest) diff --git a/gazelle/python/resolve.go b/gazelle/python/resolve.go index 607776aee3..46014e50ec 100644 --- a/gazelle/python/resolve.go +++ b/gazelle/python/resolve.go @@ -39,10 +39,6 @@ const ( // resolvedDepsKey is the attribute key used to pass dependencies that don't // need to be resolved by the dependency resolver in the Resolver step. resolvedDepsKey = "_gazelle_python_resolved_deps" - // uuidKey is the attribute key used to uniquely identify a py_library - // target that should be imported by a py_test or py_binary in the same - // Bazel package. - uuidKey = "_gazelle_python_library_uuid" ) // Resolver satisfies the resolve.Resolver interface. It resolves dependencies @@ -71,13 +67,6 @@ func (py *Resolver) Imports(c *config.Config, r *rule.Rule, f *rule.File) []reso provides = append(provides, provide) } } - if r.PrivateAttr(uuidKey) != nil { - provide := resolve.ImportSpec{ - Lang: languageName, - Imp: r.PrivateAttr(uuidKey).(string), - } - provides = append(provides, provide) - } if len(provides) == 0 { return nil } diff --git a/gazelle/python/target.go b/gazelle/python/target.go index 69711ce643..fdc99fc68c 100644 --- a/gazelle/python/target.go +++ b/gazelle/python/target.go @@ -15,12 +15,11 @@ package python import ( - "path/filepath" - "github.com/bazelbuild/bazel-gazelle/config" "github.com/bazelbuild/bazel-gazelle/rule" "github.com/emirpasic/gods/sets/treeset" godsutils "github.com/emirpasic/gods/utils" + "path/filepath" ) // targetBuilder builds targets to be generated by Gazelle. @@ -29,7 +28,6 @@ type targetBuilder struct { name string pythonProjectRoot string bzlPackage string - uuid string srcs *treeset.Set siblingSrcs *treeset.Set deps *treeset.Set @@ -55,15 +53,6 @@ func newTargetBuilder(kind, name, pythonProjectRoot, bzlPackage string, siblingS } } -// setUUID sets the given UUID for the target. It's used to index the generated -// target based on this value in addition to the other ways the targets can be -// imported. py_{binary,test} targets in the same Bazel package can add a -// virtual dependency to this UUID that gets resolved in the Resolver interface. -func (t *targetBuilder) setUUID(uuid string) *targetBuilder { - t.uuid = uuid - return t -} - // addSrc adds a single src to the target. func (t *targetBuilder) addSrc(src string) *targetBuilder { t.srcs.Add(src) @@ -81,9 +70,16 @@ func (t *targetBuilder) addSrcs(srcs *treeset.Set) *targetBuilder { // addModuleDependency adds a single module dep to the target. func (t *targetBuilder) addModuleDependency(dep module) *targetBuilder { - if dep.Name+".py" == filepath.Base(dep.Filepath) || !t.siblingSrcs.Contains(dep.Name+".py") { - t.deps.Add(dep) + fileName := dep.Name + ".py" + if dep.From != "" { + fileName = dep.From + ".py" } + if t.siblingSrcs.Contains(fileName) && fileName != filepath.Base(dep.Filepath) { + // importing another module from the same package, converting to absolute imports to make + // dependency resolution easier + dep.Name = importSpecFromSrc(t.pythonProjectRoot, t.bzlPackage, fileName).Imp + } + t.deps.Add(dep) return t } @@ -138,9 +134,6 @@ func (t *targetBuilder) generateImportsAttribute() *targetBuilder { // build returns the assembled *rule.Rule for the target. func (t *targetBuilder) build() *rule.Rule { r := rule.NewRule(t.kind, t.name) - if t.uuid != "" { - r.SetPrivateAttr(uuidKey, t.uuid) - } if !t.srcs.Empty() { r.SetAttr("srcs", t.srcs.Values()) } diff --git a/gazelle/python/testdata/generated_test_entrypoint/BUILD.out b/gazelle/python/testdata/generated_test_entrypoint/BUILD.out index 48df0688a6..e8e304c72b 100644 --- a/gazelle/python/testdata/generated_test_entrypoint/BUILD.out +++ b/gazelle/python/testdata/generated_test_entrypoint/BUILD.out @@ -17,8 +17,5 @@ py_test( name = "generated_test_entrypoint_test", srcs = [":__test__"], main = ":__test__.py", - deps = [ - ":__test__", - ":generated_test_entrypoint", - ], + deps = [":__test__"], ) diff --git a/gazelle/python/testdata/naming_convention/__main__.py b/gazelle/python/testdata/naming_convention/__main__.py index 730755995d..a3afc79dcd 100644 --- a/gazelle/python/testdata/naming_convention/__main__.py +++ b/gazelle/python/testdata/naming_convention/__main__.py @@ -13,3 +13,4 @@ # limitations under the License. # For test purposes only. +import __init__ \ No newline at end of file diff --git a/gazelle/python/testdata/naming_convention/__test__.py b/gazelle/python/testdata/naming_convention/__test__.py index 730755995d..a3afc79dcd 100644 --- a/gazelle/python/testdata/naming_convention/__test__.py +++ b/gazelle/python/testdata/naming_convention/__test__.py @@ -13,3 +13,4 @@ # limitations under the License. # For test purposes only. +import __init__ \ No newline at end of file diff --git a/gazelle/python/testdata/naming_convention/dont_rename/__main__.py b/gazelle/python/testdata/naming_convention/dont_rename/__main__.py index 730755995d..a3afc79dcd 100644 --- a/gazelle/python/testdata/naming_convention/dont_rename/__main__.py +++ b/gazelle/python/testdata/naming_convention/dont_rename/__main__.py @@ -13,3 +13,4 @@ # limitations under the License. # For test purposes only. +import __init__ \ No newline at end of file diff --git a/gazelle/python/testdata/naming_convention/dont_rename/__test__.py b/gazelle/python/testdata/naming_convention/dont_rename/__test__.py index 730755995d..a3afc79dcd 100644 --- a/gazelle/python/testdata/naming_convention/dont_rename/__test__.py +++ b/gazelle/python/testdata/naming_convention/dont_rename/__test__.py @@ -13,3 +13,4 @@ # limitations under the License. # For test purposes only. +import __init__ \ No newline at end of file diff --git a/gazelle/python/testdata/naming_convention/resolve_conflict/__main__.py b/gazelle/python/testdata/naming_convention/resolve_conflict/__main__.py index 730755995d..a3afc79dcd 100644 --- a/gazelle/python/testdata/naming_convention/resolve_conflict/__main__.py +++ b/gazelle/python/testdata/naming_convention/resolve_conflict/__main__.py @@ -13,3 +13,4 @@ # limitations under the License. # For test purposes only. +import __init__ \ No newline at end of file diff --git a/gazelle/python/testdata/naming_convention/resolve_conflict/__test__.py b/gazelle/python/testdata/naming_convention/resolve_conflict/__test__.py index 730755995d..a3afc79dcd 100644 --- a/gazelle/python/testdata/naming_convention/resolve_conflict/__test__.py +++ b/gazelle/python/testdata/naming_convention/resolve_conflict/__test__.py @@ -13,3 +13,4 @@ # limitations under the License. # For test purposes only. +import __init__ \ No newline at end of file diff --git a/gazelle/python/testdata/python_target_with_test_in_name/real_test.py b/gazelle/python/testdata/python_target_with_test_in_name/real_test.py index 2f032112ef..e390866be3 100644 --- a/gazelle/python/testdata/python_target_with_test_in_name/real_test.py +++ b/gazelle/python/testdata/python_target_with_test_in_name/real_test.py @@ -13,5 +13,6 @@ # limitations under the License. import boto3 +import __init__ _ = boto3 diff --git a/gazelle/python/testdata/python_target_with_test_in_name/test_reality.py b/gazelle/python/testdata/python_target_with_test_in_name/test_reality.py index 730755995d..a3afc79dcd 100644 --- a/gazelle/python/testdata/python_target_with_test_in_name/test_reality.py +++ b/gazelle/python/testdata/python_target_with_test_in_name/test_reality.py @@ -13,3 +13,4 @@ # limitations under the License. # For test purposes only. +import __init__ \ No newline at end of file diff --git a/gazelle/python/testdata/sibling_imports/README.md b/gazelle/python/testdata/sibling_imports/README.md new file mode 100644 index 0000000000..e59be07634 --- /dev/null +++ b/gazelle/python/testdata/sibling_imports/README.md @@ -0,0 +1,3 @@ +# Sibling imports + +This test case asserts that imports from sibling modules are resolved correctly. It covers 3 different types of imports in `pkg/unit_test.py` \ No newline at end of file diff --git a/gazelle/python/testdata/sibling_imports/WORKSPACE b/gazelle/python/testdata/sibling_imports/WORKSPACE new file mode 100644 index 0000000000..faff6af87a --- /dev/null +++ b/gazelle/python/testdata/sibling_imports/WORKSPACE @@ -0,0 +1 @@ +# This is a Bazel workspace for the Gazelle test data. diff --git a/gazelle/python/testdata/sibling_imports/pkg/BUILD.in b/gazelle/python/testdata/sibling_imports/pkg/BUILD.in new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gazelle/python/testdata/sibling_imports/pkg/BUILD.out b/gazelle/python/testdata/sibling_imports/pkg/BUILD.out new file mode 100644 index 0000000000..edb40a8bcb --- /dev/null +++ b/gazelle/python/testdata/sibling_imports/pkg/BUILD.out @@ -0,0 +1,29 @@ +load("@rules_python//python:defs.bzl", "py_library", "py_test") + +py_library( + name = "pkg", + srcs = [ + "__init__.py", + "a.py", + "b.py", + ], + imports = [".."], + visibility = ["//:__subpackages__"], +) + +py_test( + name = "test_util", + srcs = ["test_util.py"], + imports = [".."], +) + +py_test( + name = "unit_test", + srcs = ["unit_test.py"], + imports = [".."], + deps = [ + ":pkg", + ":test_util", + ], +) + diff --git a/gazelle/python/testdata/sibling_imports/pkg/__init__.py b/gazelle/python/testdata/sibling_imports/pkg/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gazelle/python/testdata/sibling_imports/pkg/a.py b/gazelle/python/testdata/sibling_imports/pkg/a.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gazelle/python/testdata/sibling_imports/pkg/b.py b/gazelle/python/testdata/sibling_imports/pkg/b.py new file mode 100644 index 0000000000..7095bdcfb2 --- /dev/null +++ b/gazelle/python/testdata/sibling_imports/pkg/b.py @@ -0,0 +1,2 @@ +def run(): + pass \ No newline at end of file diff --git a/gazelle/python/testdata/sibling_imports/pkg/test_util.py b/gazelle/python/testdata/sibling_imports/pkg/test_util.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gazelle/python/testdata/sibling_imports/pkg/unit_test.py b/gazelle/python/testdata/sibling_imports/pkg/unit_test.py new file mode 100644 index 0000000000..a3218e2ec2 --- /dev/null +++ b/gazelle/python/testdata/sibling_imports/pkg/unit_test.py @@ -0,0 +1,3 @@ +import a +from b import run +import test_util \ No newline at end of file diff --git a/gazelle/python/testdata/sibling_imports/test.yaml b/gazelle/python/testdata/sibling_imports/test.yaml new file mode 100644 index 0000000000..ed97d539c0 --- /dev/null +++ b/gazelle/python/testdata/sibling_imports/test.yaml @@ -0,0 +1 @@ +--- diff --git a/gazelle/python/testdata/simple_binary_with_library/__main__.py b/gazelle/python/testdata/simple_binary_with_library/__main__.py index 730755995d..bc7ddf0a71 100644 --- a/gazelle/python/testdata/simple_binary_with_library/__main__.py +++ b/gazelle/python/testdata/simple_binary_with_library/__main__.py @@ -13,3 +13,4 @@ # limitations under the License. # For test purposes only. +import foo diff --git a/gazelle/python/testdata/subdir_sources/foo/has_main/__main__.py b/gazelle/python/testdata/subdir_sources/foo/has_main/__main__.py index 730755995d..bd0fe61faa 100644 --- a/gazelle/python/testdata/subdir_sources/foo/has_main/__main__.py +++ b/gazelle/python/testdata/subdir_sources/foo/has_main/__main__.py @@ -13,3 +13,4 @@ # limitations under the License. # For test purposes only. +import foo.has_main.python.my_module \ No newline at end of file diff --git a/gazelle/python/testdata/subdir_sources/foo/has_test/__test__.py b/gazelle/python/testdata/subdir_sources/foo/has_test/__test__.py index 730755995d..3c9ed1a1bd 100644 --- a/gazelle/python/testdata/subdir_sources/foo/has_test/__test__.py +++ b/gazelle/python/testdata/subdir_sources/foo/has_test/__test__.py @@ -13,3 +13,4 @@ # limitations under the License. # For test purposes only. +import foo.has_test.python.my_module \ No newline at end of file diff --git a/gazelle/python/testdata/with_third_party_requirements/BUILD.out b/gazelle/python/testdata/with_third_party_requirements/BUILD.out index 2da7f2bd86..2a97d8bc1e 100644 --- a/gazelle/python/testdata/with_third_party_requirements/BUILD.out +++ b/gazelle/python/testdata/with_third_party_requirements/BUILD.out @@ -20,5 +20,5 @@ py_binary( srcs = ["__main__.py"], main = "__main__.py", visibility = ["//:__subpackages__"], - deps = [":with_third_party_requirements"], + deps = ["@gazelle_python_test_baz//:pkg"], ) From 6054455341f4b309e5c07826cb152c1a59b872f8 Mon Sep 17 00:00:00 2001 From: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> Date: Wed, 1 Feb 2023 16:10:05 -0800 Subject: [PATCH 2/4] fix: add test for nested conftest Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> --- .../simple_test_with_conftest/bar/BUILD.in | 1 + .../simple_test_with_conftest/bar/BUILD.out | 30 +++++++++++++++++++ .../simple_test_with_conftest/bar/__init__.py | 17 +++++++++++ .../simple_test_with_conftest/bar/__test__.py | 26 ++++++++++++++++ .../simple_test_with_conftest/bar/bar.py | 17 +++++++++++ .../simple_test_with_conftest/bar/conftest.py | 13 ++++++++ 6 files changed, 104 insertions(+) create mode 100644 gazelle/python/testdata/simple_test_with_conftest/bar/BUILD.in create mode 100644 gazelle/python/testdata/simple_test_with_conftest/bar/BUILD.out create mode 100644 gazelle/python/testdata/simple_test_with_conftest/bar/__init__.py create mode 100644 gazelle/python/testdata/simple_test_with_conftest/bar/__test__.py create mode 100644 gazelle/python/testdata/simple_test_with_conftest/bar/bar.py create mode 100644 gazelle/python/testdata/simple_test_with_conftest/bar/conftest.py diff --git a/gazelle/python/testdata/simple_test_with_conftest/bar/BUILD.in b/gazelle/python/testdata/simple_test_with_conftest/bar/BUILD.in new file mode 100644 index 0000000000..3f2beb3147 --- /dev/null +++ b/gazelle/python/testdata/simple_test_with_conftest/bar/BUILD.in @@ -0,0 +1 @@ +load("@rules_python//python:defs.bzl", "py_library") diff --git a/gazelle/python/testdata/simple_test_with_conftest/bar/BUILD.out b/gazelle/python/testdata/simple_test_with_conftest/bar/BUILD.out new file mode 100644 index 0000000000..e42c4998b1 --- /dev/null +++ b/gazelle/python/testdata/simple_test_with_conftest/bar/BUILD.out @@ -0,0 +1,30 @@ +load("@rules_python//python:defs.bzl", "py_library", "py_test") + +py_library( + name = "bar", + srcs = [ + "__init__.py", + "bar.py", + ], + imports = [".."], + visibility = ["//:__subpackages__"], +) + +py_library( + name = "conftest", + testonly = True, + srcs = ["conftest.py"], + imports = [".."], + visibility = ["//:__subpackages__"], +) + +py_test( + name = "bar_test", + srcs = ["__test__.py"], + imports = [".."], + main = "__test__.py", + deps = [ + ":bar", + ":conftest", + ], +) diff --git a/gazelle/python/testdata/simple_test_with_conftest/bar/__init__.py b/gazelle/python/testdata/simple_test_with_conftest/bar/__init__.py new file mode 100644 index 0000000000..3f0275e179 --- /dev/null +++ b/gazelle/python/testdata/simple_test_with_conftest/bar/__init__.py @@ -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. + +from bar import bar + +_ = bar diff --git a/gazelle/python/testdata/simple_test_with_conftest/bar/__test__.py b/gazelle/python/testdata/simple_test_with_conftest/bar/__test__.py new file mode 100644 index 0000000000..00c4c28247 --- /dev/null +++ b/gazelle/python/testdata/simple_test_with_conftest/bar/__test__.py @@ -0,0 +1,26 @@ +# 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. + +import unittest + +from __init__ import bar + + +class BarTest(unittest.TestCase): + def test_bar(self): + self.assertEqual("bar", bar()) + + +if __name__ == "__main__": + unittest.main() diff --git a/gazelle/python/testdata/simple_test_with_conftest/bar/bar.py b/gazelle/python/testdata/simple_test_with_conftest/bar/bar.py new file mode 100644 index 0000000000..ba6a62db30 --- /dev/null +++ b/gazelle/python/testdata/simple_test_with_conftest/bar/bar.py @@ -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. + + +def bar(): + return "bar" diff --git a/gazelle/python/testdata/simple_test_with_conftest/bar/conftest.py b/gazelle/python/testdata/simple_test_with_conftest/bar/conftest.py new file mode 100644 index 0000000000..41010956cf --- /dev/null +++ b/gazelle/python/testdata/simple_test_with_conftest/bar/conftest.py @@ -0,0 +1,13 @@ +# 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. From ae8f71a6bb64df415e4ace123d21cb291b0951c8 Mon Sep 17 00:00:00 2001 From: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> Date: Wed, 1 Feb 2023 16:10:43 -0800 Subject: [PATCH 3/4] fix: conftest import for nested packages Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> --- gazelle/python/generate.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gazelle/python/generate.go b/gazelle/python/generate.go index 74e5f66509..f6ee73f8fb 100644 --- a/gazelle/python/generate.go +++ b/gazelle/python/generate.go @@ -366,7 +366,8 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes for _, pyTestTarget := range pyTestTargets { if conftest != nil { - pyTestTarget.addModuleDependency(module{Name: strings.TrimSuffix(conftestFilename, ".py")}) + conftestImport := importSpecFromSrc(pythonProjectRoot, args.Rel, conftestFilename).Imp + pyTestTarget.addModuleDependency(module{Name: conftestImport}) } pyTest := pyTestTarget.build() From ed580ddddc4b2ed07d50dd2b4cbe70474e9298ca Mon Sep 17 00:00:00 2001 From: Zhongpeng Lin Date: Thu, 2 Feb 2023 16:20:51 -0800 Subject: [PATCH 4/4] Collect all py file names in the same package (#1041) --- gazelle/python/generate.go | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/gazelle/python/generate.go b/gazelle/python/generate.go index f6ee73f8fb..3d63124028 100644 --- a/gazelle/python/generate.go +++ b/gazelle/python/generate.go @@ -76,6 +76,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes pyLibraryFilenames := treeset.NewWith(godsutils.StringComparator) pyTestFilenames := treeset.NewWith(godsutils.StringComparator) + pyFileNames := treeset.NewWith(godsutils.StringComparator) // hasPyBinary controls whether a py_binary target should be generated for // this package or not. @@ -92,16 +93,19 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes continue } ext := filepath.Ext(f) - if !hasPyBinary && f == pyBinaryEntrypointFilename { - hasPyBinary = true - } else if !hasPyTestEntryPointFile && f == pyTestEntrypointFilename { - hasPyTestEntryPointFile = true - } else if f == conftestFilename { - hasConftestFile = true - } else if strings.HasSuffix(f, "_test.py") || (strings.HasPrefix(f, "test_") && ext == ".py") { - pyTestFilenames.Add(f) - } else if ext == ".py" { - pyLibraryFilenames.Add(f) + if ext == ".py" { + pyFileNames.Add(f) + if !hasPyBinary && f == pyBinaryEntrypointFilename { + hasPyBinary = true + } else if !hasPyTestEntryPointFile && f == pyTestEntrypointFilename { + hasPyTestEntryPointFile = true + } else if f == conftestFilename { + hasConftestFile = true + } else if strings.HasSuffix(f, "_test.py") || strings.HasPrefix(f, "test_") { + pyTestFilenames.Add(f) + } else { + pyLibraryFilenames.Add(f) + } } } @@ -223,7 +227,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes } } - pyLibrary = newTargetBuilder(pyLibraryKind, pyLibraryTargetName, pythonProjectRoot, args.Rel, pyLibraryFilenames.Union(pyTestFilenames)). + pyLibrary = newTargetBuilder(pyLibraryKind, pyLibraryTargetName, pythonProjectRoot, args.Rel, pyFileNames). addVisibility(visibility). addSrcs(pyLibraryFilenames). addModuleDependencies(deps). @@ -259,7 +263,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes } } - pyBinaryTarget := newTargetBuilder(pyBinaryKind, pyBinaryTargetName, pythonProjectRoot, args.Rel, pyLibraryFilenames.Union(pyTestFilenames)). + pyBinaryTarget := newTargetBuilder(pyBinaryKind, pyBinaryTargetName, pythonProjectRoot, args.Rel, pyFileNames). setMain(pyBinaryEntrypointFilename). addVisibility(visibility). addSrc(pyBinaryEntrypointFilename). @@ -295,7 +299,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes } } - conftestTarget := newTargetBuilder(pyLibraryKind, conftestTargetname, pythonProjectRoot, args.Rel, pyLibraryFilenames.Union(pyTestFilenames)). + conftestTarget := newTargetBuilder(pyLibraryKind, conftestTargetname, pythonProjectRoot, args.Rel, pyFileNames). addSrc(conftestFilename). addModuleDependencies(deps). addVisibility(visibility). @@ -330,7 +334,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes } } } - return newTargetBuilder(pyTestKind, pyTestTargetName, pythonProjectRoot, args.Rel, pyLibraryFilenames.Union(pyTestFilenames)). + return newTargetBuilder(pyTestKind, pyTestTargetName, pythonProjectRoot, args.Rel, pyFileNames). addSrcs(srcs). addModuleDependencies(deps). generateImportsAttribute() @@ -366,8 +370,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes for _, pyTestTarget := range pyTestTargets { if conftest != nil { - conftestImport := importSpecFromSrc(pythonProjectRoot, args.Rel, conftestFilename).Imp - pyTestTarget.addModuleDependency(module{Name: conftestImport}) + pyTestTarget.addModuleDependency(module{Name: strings.TrimSuffix(conftestFilename, ".py")}) } pyTest := pyTestTarget.build()