Skip to content

Commit

Permalink
Include alias when formatting import-from structs (astral-sh#5786)
Browse files Browse the repository at this point in the history
## Summary

When required-imports is set with the syntax from ... import ... as ...,
autofix I002 is failing

## Test Plan

Reuse the same python files as
`crates/ruff/src/rules/isort/mod.rs:required_import` test.
  • Loading branch information
guillaumeLepape authored and evanrittenhouse committed Jul 19, 2023
1 parent 1777683 commit 7d4b9e4
Show file tree
Hide file tree
Showing 12 changed files with 171 additions and 0 deletions.
29 changes: 29 additions & 0 deletions crates/ruff/src/rules/isort/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,35 @@ mod tests {
Ok(())
}

#[test_case(Path::new("comment.py"))]
#[test_case(Path::new("docstring.py"))]
#[test_case(Path::new("docstring.pyi"))]
#[test_case(Path::new("docstring_only.py"))]
#[test_case(Path::new("docstring_with_continuation.py"))]
#[test_case(Path::new("docstring_with_semicolon.py"))]
#[test_case(Path::new("empty.py"))]
#[test_case(Path::new("existing_import.py"))]
#[test_case(Path::new("multiline_docstring.py"))]
#[test_case(Path::new("off.py"))]
fn required_import_with_alias(path: &Path) -> Result<()> {
let snapshot = format!("required_import_with_alias_{}", path.to_string_lossy());
let diagnostics = test_path(
Path::new("isort/required_imports").join(path).as_path(),
&Settings {
src: vec![test_resource_path("fixtures/isort")],
isort: super::settings::Settings {
required_imports: BTreeSet::from([
"from __future__ import annotations as _annotations".to_string(),
]),
..super::settings::Settings::default()
},
..Settings::for_rule(Rule::MissingRequiredImport)
},
)?;
assert_messages!(snapshot, diagnostics);
Ok(())
}

#[test_case(Path::new("docstring.py"))]
#[test_case(Path::new("docstring.pyi"))]
#[test_case(Path::new("docstring_only.py"))]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
source: crates/ruff/src/rules/isort/mod.rs
---
comment.py:1:1: I002 [*] Missing required import: `from __future__ import annotations as _annotations`
|
1 | #!/usr/bin/env python3
| I002
2 |
3 | x = 1
|
= help: Insert required import: `from future import annotations as _annotations`

Fix
1 1 | #!/usr/bin/env python3
2 |+from __future__ import annotations as _annotations
2 3 |
3 4 | x = 1


Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
source: crates/ruff/src/rules/isort/mod.rs
---
docstring.py:1:1: I002 [*] Missing required import: `from __future__ import annotations as _annotations`
|
1 | """Hello, world!"""
| I002
2 |
3 | x = 1
|
= help: Insert required import: `from future import annotations as _annotations`

Fix
1 1 | """Hello, world!"""
2 |+from __future__ import annotations as _annotations
2 3 |
3 4 | x = 1


Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
source: crates/ruff/src/rules/isort/mod.rs
---

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
source: crates/ruff/src/rules/isort/mod.rs
---

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
source: crates/ruff/src/rules/isort/mod.rs
---
docstring_with_continuation.py:1:1: I002 [*] Missing required import: `from __future__ import annotations as _annotations`
|
1 | """Hello, world!"""; x = \
| I002
2 | 1; y = 2
|
= help: Insert required import: `from future import annotations as _annotations`

Fix
1 |-"""Hello, world!"""; x = \
1 |+"""Hello, world!"""; from __future__ import annotations as _annotations; x = \
2 2 | 1; y = 2


Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
source: crates/ruff/src/rules/isort/mod.rs
---
docstring_with_semicolon.py:1:1: I002 [*] Missing required import: `from __future__ import annotations as _annotations`
|
1 | """Hello, world!"""; x = 1
| I002
|
= help: Insert required import: `from future import annotations as _annotations`

Fix
1 |-"""Hello, world!"""; x = 1
1 |+"""Hello, world!"""; from __future__ import annotations as _annotations; x = 1


Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
source: crates/ruff/src/rules/isort/mod.rs
---

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
source: crates/ruff/src/rules/isort/mod.rs
---
existing_import.py:1:1: I002 [*] Missing required import: `from __future__ import annotations as _annotations`
|
1 | from __future__ import generator_stop
| I002
2 | import os
|
= help: Insert required import: `from future import annotations as _annotations`

Fix
1 |+from __future__ import annotations as _annotations
1 2 | from __future__ import generator_stop
2 3 | import os


Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
source: crates/ruff/src/rules/isort/mod.rs
---
multiline_docstring.py:1:1: I002 [*] Missing required import: `from __future__ import annotations as _annotations`
|
1 | """a
| I002
2 | b"""
3 | # b
|
= help: Insert required import: `from future import annotations as _annotations`

Fix
1 1 | """a
2 2 | b"""
3 3 | # b
4 |+from __future__ import annotations as _annotations
4 5 | import os


Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
source: crates/ruff/src/rules/isort/mod.rs
---
off.py:1:1: I002 [*] Missing required import: `from __future__ import annotations as _annotations`
|
1 | # isort: off
| I002
2 |
3 | x = 1
|
= help: Insert required import: `from future import annotations as _annotations`

Fix
1 1 | # isort: off
2 |+from __future__ import annotations as _annotations
2 3 |
3 4 | x = 1
4 5 | # isort: on


3 changes: 3 additions & 0 deletions crates/ruff_python_ast/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ impl std::fmt::Display for ImportFrom<'_> {
write!(f, "{module}")?;
}
write!(f, " import {}", self.name.name)?;
if let Some(as_name) = self.name.as_name {
write!(f, " as {as_name}")?;
}
Ok(())
}
}
Expand Down

0 comments on commit 7d4b9e4

Please sign in to comment.