Skip to content

Commit 57f819c

Browse files
authored
fix(gazelle) Fix dependency added as both deps and pyi_deps (bazel-contrib#3036)
Fix an issue in bazel-contrib#3014 where a dependency may end up being added in both `deps` and `pyi_deps`, in cases where the regular and the type-checking import refer to different python modules on the same `py_library` target. Other cases are already deduplicated earlier on, but this case can only be deduplicated in the resolve phase. (No new changelog entry since this is a fix to an unreleased feature that is already in the changelog)
1 parent 7719529 commit 57f819c

File tree

13 files changed

+49
-9
lines changed

13 files changed

+49
-9
lines changed

gazelle/python/resolve.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,16 @@ func (py *Resolver) Embeds(r *rule.Rule, from label.Label) []label.Label {
124124
}
125125

126126
// addDependency adds a dependency to either the regular deps or pyiDeps set based on
127-
// whether the module is type-checking only.
128-
func addDependency(dep string, mod Module, deps, pyiDeps *treeset.Set) {
129-
if mod.TypeCheckingOnly {
130-
pyiDeps.Add(dep)
127+
// whether the module is type-checking only. If a module is added as both
128+
// non-type-checking and type-checking, it should end up in deps and not pyiDeps.
129+
func addDependency(dep string, typeCheckingOnly bool, deps, pyiDeps *treeset.Set) {
130+
if typeCheckingOnly {
131+
if !deps.Contains(dep) {
132+
pyiDeps.Add(dep)
133+
}
131134
} else {
132135
deps.Add(dep)
136+
pyiDeps.Remove(dep)
133137
}
134138
}
135139

@@ -240,7 +244,7 @@ func (py *Resolver) Resolve(
240244
override.Repo = ""
241245
}
242246
dep := override.Rel(from.Repo, from.Pkg).String()
243-
addDependency(dep, mod, deps, pyiDeps)
247+
addDependency(dep, mod.TypeCheckingOnly, deps, pyiDeps)
244248
if explainDependency == dep {
245249
log.Printf("Explaining dependency (%s): "+
246250
"in the target %q, the file %q imports %q at line %d, "+
@@ -251,7 +255,7 @@ func (py *Resolver) Resolve(
251255
}
252256
} else {
253257
if dep, distributionName, ok := cfg.FindThirdPartyDependency(moduleName); ok {
254-
addDependency(dep, mod, deps, pyiDeps)
258+
addDependency(dep, mod.TypeCheckingOnly, deps, pyiDeps)
255259
// Add the type and stub dependencies if they exist.
256260
modules := []string{
257261
fmt.Sprintf("%s_stubs", strings.ToLower(distributionName)),
@@ -261,8 +265,8 @@ func (py *Resolver) Resolve(
261265
}
262266
for _, module := range modules {
263267
if dep, _, ok := cfg.FindThirdPartyDependency(module); ok {
264-
// Type stub packages always go to pyiDeps
265-
pyiDeps.Add(dep)
268+
// Type stub packages are added as type-checking only.
269+
addDependency(dep, true, deps, pyiDeps)
266270
}
267271
}
268272
if explainDependency == dep {
@@ -321,7 +325,7 @@ func (py *Resolver) Resolve(
321325
}
322326
matchLabel := filteredMatches[0].Label.Rel(from.Repo, from.Pkg)
323327
dep := matchLabel.String()
324-
addDependency(dep, mod, deps, pyiDeps)
328+
addDependency(dep, mod.TypeCheckingOnly, deps, pyiDeps)
325329
if explainDependency == dep {
326330
log.Printf("Explaining dependency (%s): "+
327331
"in the target %q, the file %q imports %q at line %d, "+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# gazelle:python_generation_mode package
2+
# gazelle:python_generate_pyi_deps true
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# gazelle:python_generation_mode package
2+
# gazelle:python_generate_pyi_deps true
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Overlapping deps and pyi_deps across packages
2+
3+
This test reproduces a case where a dependency may be added to both `deps` and
4+
`pyi_deps`. Package `b` imports `a.foo` normally and imports `a.bar` as a
5+
type-checking only import. The dependency on package `a` should appear only in
6+
`deps` (and not `pyi_deps`) of package `b`.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
workspace(name = "gazelle_python_test")

gazelle/python/testdata/type_checking_imports_across_packages/a/BUILD.in

Whitespace-only changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
load("@rules_python//python:defs.bzl", "py_library")
2+
3+
py_library(
4+
name = "a",
5+
srcs = [
6+
"bar.py",
7+
"foo.py",
8+
],
9+
visibility = ["//:__subpackages__"],
10+
)

gazelle/python/testdata/type_checking_imports_across_packages/a/bar.py

Whitespace-only changes.

gazelle/python/testdata/type_checking_imports_across_packages/a/foo.py

Whitespace-only changes.

gazelle/python/testdata/type_checking_imports_across_packages/b/BUILD.in

Whitespace-only changes.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy