Skip to content

Commit 74a1e1d

Browse files
soundsonacidAlexWaygood
authored andcommitted
[pylint] Handle empty comments after line continuation (PLR2044) (#19405)
fixes #19326
1 parent c24ec56 commit 74a1e1d

5 files changed

Lines changed: 55 additions & 3 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#
2+
x = 0 \
3+
#
4+
+1
5+
print(x)

crates/ruff_linter/src/checkers/tokens.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub(crate) fn check_tokens(
5858
}
5959

6060
if context.is_rule_enabled(Rule::EmptyComment) {
61-
pylint::rules::empty_comments(context, comment_ranges, locator);
61+
pylint::rules::empty_comments(context, comment_ranges, locator, indexer);
6262
}
6363

6464
if context.is_rule_enabled(Rule::AmbiguousUnicodeCharacterComment) {

crates/ruff_linter/src/rules/pylint/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ mod tests {
4848
#[test_case(Rule::ComparisonWithItself, Path::new("comparison_with_itself.py"))]
4949
#[test_case(Rule::EqWithoutHash, Path::new("eq_without_hash.py"))]
5050
#[test_case(Rule::EmptyComment, Path::new("empty_comment.py"))]
51+
#[test_case(Rule::EmptyComment, Path::new("empty_comment_line_continuation.py"))]
5152
#[test_case(Rule::ManualFromImport, Path::new("import_aliasing.py"))]
5253
#[test_case(Rule::IfStmtMinMax, Path::new("if_stmt_min_max.py"))]
5354
#[test_case(Rule::SingleStringSlots, Path::new("single_string_slots.py"))]

crates/ruff_linter/src/rules/pylint/rules/empty_comment.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use ruff_macros::{ViolationMetadata, derive_message_formats};
2+
use ruff_python_index::Indexer;
23
use ruff_python_trivia::{CommentRanges, is_python_whitespace};
34
use ruff_source_file::LineRanges;
45
use ruff_text_size::{TextRange, TextSize};
@@ -49,6 +50,7 @@ pub(crate) fn empty_comments(
4950
context: &LintContext,
5051
comment_ranges: &CommentRanges,
5152
locator: &Locator,
53+
indexer: &Indexer,
5254
) {
5355
let block_comments = comment_ranges.block_comments(locator.contents());
5456

@@ -59,12 +61,12 @@ pub(crate) fn empty_comments(
5961
}
6062

6163
// If the line contains an empty comment, add a diagnostic.
62-
empty_comment(context, range, locator);
64+
empty_comment(context, range, locator, indexer);
6365
}
6466
}
6567

6668
/// Return a [`Diagnostic`] if the comment at the given [`TextRange`] is empty.
67-
fn empty_comment(context: &LintContext, range: TextRange, locator: &Locator) {
69+
fn empty_comment(context: &LintContext, range: TextRange, locator: &Locator, indexer: &Indexer) {
6870
// Check: is the comment empty?
6971
if !locator
7072
.slice(range)
@@ -95,12 +97,20 @@ fn empty_comment(context: &LintContext, range: TextRange, locator: &Locator) {
9597
}
9698
});
9799

100+
// If there is no character preceding the comment, this comment must be on its own physical line.
101+
// If there is a line preceding the empty comment's line, check if it ends in a line continuation character. (`\`)
102+
let is_on_same_logical_line = indexer
103+
.preceded_by_continuations(first_hash_col, locator.contents())
104+
.is_some();
105+
98106
if let Some(mut diagnostic) = context
99107
.report_diagnostic_if_enabled(EmptyComment, TextRange::new(first_hash_col, line.end()))
100108
{
101109
diagnostic.set_fix(Fix::safe_edit(
102110
if let Some(deletion_start_col) = deletion_start_col {
103111
Edit::deletion(line.start() + deletion_start_col, line.end())
112+
} else if is_on_same_logical_line {
113+
Edit::deletion(first_hash_col, line.end())
104114
} else {
105115
Edit::range_deletion(locator.full_line_range(first_hash_col))
106116
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
source: crates/ruff_linter/src/rules/pylint/mod.rs
3+
---
4+
empty_comment_line_continuation.py:1:1: PLR2044 [*] Line with empty comment
5+
|
6+
1 | #
7+
| ^ PLR2044
8+
2 | x = 0 \
9+
3 | #
10+
|
11+
= help: Delete the empty comment
12+
13+
Safe fix
14+
1 |-#
15+
2 1 | x = 0 \
16+
3 2 | #
17+
4 3 | +1
18+
19+
empty_comment_line_continuation.py:3:1: PLR2044 [*] Line with empty comment
20+
|
21+
1 | #
22+
2 | x = 0 \
23+
3 | #
24+
| ^ PLR2044
25+
4 | +1
26+
5 | print(x)
27+
|
28+
= help: Delete the empty comment
29+
30+
Safe fix
31+
1 1 | #
32+
2 2 | x = 0 \
33+
3 |-#
34+
3 |+
35+
4 4 | +1
36+
5 5 | print(x)

0 commit comments

Comments
 (0)