Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ END_UNRELEASED_TEMPLATE
* (toolchain) Python 3.13 now references 3.13.5
* (gazelle) Switched back to smacker/go-tree-sitter, fixing
[#2630](https://github.com/bazel-contrib/rules_python/issues/2630)
* (gazelle) Cleanup multi-line python imports modules

{#v0-0-0-fixed}
### Fixed
Expand Down
10 changes: 10 additions & 0 deletions gazelle/python/file_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,14 @@ func parseImportStatement(node *sitter.Node, code []byte) (Module, bool) {
return Module{}, false
}

// cleanImportString removes backslashes and all whitespace from the string.
func cleanImportString(s string) string {
s = strings.ReplaceAll(s, "\\", "")
s = strings.ReplaceAll(s, " ", "")
s = strings.ReplaceAll(s, "\n", "")
return s
}

// parseImportStatements parses a node for import statements, returning true if the node is
// an import statement. It updates FileParser.output.Modules with the `module` that the
// import represents.
Expand All @@ -154,6 +162,7 @@ func (p *FileParser) parseImportStatements(node *sitter.Node) bool {
if !ok {
continue
}
m.From = cleanImportString(m.From)
m.Filepath = p.relFilepath
m.TypeCheckingOnly = p.inTypeCheckingBlock
if strings.HasPrefix(m.Name, ".") {
Expand All @@ -163,6 +172,7 @@ func (p *FileParser) parseImportStatements(node *sitter.Node) bool {
}
} else if node.Type() == sitterNodeTypeImportFromStatement {
from := node.Child(1).Content(p.code)
from = cleanImportString(from)
// If the import is from the current package, we don't need to add it to the modules i.e. from . import Class1.
// If the import is from a different relative package i.e. from .package1 import foo, we need to add it to the modules.
if from == "." {
Expand Down
29 changes: 29 additions & 0 deletions gazelle/python/file_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,32 @@ def example_function():
}
}
}

func TestParseImportStatements_MultilineWithBackslashAndWhitespace(t *testing.T) {
p := NewFileParser()
code := []byte(`from foo.bar.\
baz import (
Something,
AnotherThing
)
`)
p.SetCodeAndFile(code, "", "test.py")
output, err := p.Parse(context.Background())
assert.NoError(t, err)
// Should parse as: from foo.bar.baz import Something, AnotherThing
expected := []Module{
{
Name: "foo.bar.baz.Something",
LineNumber: 3,
Filepath: "test.py",
From: "foo.bar.baz",
},
{
Name: "foo.bar.baz.AnotherThing",
LineNumber: 4,
Filepath: "test.py",
From: "foo.bar.baz",
},
}
assert.Equal(t, expected, output.Modules)
}