diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/ruff_per_file_ignores.py b/crates/ruff_linter/resources/test/fixtures/ruff/ruff_per_file_ignores.py new file mode 100644 index 0000000000000..26112db8f424e --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/ruff/ruff_per_file_ignores.py @@ -0,0 +1,2 @@ +import os +import foo # noqa: F401 diff --git a/crates/ruff_linter/src/checkers/noqa.rs b/crates/ruff_linter/src/checkers/noqa.rs index 055f802ccc7c8..d5d4276abb27a 100644 --- a/crates/ruff_linter/src/checkers/noqa.rs +++ b/crates/ruff_linter/src/checkers/noqa.rs @@ -11,11 +11,12 @@ use ruff_source_file::Locator; use crate::noqa; use crate::noqa::{Directive, FileExemption, NoqaDirectives, NoqaMapping}; -use crate::registry::{AsRule, Rule}; +use crate::registry::{AsRule, Rule, RuleSet}; use crate::rule_redirects::get_redirect_target; use crate::rules::ruff::rules::{UnusedCodes, UnusedNOQA}; use crate::settings::LinterSettings; +#[allow(clippy::too_many_arguments)] pub(crate) fn check_noqa( diagnostics: &mut Vec, path: &Path, @@ -23,6 +24,7 @@ pub(crate) fn check_noqa( comment_ranges: &CommentRanges, noqa_line_for: &NoqaMapping, analyze_directives: bool, + per_file_ignores: &RuleSet, settings: &LinterSettings, ) -> Vec { // Identify any codes that are globally exempted (within the current file). @@ -119,7 +121,7 @@ pub(crate) fn check_noqa( let mut unknown_codes = vec![]; let mut unmatched_codes = vec![]; let mut valid_codes = vec![]; - let mut self_ignore = false; + let mut self_ignore = per_file_ignores.contains(Rule::UnusedNOQA); for code in directive.codes() { let code = get_redirect_target(code).unwrap_or(code); if Rule::UnusedNOQA.noqa_code() == code { diff --git a/crates/ruff_linter/src/linter.rs b/crates/ruff_linter/src/linter.rs index 2d81cc961c644..6e62b4d6218f1 100644 --- a/crates/ruff_linter/src/linter.rs +++ b/crates/ruff_linter/src/linter.rs @@ -31,7 +31,7 @@ use crate::fix::{fix_file, FixResult}; use crate::logging::DisplayParseError; use crate::message::Message; use crate::noqa::add_noqa; -use crate::registry::{AsRule, Rule}; +use crate::registry::{AsRule, Rule, RuleSet}; use crate::rules::pycodestyle; use crate::settings::types::UnsafeFixes; use crate::settings::{flags, LinterSettings}; @@ -213,12 +213,14 @@ pub fn check_path( } // Ignore diagnostics based on per-file-ignores. - if !diagnostics.is_empty() && !settings.per_file_ignores.is_empty() { - let ignores = fs::ignores_from_path(path, &settings.per_file_ignores); - if !ignores.is_empty() { - diagnostics.retain(|diagnostic| !ignores.contains(diagnostic.kind.rule())); - } + let per_file_ignores = if !diagnostics.is_empty() && !settings.per_file_ignores.is_empty() { + fs::ignores_from_path(path, &settings.per_file_ignores) + } else { + RuleSet::empty() }; + if !per_file_ignores.is_empty() { + diagnostics.retain(|diagnostic| !per_file_ignores.contains(diagnostic.kind.rule())); + } // Enforce `noqa` directives. if (noqa.into() && !diagnostics.is_empty()) @@ -234,6 +236,7 @@ pub fn check_path( indexer.comment_ranges(), &directives.noqa_line_for, error.is_none(), + &per_file_ignores, settings, ); if noqa.into() { diff --git a/crates/ruff_linter/src/rules/ruff/mod.rs b/crates/ruff_linter/src/rules/ruff/mod.rs index f94001b30bcf7..2c26ab0bcb33f 100644 --- a/crates/ruff_linter/src/rules/ruff/mod.rs +++ b/crates/ruff_linter/src/rules/ruff/mod.rs @@ -224,6 +224,25 @@ mod tests { assert_messages!(diagnostics); Ok(()) } + + #[test] + fn ruff_per_file_ignores() -> Result<()> { + let diagnostics = test_path( + Path::new("ruff/ruff_per_file_ignores.py"), + &settings::LinterSettings { + per_file_ignores: resolve_per_file_ignores(vec![PerFileIgnore::new( + "ruff_per_file_ignores.py".to_string(), + &["F401".parse().unwrap(), "RUF100".parse().unwrap()], + None, + )]) + .unwrap(), + ..settings::LinterSettings::for_rules(vec![Rule::UnusedImport, Rule::UnusedNOQA]) + }, + )?; + assert_messages!(diagnostics); + Ok(()) + } + #[test] fn flake8_noqa() -> Result<()> { let diagnostics = test_path( diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruff_per_file_ignores.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruff_per_file_ignores.snap new file mode 100644 index 0000000000000..7f58cfd7246a3 --- /dev/null +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__ruff_per_file_ignores.snap @@ -0,0 +1,4 @@ +--- +source: crates/ruff_linter/src/rules/ruff/mod.rs +--- +