diff --git a/crates/ruff_linter/resources/test/fixtures/isort/required_imports/docstring_with_multiple_continuations.py b/crates/ruff_linter/resources/test/fixtures/isort/required_imports/docstring_with_multiple_continuations.py new file mode 100644 index 0000000000..d98a63c3be --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/isort/required_imports/docstring_with_multiple_continuations.py @@ -0,0 +1,4 @@ +"""Hello, world!"""\ +\ + +x = 1; y = 2 diff --git a/crates/ruff_linter/src/importer/insertion.rs b/crates/ruff_linter/src/importer/insertion.rs index fbef92894e..69c9afbe6c 100644 --- a/crates/ruff_linter/src/importer/insertion.rs +++ b/crates/ruff_linter/src/importer/insertion.rs @@ -63,9 +63,9 @@ impl<'a> Insertion<'a> { return Insertion::inline(" ", location.add(offset).add(TextSize::of(';')), ";"); } - // If the first token after the docstring is a continuation character (i.e. "\"), advance - // an additional row to prevent inserting in the same logical line. - if match_continuation(locator.after(location)).is_some() { + // While the first token after the docstring is a continuation character (i.e. "\"), advance + // additional rows to prevent inserting in the same logical line. + while match_continuation(locator.after(location)).is_some() { location = locator.full_line_end(location); } @@ -379,6 +379,17 @@ mod tests { Insertion::own_line("", TextSize::from(22), "\n") ); + let contents = r#" +"""Hello, world!"""\ +\ + +"# + .trim_start(); + assert_eq!( + insert(contents)?, + Insertion::own_line("", TextSize::from(24), "\n") + ); + let contents = r" x = 1 " diff --git a/crates/ruff_linter/src/rules/isort/mod.rs b/crates/ruff_linter/src/rules/isort/mod.rs index 0ad92d763b..6f18ce05b8 100644 --- a/crates/ruff_linter/src/rules/isort/mod.rs +++ b/crates/ruff_linter/src/rules/isort/mod.rs @@ -797,6 +797,7 @@ mod tests { #[test_case(Path::new("docstring_followed_by_continuation.py"))] #[test_case(Path::new("docstring_only.py"))] #[test_case(Path::new("docstring_with_continuation.py"))] + #[test_case(Path::new("docstring_with_multiple_continuations.py"))] #[test_case(Path::new("docstring_with_semicolon.py"))] #[test_case(Path::new("empty.py"))] #[test_case(Path::new("existing_import.py"))] @@ -832,6 +833,7 @@ mod tests { #[test_case(Path::new("docstring_followed_by_continuation.py"))] #[test_case(Path::new("docstring_only.py"))] #[test_case(Path::new("docstring_with_continuation.py"))] + #[test_case(Path::new("docstring_with_multiple_continuations.py"))] #[test_case(Path::new("docstring_with_semicolon.py"))] #[test_case(Path::new("empty.py"))] #[test_case(Path::new("existing_import.py"))] diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__required_import_docstring_with_multiple_continuations.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__required_import_docstring_with_multiple_continuations.py.snap new file mode 100644 index 0000000000..3c438a2ed8 --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__required_import_docstring_with_multiple_continuations.py.snap @@ -0,0 +1,13 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- +I002 [*] Missing required import: `from __future__ import annotations` +--> docstring_with_multiple_continuations.py:1:1 +help: Insert required import: `from __future__ import annotations` + +ℹ Safe fix +1 1 | """Hello, world!"""\ +2 2 | \ +3 3 | + 4 |+from __future__ import annotations +4 5 | x = 1; y = 2 diff --git a/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__required_import_with_alias_docstring_with_multiple_continuations.py.snap b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__required_import_with_alias_docstring_with_multiple_continuations.py.snap new file mode 100644 index 0000000000..ce1f0d64ba --- /dev/null +++ b/crates/ruff_linter/src/rules/isort/snapshots/ruff_linter__rules__isort__tests__required_import_with_alias_docstring_with_multiple_continuations.py.snap @@ -0,0 +1,13 @@ +--- +source: crates/ruff_linter/src/rules/isort/mod.rs +--- +I002 [*] Missing required import: `from __future__ import annotations as _annotations` +--> docstring_with_multiple_continuations.py:1:1 +help: Insert required import: `from __future__ import annotations as _annotations` + +ℹ Safe fix +1 1 | """Hello, world!"""\ +2 2 | \ +3 3 | + 4 |+from __future__ import annotations as _annotations +4 5 | x = 1; y = 2