diff --git a/crates/ruff/resources/test/fixtures/isort/skip_file.py b/crates/ruff/resources/test/fixtures/isort/isort_skip_file.py similarity index 100% rename from crates/ruff/resources/test/fixtures/isort/skip_file.py rename to crates/ruff/resources/test/fixtures/isort/isort_skip_file.py diff --git a/crates/ruff/resources/test/fixtures/isort/ruff_skip_file.py b/crates/ruff/resources/test/fixtures/isort/ruff_skip_file.py new file mode 100644 index 0000000000..dd310782ad --- /dev/null +++ b/crates/ruff/resources/test/fixtures/isort/ruff_skip_file.py @@ -0,0 +1,10 @@ +# ruff: isort: skip_file +import e +import f + +# isort: split + +import a +import b +import c +import d diff --git a/crates/ruff/resources/test/fixtures/isort/skip.py b/crates/ruff/resources/test/fixtures/isort/skip.py index dbc836c643..5cf668879b 100644 --- a/crates/ruff/resources/test/fixtures/isort/skip.py +++ b/crates/ruff/resources/test/fixtures/isort/skip.py @@ -6,6 +6,14 @@ def f(): # isort: on +def f(): + # ruff: isort: off + import sys + import os + import collections + # ruff: isort: on + + def f(): import sys import os # isort: skip diff --git a/crates/ruff/src/directives.rs b/crates/ruff/src/directives.rs index ad3ab6ec11..b773ef227f 100644 --- a/crates/ruff/src/directives.rs +++ b/crates/ruff/src/directives.rs @@ -107,15 +107,21 @@ pub fn extract_isort_directives(lxr: &[LexResult]) -> IsortDirectives { // omit a space after the colon. The remaining action comments are // required to include the space, and must appear on their own lines. let comment_text = comment_text.trim_end(); - if comment_text == "# isort: split" { + if matches!(comment_text, "# isort: split" | "# ruff: isort: split") { splits.push(start.row()); - } else if comment_text == "# isort: skip_file" || comment_text == "# isort:skip_file" { + } else if matches!( + comment_text, + "# isort: skip_file" + | "# isort:skip_file" + | "# ruff: isort: skip_file" + | "# ruff: isort:skip_file" + ) { return IsortDirectives { skip_file: true, ..IsortDirectives::default() }; } else if off.is_some() { - if comment_text == "# isort: on" { + if comment_text == "# isort: on" || comment_text == "# ruff: isort: on" { if let Some(start) = off { for row in start.row() + 1..=end.row() { exclusions.insert(row); @@ -126,7 +132,7 @@ pub fn extract_isort_directives(lxr: &[LexResult]) -> IsortDirectives { } else { if comment_text.contains("isort: skip") || comment_text.contains("isort:skip") { exclusions.insert(start.row()); - } else if comment_text == "# isort: off" { + } else if comment_text == "# isort: off" || comment_text == "# ruff: isort: off" { off = Some(start); } } diff --git a/crates/ruff/src/rules/isort/mod.rs b/crates/ruff/src/rules/isort/mod.rs index d34cc0520a..bbbc0f7a6e 100644 --- a/crates/ruff/src/rules/isort/mod.rs +++ b/crates/ruff/src/rules/isort/mod.rs @@ -373,6 +373,7 @@ mod tests { #[test_case(Path::new("inline_comments.py"))] #[test_case(Path::new("insert_empty_lines.py"))] #[test_case(Path::new("insert_empty_lines.pyi"))] + #[test_case(Path::new("isort_skip_file.py"))] #[test_case(Path::new("leading_prefix.py"))] #[test_case(Path::new("magic_trailing_comma.py"))] #[test_case(Path::new("natural_order.py"))] @@ -391,12 +392,12 @@ mod tests { #[test_case(Path::new("preserve_tabs_2.py"))] #[test_case(Path::new("relative_imports_order.py"))] #[test_case(Path::new("reorder_within_section.py"))] + #[test_case(Path::new("ruff_skip_file.py"))] #[test_case(Path::new("separate_first_party_imports.py"))] #[test_case(Path::new("separate_future_imports.py"))] #[test_case(Path::new("separate_local_folder_imports.py"))] #[test_case(Path::new("separate_third_party_imports.py"))] #[test_case(Path::new("skip.py"))] - #[test_case(Path::new("skip_file.py"))] #[test_case(Path::new("sort_similar_imports.py"))] #[test_case(Path::new("split.py"))] #[test_case(Path::new("star_before_others.py"))] diff --git a/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__isort_skip_file.py.snap b/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__isort_skip_file.py.snap new file mode 100644 index 0000000000..caa019cc6c --- /dev/null +++ b/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__isort_skip_file.py.snap @@ -0,0 +1,6 @@ +--- +source: crates/ruff/src/rules/isort/mod.rs +expression: diagnostics +--- +[] + diff --git a/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__ruff_skip_file.py.snap b/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__ruff_skip_file.py.snap new file mode 100644 index 0000000000..caa019cc6c --- /dev/null +++ b/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__ruff_skip_file.py.snap @@ -0,0 +1,6 @@ +--- +source: crates/ruff/src/rules/isort/mod.rs +expression: diagnostics +--- +[] + diff --git a/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__skip.py.snap b/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__skip.py.snap index 6660926e53..98ba47763b 100644 --- a/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__skip.py.snap +++ b/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__skip.py.snap @@ -8,18 +8,18 @@ expression: diagnostics suggestion: Organize imports fixable: true location: - row: 12 + row: 20 column: 0 end_location: - row: 14 + row: 22 column: 0 fix: content: " import abc\n import collections\n" location: - row: 12 + row: 20 column: 0 end_location: - row: 14 + row: 22 column: 0 parent: ~ - kind: @@ -28,18 +28,18 @@ expression: diagnostics suggestion: Organize imports fixable: true location: - row: 19 + row: 27 column: 0 end_location: - row: 21 + row: 29 column: 0 fix: content: " import abc\n import collections\n" location: - row: 19 + row: 27 column: 0 end_location: - row: 21 + row: 29 column: 0 parent: ~ diff --git a/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__skip_file.py.snap b/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__skip_file.py.snap deleted file mode 100644 index 40d8799b10..0000000000 --- a/crates/ruff/src/rules/isort/snapshots/ruff__rules__isort__tests__skip_file.py.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: src/rules/isort/mod.rs -expression: diagnostics ---- -[] - diff --git a/docs/configuration.md b/docs/configuration.md index 5710074bb5..d855e44393 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -418,12 +418,17 @@ automatically add `noqa` directives to all failing lines, with the appropriate r ### Action comments -Ruff respects `isort`'s [action comments](https://pycqa.github.io/isort/docs/configuration/action_comments.html) +Ruff respects isort's [action comments](https://pycqa.github.io/isort/docs/configuration/action_comments.html) (`# isort: skip_file`, `# isort: on`, `# isort: off`, `# isort: skip`, and `# isort: split`), which enable selectively enabling and disabling import sorting for blocks of code and other inline configuration. -See the [`isort` documentation](https://pycqa.github.io/isort/docs/configuration/action_comments.html) +Ruff will also respect variants of these action comments with a `# ruff:` prefix +(e.g., `# ruff: isort: skip_file`, `# ruff: isort: on`, and so on). These variants more clearly +convey that the action comment is intended for Ruff, but are functionally equivalent to the +isort variants. + +See the [isort documentation](https://pycqa.github.io/isort/docs/configuration/action_comments.html) for more. ## Exit codes