Skip to content

Commit

Permalink
Respect per-file ignores for blanket and redirected noqa rules (#11728)
Browse files Browse the repository at this point in the history
## Summary

Ensures that we respect per-file ignores and exemptions for these rules.
Specifically, we allow:

```python
# ruff: noqa: PGH004
```

...to ignore `PGH004`.
  • Loading branch information
charliermarsh authored Jun 4, 2024
1 parent b56a577 commit 0c75548
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# noqa
# ruff : noqa
# ruff: noqa: F401
# ruff: noqa: PGH004


# flake8: noqa
import math as m
18 changes: 12 additions & 6 deletions crates/ruff_linter/src/checkers/noqa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub(crate) fn check_noqa(
}

match &exemption {
FileExemption::All => {
FileExemption::All(_) => {
// If the file is exempted, ignore all diagnostics.
ignored_diagnostics.push(index);
continue;
Expand Down Expand Up @@ -213,7 +213,17 @@ pub(crate) fn check_noqa(
}
}

if settings.rules.enabled(Rule::BlanketNOQA) {
if settings.rules.enabled(Rule::RedirectedNOQA)
&& !per_file_ignores.contains(Rule::RedirectedNOQA)
&& !exemption.includes(Rule::RedirectedNOQA)
{
ruff::rules::redirected_noqa(diagnostics, &noqa_directives);
}

if settings.rules.enabled(Rule::BlanketNOQA)
&& !per_file_ignores.contains(Rule::BlanketNOQA)
&& !exemption.enumerates(Rule::BlanketNOQA)
{
pygrep_hooks::rules::blanket_noqa(
diagnostics,
&noqa_directives,
Expand All @@ -223,10 +233,6 @@ pub(crate) fn check_noqa(
);
}

if settings.rules.enabled(Rule::RedirectedNOQA) {
ruff::rules::redirected_noqa(diagnostics, &noqa_directives);
}

ignored_diagnostics.sort_unstable();
ignored_diagnostics
}
32 changes: 21 additions & 11 deletions crates/ruff_linter/src/noqa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ pub(crate) fn rule_is_ignored(
#[derive(Debug)]
pub(crate) enum FileExemption<'a> {
/// The file is exempt from all rules.
All,
All(Vec<&'a NoqaCode>),
/// The file is exempt from the given rules.
Codes(Vec<&'a NoqaCode>),
}
Expand All @@ -290,28 +290,38 @@ impl<'a> FileExemption<'a> {
pub(crate) fn includes(&self, needle: Rule) -> bool {
let needle = needle.noqa_code();
match self {
FileExemption::All => true,
FileExemption::All(_) => true,
FileExemption::Codes(codes) => codes.iter().any(|code| needle == **code),
}
}

/// Returns `true` if the file exemption lists the rule directly, rather than via a blanket
/// exemption.
pub(crate) fn enumerates(&self, needle: Rule) -> bool {
let needle = needle.noqa_code();
let codes = match self {
FileExemption::All(codes) => codes,
FileExemption::Codes(codes) => codes,
};
codes.iter().any(|code| needle == **code)
}
}

impl<'a> From<&'a FileNoqaDirectives<'a>> for FileExemption<'a> {
fn from(directives: &'a FileNoqaDirectives) -> Self {
let codes = directives
.lines()
.iter()
.flat_map(|line| &line.matches)
.collect();
if directives
.lines()
.iter()
.any(|line| ParsedFileExemption::All == line.parsed_file_exemption)
{
FileExemption::All
FileExemption::All(codes)
} else {
FileExemption::Codes(
directives
.lines()
.iter()
.flat_map(|line| &line.matches)
.collect(),
)
FileExemption::Codes(codes)
}
}
}
Expand Down Expand Up @@ -717,7 +727,7 @@ fn find_noqa_comments<'a>(
// Mark any non-ignored diagnostics.
for diagnostic in diagnostics {
match &exemption {
FileExemption::All => {
FileExemption::All(_) => {
// If the file is exempted, don't add any noqa directives.
comments_by_line.push(None);
continue;
Expand Down
1 change: 1 addition & 0 deletions crates/ruff_linter/src/rules/pygrep_hooks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod tests {
#[test_case(Rule::BlanketNOQA, Path::new("PGH004_0.py"))]
#[test_case(Rule::BlanketNOQA, Path::new("PGH004_1.py"))]
#[test_case(Rule::BlanketNOQA, Path::new("PGH004_2.py"))]
#[test_case(Rule::BlanketNOQA, Path::new("PGH004_3.py"))]
#[test_case(Rule::InvalidMockAccess, Path::new("PGH005_0.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
source: crates/ruff_linter/src/rules/pygrep_hooks/mod.rs
---

0 comments on commit 0c75548

Please sign in to comment.