Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support negated patterns in [extend-]per-file-ignores #10852

Merged
merged 3 commits into from Apr 10, 2024
Merged

Support negated patterns in [extend-]per-file-ignores #10852

merged 3 commits into from Apr 10, 2024

Conversation

carljm
Copy link
Contributor

@carljm carljm commented Apr 10, 2024

Fixes #3172

Summary

Allow prefixing [extend-]per-file-ignores patterns with ! to negate the pattern; listed rules / prefixes will be ignored in all files that don't match the pattern.

Test Plan

Added tests for the feature.

Rendered docs and checked rendered output.

Comment on lines +312 to +314
if negated {
pattern.drain(..1);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This might look a little odd, but it's zero-allocation, unlike the version using .strip_prefix().

Perf probably doesn't matter much here in config-parsing; if you'd prefer the version that takes a non-mut String and uses .strip_prefix(), I can switch to that, though the code actually ends up longer than this.

Copy link
Member

Choose a reason for hiding this comment

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

I'm cool with this.

Copy link
Member

Choose a reason for hiding this comment

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

\cc @BurntSushi may have interesting things to say here :)

Copy link
Member

Choose a reason for hiding this comment

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

I think this is fine personally. I agree that saving an alloc probably doesn't matter here (I assume these ultimately get converted to a glob matcher, and that is an enormous amount of work compared to saving an alloc) so I'd write whatever is clear. And this seems clear to me. :)

@@ -593,7 +603,7 @@ pub type IdentifierPattern = glob::Pattern;
#[derive(Debug, Clone, CacheKey, Default)]
pub struct PerFileIgnores {
// Ordered as (absolute path matcher, basename matcher, rules)
ignores: Vec<(GlobMatcher, GlobMatcher, RuleSet)>,
ignores: Vec<(GlobMatcher, GlobMatcher, bool, RuleSet)>,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this should be a named struct (CompiledPerFileIgnore? PerFileIgnoreMatcher?) with named fields rather than a tuple, but for ease of review I didn't make that change here; will push it as a separate PR (unless a reviewer suggests I shouldn't.)

Copy link
Member

Choose a reason for hiding this comment

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

Agreed.

Copy link

github-actions bot commented Apr 10, 2024

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

crates/ruff/tests/lint.rs Outdated Show resolved Hide resolved
Copy link
Member

@charliermarsh charliermarsh left a comment

Choose a reason for hiding this comment

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

Looks great.

@charliermarsh charliermarsh added the configuration Related to settings and configuration label Apr 10, 2024
@carljm carljm merged commit 02e88fd into main Apr 10, 2024
17 checks passed
@carljm carljm deleted the cjm/select branch April 10, 2024 03:53
@@ -914,6 +915,8 @@ pub struct LintCommonOptions {
# Ignore `E402` (import violations) in all `__init__.py` files, and in `path/to/file.py`.
"__init__.py" = ["E402"]
"path/to/file.py" = ["E402"]
# Ignore `D` rules everywhere except for the `src/` directory.
Copy link

Choose a reason for hiding this comment

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

Is this comment correct? Looks like it ignored F401 not D

Copy link
Member

Choose a reason for hiding this comment

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

Ah yeah, it should be D below (or the comment should change to F401) \cc @carljm

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops, thanks, will fix!

Copy link
Member

@BurntSushi BurntSushi left a comment

Choose a reason for hiding this comment

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

Nice!

"###);
});
Ok(())
}
Copy link
Member

Choose a reason for hiding this comment

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

It might be worth adding some more tests where there are both regular patterns and negated patterns. And in particular, cases where a negated pattern might try to "override" a previous pattern. e.g.,

"*.py" = ["RUF"]
"!foo.py" = ["RUF"]

Or something like that.

Copy link
Contributor Author

@carljm carljm Apr 10, 2024

Choose a reason for hiding this comment

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

Yeah, that's a great point, I'll put up an update with a test for this case, and probably also more clearly document how this works.

(I don't expect to change the implementation as part of this; I think the way it needs to work is how it does now: we go through each pattern, and if the pattern matches (whether that's a positive match or a negated non-match), we add the listed rules as ignored; we never un-ignore rules based on failure to match a pattern. I think that would get too complex to understand pretty quickly, and also un-ignoring doesn't really make sense for an option named per-file-ignores.)

Comment on lines +312 to +314
if negated {
pattern.drain(..1);
}
Copy link
Member

Choose a reason for hiding this comment

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

I think this is fine personally. I agree that saving an alloc probably doesn't matter here (I assume these ultimately get converted to a glob matcher, and that is an enormous amount of work compared to saving an alloc) so I'd write whatever is clear. And this seems clear to me. :)

Glyphack pushed a commit to Glyphack/ruff that referenced this pull request Apr 12, 2024
Fixes astral-sh#3172 

## Summary

Allow prefixing [extend-]per-file-ignores patterns with `!` to negate
the pattern; listed rules / prefixes will be ignored in all files that
don't match the pattern.

## Test Plan

Added tests for the feature.

Rendered docs and checked rendered output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
configuration Related to settings and configuration
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Per file selection
5 participants