Skip to content

Commit c1059cc

Browse files
committed
Treat all RUF10x noqa codes as used
These codes are generated while processing noqa, so will never be seen as "used" by this logic. Just go ahead and treat them as used and trust that they're there for a reason. Issue #23191, fixes #21877
1 parent 012ec63 commit c1059cc

2 files changed

Lines changed: 35 additions & 4 deletions

File tree

crates/ruff_linter/src/checkers/noqa.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::rules::pygrep_hooks;
1818
use crate::rules::ruff;
1919
use crate::rules::ruff::rules::{UnusedCodes, UnusedNOQA};
2020
use crate::settings::LinterSettings;
21-
use crate::suppression::Suppressions;
21+
use crate::suppression::{Suppressions, is_suppression_diagnostic_code};
2222
use crate::{Edit, Fix, Locator};
2323

2424
use super::ast::LintContext;
@@ -178,7 +178,8 @@ pub(crate) fn check_noqa(
178178
} || settings
179179
.external
180180
.iter()
181-
.any(|external| code.starts_with(external));
181+
.any(|external| code.starts_with(external))
182+
|| is_suppression_diagnostic_code(code);
182183

183184
if is_code_used {
184185
valid_codes.push(original_code);

crates/ruff_linter/src/suppression.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use ruff_python_ast::token::{TokenKind, Tokens};
77
use ruff_python_index::Indexer;
88
use rustc_hash::FxHashSet;
99
use std::cell::Cell;
10+
use std::sync::LazyLock;
1011
use std::{error::Error, fmt::Formatter};
1112
use thiserror::Error;
1213

@@ -15,7 +16,7 @@ use ruff_text_size::{Ranged, TextLen, TextRange, TextSize, TextSlice};
1516
use smallvec::{SmallVec, smallvec};
1617

1718
use crate::checkers::ast::LintContext;
18-
use crate::codes::Rule;
19+
use crate::codes::{NoqaCode, Rule};
1920
use crate::fix::edits::delete_comment;
2021
use crate::rule_redirects::get_redirect_target;
2122
use crate::rules::ruff::rules::{
@@ -24,6 +25,20 @@ use crate::rules::ruff::rules::{
2425
};
2526
use crate::{Locator, Violation};
2627

28+
/// Determine if the rule code is a `RUF10x` diagnostic generated while processing diagnostics
29+
pub fn is_suppression_diagnostic_code(code: &str) -> bool {
30+
static SUPPRESSION_CODES: LazyLock<Vec<NoqaCode>> = LazyLock::new(|| {
31+
vec![
32+
Rule::UnusedNOQA.noqa_code(),
33+
Rule::RedirectedNOQA.noqa_code(),
34+
Rule::InvalidRuleCode.noqa_code(),
35+
Rule::InvalidSuppressionComment.noqa_code(),
36+
Rule::UnmatchedSuppressionComment.noqa_code(),
37+
]
38+
});
39+
SUPPRESSION_CODES.iter().any(|sc| sc == &code)
40+
}
41+
2742
#[derive(Clone, Debug, Eq, PartialEq)]
2843
enum SuppressionAction {
2944
Disable,
@@ -836,9 +851,24 @@ mod tests {
836851

837852
use crate::suppression::{
838853
InvalidSuppression, ParseError, Suppression, SuppressionAction, SuppressionComment,
839-
SuppressionParser, Suppressions,
854+
SuppressionParser, Suppressions, is_suppression_diagnostic_code,
840855
};
841856

857+
#[test]
858+
fn suppression_diagnostic_codes() {
859+
// Suppression-related diagnostics
860+
assert!(is_suppression_diagnostic_code("RUF100")); // UnusedNOQA
861+
assert!(is_suppression_diagnostic_code("RUF101")); // RedirectedNOQA
862+
assert!(is_suppression_diagnostic_code("RUF102")); // InvalidRuleCode
863+
assert!(is_suppression_diagnostic_code("RUF103")); // InvalidSuppressionComment
864+
assert!(is_suppression_diagnostic_code("RUF104")); // UnmatchedSuppressionComment
865+
866+
// Random rules
867+
assert!(!is_suppression_diagnostic_code("RUF013"));
868+
assert!(!is_suppression_diagnostic_code("F401"));
869+
assert!(!is_suppression_diagnostic_code("E101"));
870+
}
871+
842872
#[test]
843873
fn no_suppression() {
844874
let source = "

0 commit comments

Comments
 (0)