Add filename to `noqa` warnings (#5856)

## Summary

Before:

```
» ruff litestar tests --fix
warning: Invalid `# noqa` directive on line 19: expected a comma-separated list of codes (e.g., `# noqa: F401, F841`).
warning: Invalid `# noqa` directive on line 65: expected a comma-separated list of codes (e.g., `# noqa: F401, F841`).
warning: Invalid `# noqa` directive on line 74: expected a comma-separated list of codes (e.g., `# noqa: F401, F841`).
warning: Invalid `# noqa` directive on line 22: expected a comma-separated list of codes (e.g., `# noqa: F401, F841`).
warning: Invalid `# noqa` directive on line 66: expected a comma-separated list of codes (e.g., `# noqa: F401, F841`).
warning: Invalid `# noqa` directive on line 75: expected a comma-separated list of codes (e.g., `# noqa: F401, F841`).
```

After:

```
» cargo run --bin ruff ../litestar/litestar ../litestar/tests
    Finished dev [unoptimized + debuginfo] target(s) in 0.15s
     Running `target/debug/ruff ../litestar/litestar ../litestar/tests`
warning: Detected debug build without --no-cache.
warning: Invalid `# noqa` directive on /Users/sobolev/Desktop/litestar/tests/unit/test_contrib/test_sqlalchemy/models_bigint.py:19: expected a comma-separated list of codes (e.g., `# noqa: F401, F841`).
warning: Invalid `# noqa` directive on /Users/sobolev/Desktop/litestar/tests/unit/test_contrib/test_sqlalchemy/models_bigint.py:65: expected a comma-separated list of codes (e.g., `# noqa: F401, F841`).
warning: Invalid `# noqa` directive on /Users/sobolev/Desktop/litestar/tests/unit/test_contrib/test_sqlalchemy/models_bigint.py:74: expected a comma-separated list of codes (e.g., `# noqa: F401, F841`).
warning: Invalid `# noqa` directive on /Users/sobolev/Desktop/litestar/tests/unit/test_contrib/test_sqlalchemy/models_uuid.py:22: expected a comma-separated list of codes (e.g., `# noqa: F401, F841`).
warning: Invalid `# noqa` directive on /Users/sobolev/Desktop/litestar/tests/unit/test_contrib/test_sqlalchemy/models_uuid.py:66: expected a comma-separated list of codes (e.g., `# noqa: F401, F841`).
warning: Invalid `# noqa` directive on /Users/sobolev/Desktop/litestar/tests/unit/test_contrib/test_sqlalchemy/models_uuid.py:75: expected a comma-separated list of codes (e.g., `# noqa: F401, F841`).
```

## Test Plan

I didn't find any existing tests with this warning.

Closes https://github.com/astral-sh/ruff/issues/5855
This commit is contained in:
Nikita Sobolev 2023-07-18 17:08:22 +03:00 committed by GitHub
parent 3b32e3a8fe
commit 0c7c81aa31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 6 deletions

View File

@ -1,5 +1,7 @@
//! `NoQA` enforcement and validation. //! `NoQA` enforcement and validation.
use std::path::Path;
use itertools::Itertools; use itertools::Itertools;
use ruff_text_size::{TextLen, TextRange, TextSize}; use ruff_text_size::{TextLen, TextRange, TextSize};
use rustpython_parser::ast::Ranged; use rustpython_parser::ast::Ranged;
@ -16,6 +18,7 @@ use crate::settings::Settings;
pub(crate) fn check_noqa( pub(crate) fn check_noqa(
diagnostics: &mut Vec<Diagnostic>, diagnostics: &mut Vec<Diagnostic>,
path: &Path,
locator: &Locator, locator: &Locator,
comment_ranges: &[TextRange], comment_ranges: &[TextRange],
noqa_line_for: &NoqaMapping, noqa_line_for: &NoqaMapping,
@ -23,10 +26,10 @@ pub(crate) fn check_noqa(
settings: &Settings, settings: &Settings,
) -> 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, locator); let exemption = FileExemption::try_extract(locator.contents(), comment_ranges, path, locator);
// Extract all `noqa` directives. // Extract all `noqa` directives.
let mut noqa_directives = NoqaDirectives::from_commented_ranges(comment_ranges, locator); let mut noqa_directives = NoqaDirectives::from_commented_ranges(comment_ranges, path, locator);
// Indices of diagnostics that were ignored by a `noqa` directive. // Indices of diagnostics that were ignored by a `noqa` directive.
let mut ignored_diagnostics = vec![]; let mut ignored_diagnostics = vec![];

View File

@ -214,6 +214,7 @@ pub fn check_path(
{ {
let ignored = check_noqa( let ignored = check_noqa(
&mut diagnostics, &mut diagnostics,
path,
locator, locator,
indexer.comment_ranges(), indexer.comment_ranges(),
&directives.noqa_line_for, &directives.noqa_line_for,

View File

@ -16,6 +16,7 @@ use ruff_python_ast::source_code::Locator;
use ruff_python_whitespace::LineEnding; use ruff_python_whitespace::LineEnding;
use crate::codes::NoqaCode; use crate::codes::NoqaCode;
use crate::fs::relativize_path;
use crate::registry::{AsRule, Rule, RuleSet}; use crate::registry::{AsRule, Rule, RuleSet};
use crate::rule_redirects::get_redirect_target; use crate::rule_redirects::get_redirect_target;
@ -225,6 +226,7 @@ impl FileExemption {
pub(crate) fn try_extract( pub(crate) fn try_extract(
contents: &str, contents: &str,
comment_ranges: &[TextRange], comment_ranges: &[TextRange],
path: &Path,
locator: &Locator, locator: &Locator,
) -> Option<Self> { ) -> Option<Self> {
let mut exempt_codes: Vec<NoqaCode> = vec![]; let mut exempt_codes: Vec<NoqaCode> = vec![];
@ -234,7 +236,8 @@ impl FileExemption {
Err(err) => { Err(err) => {
#[allow(deprecated)] #[allow(deprecated)]
let line = locator.compute_line_index(range.start()); let line = locator.compute_line_index(range.start());
warn!("Invalid `# noqa` directive on line {line}: {err}"); let path_display = path.display();
warn!("Invalid `# noqa` directive on {path_display}:{line}: {err}");
} }
Ok(Some(ParsedFileExemption::All)) => { Ok(Some(ParsedFileExemption::All)) => {
return Some(Self::All); return Some(Self::All);
@ -437,6 +440,7 @@ pub(crate) fn add_noqa(
line_ending: LineEnding, line_ending: LineEnding,
) -> Result<usize> { ) -> Result<usize> {
let (count, output) = add_noqa_inner( let (count, output) = add_noqa_inner(
path,
diagnostics, diagnostics,
locator, locator,
commented_lines, commented_lines,
@ -448,6 +452,7 @@ pub(crate) fn add_noqa(
} }
fn add_noqa_inner( fn add_noqa_inner(
path: &Path,
diagnostics: &[Diagnostic], diagnostics: &[Diagnostic],
locator: &Locator, locator: &Locator,
commented_ranges: &[TextRange], commented_ranges: &[TextRange],
@ -460,8 +465,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(), commented_ranges, locator); let exemption = FileExemption::try_extract(locator.contents(), commented_ranges, path, locator);
let directives = NoqaDirectives::from_commented_ranges(commented_ranges, locator); let directives = NoqaDirectives::from_commented_ranges(commented_ranges, path, locator);
// Mark any non-ignored diagnostics. // Mark any non-ignored diagnostics.
for diagnostic in diagnostics { for diagnostic in diagnostics {
@ -625,6 +630,7 @@ pub(crate) struct NoqaDirectives<'a> {
impl<'a> NoqaDirectives<'a> { impl<'a> NoqaDirectives<'a> {
pub(crate) fn from_commented_ranges( pub(crate) fn from_commented_ranges(
comment_ranges: &[TextRange], comment_ranges: &[TextRange],
path: &Path,
locator: &'a Locator<'a>, locator: &'a Locator<'a>,
) -> Self { ) -> Self {
let mut directives = Vec::new(); let mut directives = Vec::new();
@ -634,7 +640,8 @@ impl<'a> NoqaDirectives<'a> {
Err(err) => { Err(err) => {
#[allow(deprecated)] #[allow(deprecated)]
let line = locator.compute_line_index(range.start()); let line = locator.compute_line_index(range.start());
warn!("Invalid `# noqa` directive on line {line}: {err}"); let path_display = relativize_path(path);
warn!("Invalid `# noqa` directive on {path_display}:{line}: {err}");
} }
Ok(Some(directive)) => { Ok(Some(directive)) => {
// noqa comments are guaranteed to be single line. // noqa comments are guaranteed to be single line.
@ -758,6 +765,8 @@ impl FromIterator<TextRange> for NoqaMapping {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::path::Path;
use insta::assert_debug_snapshot; use insta::assert_debug_snapshot;
use ruff_text_size::{TextRange, TextSize}; use ruff_text_size::{TextRange, TextSize};
@ -946,9 +955,12 @@ mod tests {
#[test] #[test]
fn modification() { fn modification() {
let path = Path::new("/tmp/foo.txt");
let contents = "x = 1"; let contents = "x = 1";
let noqa_line_for = NoqaMapping::default(); let noqa_line_for = NoqaMapping::default();
let (count, output) = add_noqa_inner( let (count, output) = add_noqa_inner(
path,
&[], &[],
&Locator::new(contents), &Locator::new(contents),
&[], &[],
@ -968,6 +980,7 @@ mod tests {
let contents = "x = 1"; let contents = "x = 1";
let noqa_line_for = NoqaMapping::default(); let noqa_line_for = NoqaMapping::default();
let (count, output) = add_noqa_inner( let (count, output) = add_noqa_inner(
path,
&diagnostics, &diagnostics,
&Locator::new(contents), &Locator::new(contents),
&[], &[],
@ -992,6 +1005,7 @@ mod tests {
let contents = "x = 1 # noqa: E741\n"; let contents = "x = 1 # noqa: E741\n";
let noqa_line_for = NoqaMapping::default(); let noqa_line_for = NoqaMapping::default();
let (count, output) = add_noqa_inner( let (count, output) = add_noqa_inner(
path,
&diagnostics, &diagnostics,
&Locator::new(contents), &Locator::new(contents),
&[TextRange::new(TextSize::from(7), TextSize::from(19))], &[TextRange::new(TextSize::from(7), TextSize::from(19))],
@ -1016,6 +1030,7 @@ mod tests {
let contents = "x = 1 # noqa"; let contents = "x = 1 # noqa";
let noqa_line_for = NoqaMapping::default(); let noqa_line_for = NoqaMapping::default();
let (count, output) = add_noqa_inner( let (count, output) = add_noqa_inner(
path,
&diagnostics, &diagnostics,
&Locator::new(contents), &Locator::new(contents),
&[TextRange::new(TextSize::from(7), TextSize::from(13))], &[TextRange::new(TextSize::from(7), TextSize::from(13))],