mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:39:12 +00:00
Respect per-file ignores for blanket and redirected noqa rules (#11728)
## Summary Ensures that we respect per-file ignores and exemptions for these rules. Specifically, we allow: ```python # ruff: noqa: PGH004 ``` ...to ignore `PGH004`.
This commit is contained in:
parent
b56a577f25
commit
0c75548146
5 changed files with 46 additions and 17 deletions
8
crates/ruff_linter/resources/test/fixtures/pygrep_hooks/PGH004_3.py
vendored
Normal file
8
crates/ruff_linter/resources/test/fixtures/pygrep_hooks/PGH004_3.py
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
# noqa
|
||||
# ruff : noqa
|
||||
# ruff: noqa: F401
|
||||
# ruff: noqa: PGH004
|
||||
|
||||
|
||||
# flake8: noqa
|
||||
import math as m
|
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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>),
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/pygrep_hooks/mod.rs
|
||||
---
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue