-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Update rule selection to respect preview mode #7195
Changes from 1 commit
9b4aee1
8fce454
c527f69
a954fd6
2e44d66
51bce02
1689190
2c830e2
f111189
e6d491a
97b80c0
2b0dfd6
359012a
b60ce8b
950bd95
ae80063
5ae0075
a5200ed
83d888f
45ceb6a
cb47f02
2d8f961
550f787
c581006
f628e95
c092d62
32b34fa
fbd449a
d94dfd7
e7f095a
b09fbb9
b374802
4ea6f17
2cab8b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,11 @@ pub enum RuleSelector { | |
prefix: RuleCodePrefix, | ||
redirected_from: Option<&'static str>, | ||
}, | ||
/// Select an individual rule with a given prefix. | ||
Rule { | ||
prefix: RuleCodePrefix, | ||
redirected_from: Option<&'static str>, | ||
}, | ||
} | ||
|
||
impl From<Linter> for RuleSelector { | ||
|
@@ -61,16 +66,42 @@ impl FromStr for RuleSelector { | |
return Ok(Self::Linter(linter)); | ||
} | ||
|
||
Ok(Self::Prefix { | ||
prefix: RuleCodePrefix::parse(&linter, code) | ||
.map_err(|_| ParseError::Unknown(s.to_string()))?, | ||
redirected_from, | ||
}) | ||
// Does the selector select a single rule? | ||
let prefix = RuleCodePrefix::parse(&linter, code) | ||
.map_err(|_| ParseError::Unknown(s.to_string()))?; | ||
if is_single_rule_selector(&prefix) { | ||
Ok(Self::Rule { | ||
prefix, | ||
redirected_from, | ||
}) | ||
} else { | ||
Ok(Self::Prefix { | ||
prefix, | ||
redirected_from, | ||
}) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// Returns `true` if the [`RuleCodePrefix`] matches a single rule exactly | ||
/// (e.g., `E225`, as opposed to `E2`). | ||
fn is_single_rule_selector(prefix: &RuleCodePrefix) -> bool { | ||
let mut rules = prefix.rules(); | ||
|
||
// The selector must match a single rule. | ||
let Some(rule) = rules.next() else { | ||
return false; | ||
}; | ||
if rules.next().is_some() { | ||
return false; | ||
} | ||
|
||
// The rule must match the selector exactly. | ||
rule.noqa_code().suffix() == prefix.short_code() | ||
} | ||
|
||
#[derive(Debug, thiserror::Error)] | ||
pub enum ParseError { | ||
#[error("Unknown rule selector: `{0}`")] | ||
|
@@ -86,7 +117,7 @@ impl RuleSelector { | |
RuleSelector::Preview => ("", "PREVIEW"), | ||
RuleSelector::C => ("", "C"), | ||
RuleSelector::T => ("", "T"), | ||
RuleSelector::Prefix { prefix, .. } => { | ||
RuleSelector::Prefix { prefix, .. } | RuleSelector::Rule { prefix, .. } => { | ||
(prefix.linter().common_prefix(), prefix.short_code()) | ||
} | ||
RuleSelector::Linter(l) => (l.common_prefix(), ""), | ||
|
@@ -137,18 +168,9 @@ impl Visitor<'_> for SelectorVisitor { | |
} | ||
} | ||
|
||
impl From<RuleCodePrefix> for RuleSelector { | ||
fn from(prefix: RuleCodePrefix) -> Self { | ||
Self::Prefix { | ||
prefix, | ||
redirected_from: None, | ||
} | ||
} | ||
} | ||
|
||
impl IntoIterator for &RuleSelector { | ||
type IntoIter = RuleSelectorIter; | ||
type Item = Rule; | ||
type IntoIter = RuleSelectorIter; | ||
|
||
fn into_iter(self) -> Self::IntoIter { | ||
match self { | ||
|
@@ -167,7 +189,9 @@ impl IntoIterator for &RuleSelector { | |
.chain(Linter::Flake8Print.rules()), | ||
), | ||
RuleSelector::Linter(linter) => RuleSelectorIter::Vec(linter.rules()), | ||
RuleSelector::Prefix { prefix, .. } => RuleSelectorIter::Vec(prefix.clone().rules()), | ||
RuleSelector::Prefix { prefix, .. } | RuleSelector::Rule { prefix, .. } => { | ||
RuleSelectorIter::Vec(prefix.clone().rules()) | ||
} | ||
} | ||
} | ||
} | ||
|
@@ -270,14 +294,14 @@ impl RuleSelector { | |
RuleSelector::T => Specificity::LinterGroup, | ||
RuleSelector::C => Specificity::LinterGroup, | ||
RuleSelector::Linter(..) => Specificity::Linter, | ||
RuleSelector::Rule { .. } => Specificity::Rule, | ||
RuleSelector::Prefix { prefix, .. } => { | ||
let prefix: &'static str = prefix.short_code(); | ||
match prefix.len() { | ||
1 => Specificity::Code1Char, | ||
2 => Specificity::Code2Chars, | ||
3 => Specificity::Code3Chars, | ||
4 => Specificity::Code4Chars, | ||
5 => Specificity::Code5Chars, | ||
1 => Specificity::Prefix1Char, | ||
2 => Specificity::Prefix2Chars, | ||
3 => Specificity::Prefix3Chars, | ||
4 => Specificity::Prefix4Chars, | ||
_ => panic!("RuleSelector::specificity doesn't yet support codes with so many characters"), | ||
} | ||
} | ||
|
@@ -287,14 +311,22 @@ impl RuleSelector { | |
|
||
#[derive(EnumIter, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Debug)] | ||
pub enum Specificity { | ||
/// The specificity when selecting all rules (e.g., `--select ALL`). | ||
All, | ||
/// The specificity when selecting a linter group (e.g., `--select PL`). | ||
LinterGroup, | ||
/// The specificity when selecting a linter (e.g., `--select PLE` or `--select UP`). | ||
Linter, | ||
Code1Char, | ||
Code2Chars, | ||
Code3Chars, | ||
Code4Chars, | ||
Code5Chars, | ||
/// The specificity when selecting via a rule prefix at one-character depth (e.g., `--select PLE1`). | ||
Prefix1Char, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I got a bit confused with "rule prefix" which made me think of the prefix part of the code i.e., "PLE" in the given example. But I think this is related to the number part, right? Maybe "Suffix1Char"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm well the specificity is that it's a prefix e.g. including "PLE10" but I agree the character count part is confusing since it just refers to the code length. |
||
/// The specificity when selecting via a rule prefix at two-character depth (e.g., `--select PLE12`). | ||
Prefix2Chars, | ||
/// The specificity when selecting via a rule prefix at one-character depth (e.g., `--select PLE120`). | ||
Prefix3Chars, | ||
dhruvmanila marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// The specificity when selecting via a rule prefix at one-character depth (e.g., `--select PLE120`). | ||
Prefix4Chars, | ||
dhruvmanila marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// The specificity when selecting an individual rule (e.g., `--select PLE1205`). | ||
Rule, | ||
} | ||
|
||
#[cfg(feature = "clap")] | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I bet this could be encoded in the type system somehow, this feels awkward (I know that I wrote it lol). Not asking for a change here since it will likely involve more extensive changes in the macro, etc., just expressing that it feels strange.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will open a tracking issue once this is merged