diff --git a/crates/ruff/resources/test/fixtures/isort/required_imports/comments_and_newlines.py b/crates/ruff/resources/test/fixtures/isort/required_imports/comments_and_newlines.py new file mode 100644 index 0000000000000..5d2462ab9f966 --- /dev/null +++ b/crates/ruff/resources/test/fixtures/isort/required_imports/comments_and_newlines.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 +# A copyright notice could go here + +# A linter directive could go here + +x = 1 diff --git a/crates/ruff/src/importer/insertion.rs b/crates/ruff/src/importer/insertion.rs index 311a1be96791c..92c335a2df582 100644 --- a/crates/ruff/src/importer/insertion.rs +++ b/crates/ruff/src/importer/insertion.rs @@ -67,9 +67,13 @@ impl<'a> Insertion<'a> { TextSize::default() }; - // Skip over commented lines. + // Skip over commented lines, with whitespace separation. for line in UniversalNewlineIterator::with_offset(locator.after(location), location) { - if line.trim_whitespace_start().starts_with('#') { + let trimmed_line = line.trim_whitespace_start(); + if trimmed_line.is_empty() { + continue; + } + if trimmed_line.starts_with('#') { location = line.full_end(); } else { break; diff --git a/crates/ruff/src/rules/isort/mod.rs b/crates/ruff/src/rules/isort/mod.rs index eed06c0e3d4d5..c8780dd26d6c8 100644 --- a/crates/ruff/src/rules/isort/mod.rs +++ b/crates/ruff/src/rules/isort/mod.rs @@ -762,6 +762,7 @@ mod tests { } #[test_case(Path::new("comment.py"))] + #[test_case(Path::new("comments_and_newlines.py"))] #[test_case(Path::new("docstring.py"))] #[test_case(Path::new("docstring.pyi"))] #[test_case(Path::new("docstring_only.py"))] @@ -791,6 +792,7 @@ mod tests { } #[test_case(Path::new("comment.py"))] + #[test_case(Path::new("comments_and_newlines.py"))] #[test_case(Path::new("docstring.py"))] #[test_case(Path::new("docstring.pyi"))] #[test_case(Path::new("docstring_only.py"))] diff --git a/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__required_import_comments_and_newlines.py.snap b/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__required_import_comments_and_newlines.py.snap new file mode 100644 index 0000000000000..107c3ef147d64 --- /dev/null +++ b/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__required_import_comments_and_newlines.py.snap @@ -0,0 +1,20 @@ +--- +source: crates/ruff/src/rules/isort/mod.rs +--- +comments_and_newlines.py:1:1: I002 [*] Missing required import: `from __future__ import annotations` + | +1 | #!/usr/bin/env python3 + | I002 +2 | # A copyright notice could go here + | + = help: Insert required import: `from future import annotations` + +ℹ Fix +2 2 | # A copyright notice could go here +3 3 | +4 4 | # A linter directive could go here + 5 |+from __future__ import annotations +5 6 | +6 7 | x = 1 + + diff --git a/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__required_import_with_alias_comments_and_newlines.py.snap b/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__required_import_with_alias_comments_and_newlines.py.snap new file mode 100644 index 0000000000000..a9ea7adf2e3bd --- /dev/null +++ b/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__required_import_with_alias_comments_and_newlines.py.snap @@ -0,0 +1,20 @@ +--- +source: crates/ruff/src/rules/isort/mod.rs +--- +comments_and_newlines.py:1:1: I002 [*] Missing required import: `from __future__ import annotations as _annotations` + | +1 | #!/usr/bin/env python3 + | I002 +2 | # A copyright notice could go here + | + = help: Insert required import: `from future import annotations as _annotations` + +ℹ Fix +2 2 | # A copyright notice could go here +3 3 | +4 4 | # A linter directive could go here + 5 |+from __future__ import annotations as _annotations +5 6 | +6 7 | x = 1 + +