Skip to content

Commit 25f5a8b

Browse files
carljmAlexWaygood
andauthored
Struct not tuple for compiled per-file ignores (#10864)
## Summary Code cleanup for per-file ignores; use a struct instead of a tuple. Named the structs for individual ignores and the list of ignores `CompiledPerFileIgnore` and `CompiledPerFileIgnoreList`. Name choice is because we already have a `PerFileIgnore` struct for a pre-compiled-matchers form of the config. Name bikeshedding welcome. ## Test Plan Refactor, should not change behavior; existing tests pass. --------- Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
1 parent e7d1d43 commit 25f5a8b

File tree

5 files changed

+76
-52
lines changed

5 files changed

+76
-52
lines changed

crates/ruff_linter/src/fs.rs

+19-22
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,46 @@
11
use std::path::{Path, PathBuf};
22

3-
use globset::GlobMatcher;
43
use log::debug;
54
use path_absolutize::Absolutize;
65

76
use crate::registry::RuleSet;
7+
use crate::settings::types::CompiledPerFileIgnoreList;
88

99
/// Create a set with codes matching the pattern/code pairs.
10-
pub(crate) fn ignores_from_path(
11-
path: &Path,
12-
pattern_code_pairs: &[(GlobMatcher, GlobMatcher, bool, RuleSet)],
13-
) -> RuleSet {
10+
pub(crate) fn ignores_from_path(path: &Path, ignore_list: &CompiledPerFileIgnoreList) -> RuleSet {
1411
let file_name = path.file_name().expect("Unable to parse filename");
15-
pattern_code_pairs
12+
ignore_list
1613
.iter()
17-
.filter_map(|(absolute, basename, negated, rules)| {
18-
if basename.is_match(file_name) {
19-
if *negated { None } else {
14+
.filter_map(|entry| {
15+
if entry.basename_matcher.is_match(file_name) {
16+
if entry.negated { None } else {
2017
debug!(
2118
"Adding per-file ignores for {:?} due to basename match on {:?}: {:?}",
2219
path,
23-
basename.glob().regex(),
24-
rules
20+
entry.basename_matcher.glob().regex(),
21+
entry.rules
2522
);
26-
Some(rules)
23+
Some(&entry.rules)
2724
}
28-
} else if absolute.is_match(path) {
29-
if *negated { None } else {
25+
} else if entry.absolute_matcher.is_match(path) {
26+
if entry.negated { None } else {
3027
debug!(
3128
"Adding per-file ignores for {:?} due to absolute match on {:?}: {:?}",
3229
path,
33-
absolute.glob().regex(),
34-
rules
30+
entry.absolute_matcher.glob().regex(),
31+
entry.rules
3532
);
36-
Some(rules)
33+
Some(&entry.rules)
3734
}
38-
} else if *negated {
35+
} else if entry.negated {
3936
debug!(
4037
"Adding per-file ignores for {:?} due to negated pattern matching neither {:?} nor {:?}: {:?}",
4138
path,
42-
basename.glob().regex(),
43-
absolute.glob().regex(),
44-
rules
39+
entry.basename_matcher.glob().regex(),
40+
entry.absolute_matcher.glob().regex(),
41+
entry.rules
4542
);
46-
Some(rules)
43+
Some(&entry.rules)
4744
} else {
4845
None
4946
}

crates/ruff_linter/src/rules/ruff/mod.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ mod tests {
1616

1717
use crate::pyproject_toml::lint_pyproject_toml;
1818
use crate::registry::Rule;
19-
use crate::settings::types::{PerFileIgnore, PerFileIgnores, PreviewMode, PythonVersion};
19+
use crate::settings::types::{
20+
CompiledPerFileIgnoreList, PerFileIgnore, PreviewMode, PythonVersion,
21+
};
2022
use crate::test::{test_path, test_resource_path};
2123
use crate::{assert_messages, settings};
2224

@@ -179,7 +181,7 @@ mod tests {
179181
let mut settings =
180182
settings::LinterSettings::for_rules(vec![Rule::UnusedNOQA, Rule::UnusedImport]);
181183

182-
settings.per_file_ignores = PerFileIgnores::resolve(vec![PerFileIgnore::new(
184+
settings.per_file_ignores = CompiledPerFileIgnoreList::resolve(vec![PerFileIgnore::new(
183185
"RUF100_2.py".to_string(),
184186
&["F401".parse().unwrap()],
185187
None,
@@ -236,7 +238,7 @@ mod tests {
236238
let diagnostics = test_path(
237239
Path::new("ruff/ruff_per_file_ignores.py"),
238240
&settings::LinterSettings {
239-
per_file_ignores: PerFileIgnores::resolve(vec![PerFileIgnore::new(
241+
per_file_ignores: CompiledPerFileIgnoreList::resolve(vec![PerFileIgnore::new(
240242
"ruff_per_file_ignores.py".to_string(),
241243
&["F401".parse().unwrap(), "RUF100".parse().unwrap()],
242244
None,

crates/ruff_linter/src/settings/mod.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ use crate::rules::{
2222
flake8_self, flake8_tidy_imports, flake8_type_checking, flake8_unused_arguments, isort, mccabe,
2323
pep8_naming, pycodestyle, pydocstyle, pyflakes, pylint, pyupgrade,
2424
};
25-
use crate::settings::types::{ExtensionMapping, FilePatternSet, PerFileIgnores, PythonVersion};
25+
use crate::settings::types::{
26+
CompiledPerFileIgnoreList, ExtensionMapping, FilePatternSet, PythonVersion,
27+
};
2628
use crate::{codes, RuleSelector};
2729

2830
use super::line_width::IndentWidth;
@@ -129,6 +131,9 @@ macro_rules! display_settings {
129131
(@field $fmt:ident, $prefix:ident, $settings:ident.$field:ident | quoted) => {
130132
writeln!($fmt, "{}{} = \"{}\"", $prefix, stringify!($field), $settings.$field)?;
131133
};
134+
(@field $fmt:ident, $prefix:ident, $settings:ident.$field:ident | globmatcher) => {
135+
writeln!($fmt, "{}{} = \"{}\"", $prefix, stringify!($field), $settings.$field.glob())?;
136+
};
132137
(@field $fmt:ident, $prefix:ident, $settings:ident.$field:ident | nested) => {
133138
write!($fmt, "{}", $settings.$field)?;
134139
};
@@ -213,7 +218,7 @@ pub struct LinterSettings {
213218
pub project_root: PathBuf,
214219

215220
pub rules: RuleTable,
216-
pub per_file_ignores: PerFileIgnores,
221+
pub per_file_ignores: CompiledPerFileIgnoreList,
217222
pub fix_safety: FixSafetyTable,
218223

219224
pub target_version: PythonVersion,
@@ -388,7 +393,7 @@ impl LinterSettings {
388393
logger_objects: vec![],
389394
namespace_packages: vec![],
390395

391-
per_file_ignores: PerFileIgnores::default(),
396+
per_file_ignores: CompiledPerFileIgnoreList::default(),
392397
fix_safety: FixSafetyTable::default(),
393398

394399
src: vec![path_dedot::CWD.clone()],

crates/ruff_linter/src/settings/types.rs

+41-21
Original file line numberDiff line numberDiff line change
@@ -600,57 +600,77 @@ impl Display for RequiredVersion {
600600
/// pattern matching.
601601
pub type IdentifierPattern = glob::Pattern;
602602

603+
#[derive(Debug, Clone, CacheKey)]
604+
pub struct CompiledPerFileIgnore {
605+
pub absolute_matcher: GlobMatcher,
606+
pub basename_matcher: GlobMatcher,
607+
pub negated: bool,
608+
pub rules: RuleSet,
609+
}
610+
611+
impl Display for CompiledPerFileIgnore {
612+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
613+
display_settings! {
614+
formatter = f,
615+
fields = [
616+
self.absolute_matcher | globmatcher,
617+
self.basename_matcher | globmatcher,
618+
self.negated,
619+
self.rules,
620+
]
621+
}
622+
Ok(())
623+
}
624+
}
625+
603626
#[derive(Debug, Clone, CacheKey, Default)]
604-
pub struct PerFileIgnores {
627+
pub struct CompiledPerFileIgnoreList {
605628
// Ordered as (absolute path matcher, basename matcher, rules)
606-
ignores: Vec<(GlobMatcher, GlobMatcher, bool, RuleSet)>,
629+
ignores: Vec<CompiledPerFileIgnore>,
607630
}
608631

609-
impl PerFileIgnores {
632+
impl CompiledPerFileIgnoreList {
610633
/// Given a list of patterns, create a `GlobSet`.
611634
pub fn resolve(per_file_ignores: Vec<PerFileIgnore>) -> Result<Self> {
612635
let ignores: Result<Vec<_>> = per_file_ignores
613636
.into_iter()
614637
.map(|per_file_ignore| {
615638
// Construct absolute path matcher.
616-
let absolute =
639+
let absolute_matcher =
617640
Glob::new(&per_file_ignore.absolute.to_string_lossy())?.compile_matcher();
618641

619642
// Construct basename matcher.
620-
let basename = Glob::new(&per_file_ignore.basename)?.compile_matcher();
621-
622-
Ok((
623-
absolute,
624-
basename,
625-
per_file_ignore.negated,
626-
per_file_ignore.rules,
627-
))
643+
let basename_matcher = Glob::new(&per_file_ignore.basename)?.compile_matcher();
644+
645+
Ok(CompiledPerFileIgnore {
646+
absolute_matcher,
647+
basename_matcher,
648+
negated: per_file_ignore.negated,
649+
rules: per_file_ignore.rules,
650+
})
628651
})
629652
.collect();
630653
Ok(Self { ignores: ignores? })
631654
}
632655
}
633656

634-
impl Display for PerFileIgnores {
657+
impl Display for CompiledPerFileIgnoreList {
635658
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
636-
if self.is_empty() {
659+
if self.ignores.is_empty() {
637660
write!(f, "{{}}")?;
638661
} else {
639662
writeln!(f, "{{")?;
640-
for (absolute, basename, negated, rules) in &self.ignores {
641-
writeln!(
642-
f,
643-
"\t{{ absolute = {absolute:#?}, basename = {basename:#?}, negated = {negated:#?}, rules = {rules} }},"
644-
)?;
663+
for ignore in &self.ignores {
664+
writeln!(f, "\t{ignore}")?;
645665
}
646666
write!(f, "}}")?;
647667
}
648668
Ok(())
649669
}
650670
}
651671

652-
impl Deref for PerFileIgnores {
653-
type Target = Vec<(GlobMatcher, GlobMatcher, bool, RuleSet)>;
672+
impl Deref for CompiledPerFileIgnoreList {
673+
type Target = Vec<CompiledPerFileIgnore>;
654674

655675
fn deref(&self) -> &Self::Target {
656676
&self.ignores

crates/ruff_workspace/src/configuration.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ use ruff_linter::rules::pycodestyle;
2727
use ruff_linter::settings::fix_safety_table::FixSafetyTable;
2828
use ruff_linter::settings::rule_table::RuleTable;
2929
use ruff_linter::settings::types::{
30-
ExtensionMapping, FilePattern, FilePatternSet, PerFileIgnore, PerFileIgnores, PreviewMode,
31-
PythonVersion, RequiredVersion, SerializationFormat, UnsafeFixes,
30+
CompiledPerFileIgnoreList, ExtensionMapping, FilePattern, FilePatternSet, PerFileIgnore,
31+
PreviewMode, PythonVersion, RequiredVersion, SerializationFormat, UnsafeFixes,
3232
};
3333
use ruff_linter::settings::{LinterSettings, DEFAULT_SELECTORS, DUMMY_VARIABLE_RGX, TASK_TAGS};
3434
use ruff_linter::{
@@ -259,7 +259,7 @@ impl Configuration {
259259
line_length,
260260
tab_size: self.indent_width.unwrap_or_default(),
261261
namespace_packages: self.namespace_packages.unwrap_or_default(),
262-
per_file_ignores: PerFileIgnores::resolve(
262+
per_file_ignores: CompiledPerFileIgnoreList::resolve(
263263
lint.per_file_ignores
264264
.unwrap_or_default()
265265
.into_iter()

0 commit comments

Comments
 (0)