Respect external codes in file-level exemptions (#10203)

We shouldn't warn when an "external" code is used in a file-level
exemption.

Closes https://github.com/astral-sh/ruff/issues/10202.
This commit is contained in:
Charlie Marsh 2024-03-02 16:20:36 -08:00 committed by GitHub
parent c7431828a7
commit 7515196245
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 62 additions and 2 deletions

View file

@ -933,3 +933,42 @@ include = ["*.ipy"]
Ok(()) Ok(())
} }
#[test]
fn file_noqa_external() -> Result<()> {
let tempdir = TempDir::new()?;
let ruff_toml = tempdir.path().join("ruff.toml");
fs::write(
&ruff_toml,
r#"
[lint]
external = ["AAA"]
"#,
)?;
insta::with_settings!({
filters => vec![(tempdir_filter(&tempdir).as_str(), "[TMP]/")]
}, {
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
.args(STDIN_BASE_OPTIONS)
.arg("--config")
.arg(&ruff_toml)
.arg("-")
.pass_stdin(r#"
# flake8: noqa: AAA101, BBB102
import os
"#), @r###"
success: false
exit_code: 1
----- stdout -----
-:3:8: F401 [*] `os` imported but unused
Found 1 error.
[*] 1 fixable with the `--fix` option.
----- stderr -----
warning: Invalid rule code provided to `# ruff: noqa` at -:2: BBB102
"###);
});
Ok(())
}

View file

@ -29,7 +29,13 @@ pub(crate) fn check_noqa(
settings: &LinterSettings, settings: &LinterSettings,
) -> Vec<usize> { ) -> Vec<usize> {
// Identify any codes that are globally exempted (within the current file). // Identify any codes that are globally exempted (within the current file).
let exemption = FileExemption::try_extract(locator.contents(), comment_ranges, path, locator); let exemption = FileExemption::try_extract(
locator.contents(),
comment_ranges,
&settings.external,
path,
locator,
);
// Extract all `noqa` directives. // Extract all `noqa` directives.
let mut noqa_directives = NoqaDirectives::from_commented_ranges(comment_ranges, path, locator); let mut noqa_directives = NoqaDirectives::from_commented_ranges(comment_ranges, path, locator);

View file

@ -407,6 +407,7 @@ pub fn add_noqa_to_path(
&diagnostics.0, &diagnostics.0,
&locator, &locator,
indexer.comment_ranges(), indexer.comment_ranges(),
&settings.external,
&directives.noqa_line_for, &directives.noqa_line_for,
stylist.line_ending(), stylist.line_ending(),
) )

View file

@ -235,6 +235,7 @@ impl FileExemption {
pub(crate) fn try_extract( pub(crate) fn try_extract(
contents: &str, contents: &str,
comment_ranges: &CommentRanges, comment_ranges: &CommentRanges,
external: &[String],
path: &Path, path: &Path,
locator: &Locator, locator: &Locator,
) -> Option<Self> { ) -> Option<Self> {
@ -263,6 +264,11 @@ impl FileExemption {
} }
ParsedFileExemption::Codes(codes) => { ParsedFileExemption::Codes(codes) => {
exempt_codes.extend(codes.into_iter().filter_map(|code| { exempt_codes.extend(codes.into_iter().filter_map(|code| {
// Ignore externally-defined rules.
if external.iter().any(|external| code.starts_with(external)) {
return None;
}
if let Ok(rule) = Rule::from_code(get_redirect_target(code).unwrap_or(code)) if let Ok(rule) = Rule::from_code(get_redirect_target(code).unwrap_or(code))
{ {
Some(rule.noqa_code()) Some(rule.noqa_code())
@ -458,6 +464,7 @@ pub(crate) fn add_noqa(
diagnostics: &[Diagnostic], diagnostics: &[Diagnostic],
locator: &Locator, locator: &Locator,
comment_ranges: &CommentRanges, comment_ranges: &CommentRanges,
external: &[String],
noqa_line_for: &NoqaMapping, noqa_line_for: &NoqaMapping,
line_ending: LineEnding, line_ending: LineEnding,
) -> Result<usize> { ) -> Result<usize> {
@ -466,6 +473,7 @@ pub(crate) fn add_noqa(
diagnostics, diagnostics,
locator, locator,
comment_ranges, comment_ranges,
external,
noqa_line_for, noqa_line_for,
line_ending, line_ending,
); );
@ -478,6 +486,7 @@ fn add_noqa_inner(
diagnostics: &[Diagnostic], diagnostics: &[Diagnostic],
locator: &Locator, locator: &Locator,
comment_ranges: &CommentRanges, comment_ranges: &CommentRanges,
external: &[String],
noqa_line_for: &NoqaMapping, noqa_line_for: &NoqaMapping,
line_ending: LineEnding, line_ending: LineEnding,
) -> (usize, String) { ) -> (usize, String) {
@ -487,7 +496,8 @@ fn add_noqa_inner(
// Whether the file is exempted from all checks. // Whether the file is exempted from all checks.
// Codes that are globally exempted (within the current file). // Codes that are globally exempted (within the current file).
let exemption = FileExemption::try_extract(locator.contents(), comment_ranges, path, locator); let exemption =
FileExemption::try_extract(locator.contents(), comment_ranges, external, path, locator);
let directives = NoqaDirectives::from_commented_ranges(comment_ranges, path, locator); let directives = NoqaDirectives::from_commented_ranges(comment_ranges, path, locator);
// Mark any non-ignored diagnostics. // Mark any non-ignored diagnostics.
@ -1001,6 +1011,7 @@ mod tests {
&[], &[],
&Locator::new(contents), &Locator::new(contents),
&CommentRanges::default(), &CommentRanges::default(),
&[],
&noqa_line_for, &noqa_line_for,
LineEnding::Lf, LineEnding::Lf,
); );
@ -1021,6 +1032,7 @@ mod tests {
&diagnostics, &diagnostics,
&Locator::new(contents), &Locator::new(contents),
&CommentRanges::default(), &CommentRanges::default(),
&[],
&noqa_line_for, &noqa_line_for,
LineEnding::Lf, LineEnding::Lf,
); );
@ -1048,6 +1060,7 @@ mod tests {
&diagnostics, &diagnostics,
&Locator::new(contents), &Locator::new(contents),
&comment_ranges, &comment_ranges,
&[],
&noqa_line_for, &noqa_line_for,
LineEnding::Lf, LineEnding::Lf,
); );
@ -1075,6 +1088,7 @@ mod tests {
&diagnostics, &diagnostics,
&Locator::new(contents), &Locator::new(contents),
&comment_ranges, &comment_ranges,
&[],
&noqa_line_for, &noqa_line_for,
LineEnding::Lf, LineEnding::Lf,
); );