Skip to content

Commit 55d06c8

Browse files
authored
Ensure pending suppression diagnostics are reported (#23242)
1 parent d056a9f commit 55d06c8

3 files changed

Lines changed: 93 additions & 51 deletions

File tree

crates/ruff_linter/resources/test/fixtures/ruff/suppressions.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,10 @@ def f():
109109
# ruff: disable
110110
# ruff: disable[]
111111
print("hello")
112+
113+
114+
# Ensure LAST suppression in file is reported.
115+
# https://github.com/astral-sh/ruff/issues/23235
116+
# ruff:disable[F401]
117+
print("goodbye")
118+
# ruff:enable[F401]

crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__range_suppressions.snap

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ help: Remove suppression comment
382382
- # ruff: disable
383383
109 | # ruff: disable[]
384384
110 | print("hello")
385+
111 |
385386
note: This is an unsafe fix and may change runtime behavior
386387

387388
RUF103 [*] Invalid suppression comment: missing suppression codes like `[E501, ...]`
@@ -399,4 +400,25 @@ help: Remove suppression comment
399400
109 | # ruff: disable
400401
- # ruff: disable[]
401402
110 | print("hello")
403+
111 |
404+
112 |
402405
note: This is an unsafe fix and may change runtime behavior
406+
407+
RUF100 [*] Unused suppression (non-enabled: `F401`)
408+
--> suppressions.py:116:1
409+
|
410+
114 | # Ensure LAST suppression in file is reported.
411+
115 | # https://github.com/astral-sh/ruff/issues/23235
412+
116 | # ruff:disable[F401]
413+
| ^^^^^^^^^^^^^^^^^^^^
414+
117 | print("goodbye")
415+
118 | # ruff:enable[F401]
416+
| -------------------
417+
|
418+
help: Remove unused suppression
419+
113 |
420+
114 | # Ensure LAST suppression in file is reported.
421+
115 | # https://github.com/astral-sh/ruff/issues/23235
422+
- # ruff:disable[F401]
423+
116 | print("goodbye")
424+
- # ruff:enable[F401]

crates/ruff_linter/src/suppression.rs

Lines changed: 64 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -222,60 +222,71 @@ impl Suppressions {
222222
pub(crate) fn check_suppressions(&self, context: &LintContext, locator: &Locator) {
223223
let mut grouped_diagnostic: Option<(TextRange, SuppressionDiagnostic)> = None;
224224
let mut unmatched_ranges = FxHashSet::default();
225+
226+
let process_pending_diagnostics =
227+
|key: Option<TextRange>,
228+
grouped_diagnostic: &Option<(TextRange, SuppressionDiagnostic)>|
229+
-> bool {
230+
if let Some((group_key, group)) = grouped_diagnostic
231+
&& key.is_none_or(|key| key != *group_key)
232+
{
233+
if group.any_invalid() {
234+
Suppressions::report_suppression_codes(
235+
context,
236+
locator,
237+
group.suppression,
238+
&group.invalid_codes,
239+
true,
240+
InvalidRuleCode {
241+
rule_code: group.invalid_codes.iter().join(", "),
242+
kind: InvalidRuleCodeKind::Suppression,
243+
whole_comment: group.suppression.codes().len()
244+
== group.invalid_codes.len(),
245+
},
246+
);
247+
}
248+
if group.any_unused() {
249+
let mut codes = group.disabled_codes.clone();
250+
codes.extend(group.unused_codes.clone());
251+
Suppressions::report_suppression_codes(
252+
context,
253+
locator,
254+
group.suppression,
255+
&codes,
256+
false,
257+
UnusedNOQA {
258+
codes: Some(UnusedCodes {
259+
disabled: group
260+
.disabled_codes
261+
.iter()
262+
.map(ToString::to_string)
263+
.collect_vec(),
264+
duplicated: group
265+
.duplicated_codes
266+
.iter()
267+
.map(ToString::to_string)
268+
.collect_vec(),
269+
unmatched: group
270+
.unused_codes
271+
.iter()
272+
.map(ToString::to_string)
273+
.collect_vec(),
274+
..Default::default()
275+
}),
276+
kind: UnusedNOQAKind::Suppression,
277+
},
278+
);
279+
}
280+
true
281+
} else {
282+
false
283+
}
284+
};
285+
225286
for suppression in &self.valid {
226287
let key = suppression.comments.disable_comment().range;
227288

228-
// Process any pending grouped diagnostics
229-
if let Some((group_key, ref group)) = grouped_diagnostic
230-
&& key != group_key
231-
{
232-
if group.any_invalid() {
233-
Suppressions::report_suppression_codes(
234-
context,
235-
locator,
236-
group.suppression,
237-
&group.invalid_codes,
238-
true,
239-
InvalidRuleCode {
240-
rule_code: group.invalid_codes.iter().join(", "),
241-
kind: InvalidRuleCodeKind::Suppression,
242-
whole_comment: group.suppression.codes().len()
243-
== group.invalid_codes.len(),
244-
},
245-
);
246-
}
247-
if group.any_unused() {
248-
let mut codes = group.disabled_codes.clone();
249-
codes.extend(group.unused_codes.clone());
250-
Suppressions::report_suppression_codes(
251-
context,
252-
locator,
253-
group.suppression,
254-
&codes,
255-
false,
256-
UnusedNOQA {
257-
codes: Some(UnusedCodes {
258-
disabled: group
259-
.disabled_codes
260-
.iter()
261-
.map(ToString::to_string)
262-
.collect_vec(),
263-
duplicated: group
264-
.duplicated_codes
265-
.iter()
266-
.map(ToString::to_string)
267-
.collect_vec(),
268-
unmatched: group
269-
.unused_codes
270-
.iter()
271-
.map(ToString::to_string)
272-
.collect_vec(),
273-
..Default::default()
274-
}),
275-
kind: UnusedNOQAKind::Suppression,
276-
},
277-
);
278-
}
289+
if process_pending_diagnostics(Some(key), &grouped_diagnostic) {
279290
grouped_diagnostic = None;
280291
}
281292

@@ -324,6 +335,8 @@ impl Suppressions {
324335
}
325336
}
326337

338+
process_pending_diagnostics(None, &grouped_diagnostic);
339+
327340
if context.is_rule_enabled(Rule::InvalidSuppressionComment) {
328341
for error in &self.errors {
329342
context

0 commit comments

Comments
 (0)