Skip to content

Conversation

@amyreese
Copy link
Contributor

@amyreese amyreese commented Nov 25, 2025

Builds on range suppressions from #21441

Filters diagnostics based on parsed valid range suppressions.

Issue: #3711

@amyreese amyreese changed the base branch from main to suppression-parsing November 25, 2025 02:02
@astral-sh-bot
Copy link

astral-sh-bot bot commented Nov 25, 2025

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add some tests now. check_path is called from our testing framework, meaning we should now be able to write a test similar to

#[test]
fn noqa() -> Result<()> {
let diagnostics = test_path(
Path::new("ruff/noqa.py"),
&settings::LinterSettings::for_rules(vec![
Rule::UnusedVariable,
Rule::AmbiguousVariableName,
]),
)?;
assert_diagnostics!(diagnostics);
Ok(())
}

This could also be used as a replacement for some of the tests I asked for in your previous PR.

I also suggest adding some CLI tests verifying that this PR doesn't break in combination with --add-noqa, --remove-noqa --ignore-noqa etc.

@MichaReiser MichaReiser added the suppression Related to supression of violations e.g. noqa label Nov 25, 2025
@amyreese amyreese force-pushed the amy/suppress-diagnostics branch from 850398d to 2ff32de Compare November 26, 2025 01:36
@MichaReiser MichaReiser changed the title [ruff] apply range suppressions to filter diagnostics apply range suppressions to filter diagnostics Nov 26, 2025
@MichaReiser MichaReiser added the internal An internal refactor or improvement label Nov 26, 2025
@amyreese amyreese force-pushed the suppression-parsing branch from ce14617 to 607325e Compare December 1, 2025 21:17
@amyreese
Copy link
Contributor Author

amyreese commented Dec 2, 2025

I also suggest adding some CLI tests verifying that this PR doesn't break in combination with --add-noqa, --remove-noqa --ignore-noqa etc.

Is there an existing set of CLI tests for noqa that I can use as an example here?

@amyreese amyreese force-pushed the amy/suppress-diagnostics branch from 2ff32de to 1586572 Compare December 2, 2025 01:30
@amyreese amyreese requested a review from MichaReiser December 2, 2025 01:31
@MichaReiser
Copy link
Member

Is there an existing set of CLI tests for noqa that I can use as an example here?

There are some here

fn add_noqa() -> Result<()> {

I couldn't find any for --ignore-noqa, and --remove-noqa doesn't exist, it's just fix and you can find some tests in the above mentioned test file

Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good. But we should look into the performance regression before landing this PR (can be fixed as a separate PR but we can't land this until we fixed the regression)

@amyreese
Copy link
Contributor Author

amyreese commented Dec 2, 2025

Note: add --preview gating so we can land this without waiting for diagnostics etc

@amyreese amyreese force-pushed the suppression-parsing branch from ea5b48d to 288d431 Compare December 2, 2025 22:46
Base automatically changed from suppression-parsing to main December 2, 2025 23:40
@amyreese amyreese force-pushed the amy/suppress-diagnostics branch from 1586572 to 5ebadd4 Compare December 3, 2025 02:03
Comment on lines +1743 to +1744
let test_code =
fs::read_to_string(fixture.root().join("noqa.py")).expect("should read test file");
Copy link
Member

@MichaReiser MichaReiser Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We try to avoid reading fixture files in CLI tests as it makes the tests depend on each other and it can also become harder to reason about what we're testing here. Would it be possible to extract the specific case you want to test from noqa.py?

The tests here also don't need to be exhaustive. We can add more exhaustive tests to add_noqa (I think we have some integration tests, right?)

Comment on lines +427 to +432
let suppressions = if is_range_suppressions_enabled(settings) {
Suppressions::from_tokens(locator.contents(), parsed.tokens())
} else {
Suppressions::default()
};

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now end up extracting the suppressions twice: Once in check_path and once here. We might need to pass the suppressions as part of check_path

let exemption = FileExemption::from(&file_directives);
let directives = NoqaDirectives::from_commented_ranges(comment_ranges, external, path, locator);
let comments = find_noqa_comments(diagnostics, locator, &exemption, &directives, noqa_line_for);
// This is called by ruff_server, which already filtered diagnostics via check_path
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also call this function from our tests. Would it make sense to lift Suppressions out of generate_noqa_edits and instead require the caller to pass the suppressions?

])
.with_preview_mode(),
)?;
assert_diagnostics!(diagnostics);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be a good case for assert_diagnostics_diff which snapshots the difference between two settings: E.g. between preview on and off

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal An internal refactor or improvement suppression Related to supression of violations e.g. noqa

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants