-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Remove Message::to_rule
#18447
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
Remove Message::to_rule
#18447
Conversation
|
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.
Thank you. This is great. I think we can avoid the from_code
in a few more places, but this, overall looks good
crates/ruff/src/printer.rs
Outdated
rule.noqa_code().to_string().red().bold(), | ||
rule.as_ref(), | ||
code.red().bold(), | ||
Rule::from_code(&code).map_or(code, |rule| rule.to_string()), |
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.
Does rule.to_string
return the rule name? I'm inclined to change FixTable
to a map from noqa
to (name, usize)
. This removes the need to lookup the rule.
let code_str = code.to_string(); | ||
// This is a manual re-implementation of Rule::from_code, but we also want the Linter. This | ||
// avoids calling Linter::parse_code twice. | ||
let (linter, suffix) = Linter::parse_code(&code_str).unwrap(); |
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.
It's a bit silly that parse_code
strips the prefix again, when NoqaCode
already has the prefix. If not too hard, would it make sense to add a parse_noqa
method that matches on code.prefix()
?
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 looked into this a bit last week, and the tricky thing is that despite NoqaCode
having two &'static str
s and a prefix
and suffix
method, they don't always do what you expect because in cases with multiple common prefixes (at least I think this is the cause, from what I remember) the "prefix" will actually be empty and the whole code is in the "suffix." That's why parse_code
is implemented like this, I think.
This is also what I was trying to work around with my proc macro changes in #18391.
Here's the macro code for generating the common_prefix
method:
ruff/crates/ruff_macros/src/rule_namespace.rs
Lines 89 to 96 in 43277a1
if let [prefix] = &prefixes[..] { | |
common_prefix_match_arms.extend(quote! { Self::#variant_ident => #prefix, }); | |
} else { | |
// There is more than one prefix. We already previously asserted | |
// that prefixes of the same variant don't start with the same character | |
// so the common prefix for this variant is the empty string. | |
common_prefix_match_arms.extend(quote! { Self::#variant_ident => "", }); | |
} |
And then the construction of NoqaCode
s uses it:
ruff/crates/ruff_macros/src/map_codes.rs
Lines 291 to 293 in 43277a1
rule_noqa_code_match_arms.extend(quote! { | |
#(#attrs)* Rule::#rule_name => NoqaCode(crate::registry::Linter::#linter.common_prefix(), #code), | |
}); |
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 think your idea about storing a single &str
and a usize
here might help, but it's still a bit tricky to get everything into a single &'static str
. We might still need my const
tricks from the other PR to concat!
them here.
Here a patch for adding a Patchdiff --git a/crates/ruff/src/commands/rule.rs b/crates/ruff/src/commands/rule.rs
index 45b071d2e..adc761b3e 100644
--- a/crates/ruff/src/commands/rule.rs
+++ b/crates/ruff/src/commands/rule.rs
@@ -30,7 +30,7 @@ impl<'a> Explanation<'a> {
let (linter, _) = Linter::parse_code(&code).unwrap();
let fix = rule.fixable().to_string();
Self {
- name: rule.as_ref(),
+ name: rule.name().as_str(),
code,
linter: linter.name(),
summary: rule.message_formats()[0],
@@ -44,7 +44,7 @@ impl<'a> Explanation<'a> {
fn format_rule_text(rule: Rule) -> String {
let mut output = String::new();
- let _ = write!(&mut output, "# {} ({})", rule.as_ref(), rule.noqa_code());
+ let _ = write!(&mut output, "# {} ({})", rule.name(), rule.noqa_code());
output.push('\n');
output.push('\n');
diff --git a/crates/ruff_dev/src/generate_docs.rs b/crates/ruff_dev/src/generate_docs.rs
index d191e8264..5f2309328 100644
--- a/crates/ruff_dev/src/generate_docs.rs
+++ b/crates/ruff_dev/src/generate_docs.rs
@@ -29,7 +29,7 @@ pub(crate) fn main(args: &Args) -> Result<()> {
if let Some(explanation) = rule.explanation() {
let mut output = String::new();
- let _ = writeln!(&mut output, "# {} ({})", rule.as_ref(), rule.noqa_code());
+ let _ = writeln!(&mut output, "# {} ({})", rule.name(), rule.noqa_code());
let (linter, _) = Linter::parse_code(&rule.noqa_code().to_string()).unwrap();
if linter.url().is_some() {
@@ -101,7 +101,7 @@ pub(crate) fn main(args: &Args) -> Result<()> {
let filename = PathBuf::from(ROOT_DIR)
.join("docs")
.join("rules")
- .join(rule.as_ref())
+ .join(&*rule.name())
.with_extension("md");
if args.dry_run {
diff --git a/crates/ruff_dev/src/generate_rules_table.rs b/crates/ruff_dev/src/generate_rules_table.rs
index 48b1cdc2c..3255f8f42 100644
--- a/crates/ruff_dev/src/generate_rules_table.rs
+++ b/crates/ruff_dev/src/generate_rules_table.rs
@@ -55,7 +55,7 @@ fn generate_table(table_out: &mut String, rules: impl IntoIterator<Item = Rule>,
FixAvailability::None => format!("<span {SYMBOL_STYLE}></span>"),
};
- let rule_name = rule.as_ref();
+ let rule_name = rule.name();
// If the message ends in a bracketed expression (like: "Use {replacement}"), escape the
// brackets. Otherwise, it'll be interpreted as an HTML attribute via the `attr_list`
diff --git a/crates/ruff_linter/src/codes.rs b/crates/ruff_linter/src/codes.rs
index fafb840a0..c31e989a4 100644
--- a/crates/ruff_linter/src/codes.rs
+++ b/crates/ruff_linter/src/codes.rs
@@ -4,7 +4,7 @@
/// `--select`. For pylint this is e.g. C0414 and E0118 but also C and E01.
use std::fmt::Formatter;
-use strum_macros::{AsRefStr, EnumIter};
+use strum_macros::EnumIter;
use crate::registry::Linter;
use crate::rule_selector::is_single_rule_selector;
diff --git a/crates/ruff_linter/src/logging.rs b/crates/ruff_linter/src/logging.rs
index dadf6ce25..b59c63737 100644
--- a/crates/ruff_linter/src/logging.rs
+++ b/crates/ruff_linter/src/logging.rs
@@ -20,7 +20,7 @@ pub static IDENTIFIERS: LazyLock<Mutex<Vec<&'static str>>> = LazyLock::new(Mutex
/// Warn a user once, with uniqueness determined by the given ID.
#[macro_export]
macro_rules! warn_user_once_by_id {
- ($id:expr, $($arg:tt)*) => {
+ ($id:expr, $($arg:tt)*) => {{
use colored::Colorize;
use log::warn;
@@ -31,7 +31,7 @@ macro_rules! warn_user_once_by_id {
states.push($id);
}
}
- };
+ }};
}
pub static MESSAGES: LazyLock<Mutex<FxHashSet<String>>> = LazyLock::new(Mutex::default);
diff --git a/crates/ruff_linter/src/registry.rs b/crates/ruff_linter/src/registry.rs
index 9b03a8b7f..2f8a92324 100644
--- a/crates/ruff_linter/src/registry.rs
+++ b/crates/ruff_linter/src/registry.rs
@@ -1,6 +1,7 @@
//! Remnant of the registry of all [`Rule`] implementations, now it's reexporting from codes.rs
//! with some helper symbols
+use ruff_db::diagnostic::LintName;
use strum_macros::EnumIter;
pub use codes::Rule;
@@ -348,9 +349,18 @@ impl Rule {
/// Return the URL for the rule documentation, if it exists.
pub fn url(&self) -> Option<String> {
- self.explanation()
- .is_some()
- .then(|| format!("{}/rules/{}", env!("CARGO_PKG_HOMEPAGE"), self.as_ref()))
+ self.explanation().is_some().then(|| {
+ format!(
+ "{}/rules/{name}",
+ env!("CARGO_PKG_HOMEPAGE"),
+ name = self.name()
+ )
+ })
+ }
+
+ pub fn name(&self) -> LintName {
+ let name: &'static str = self.into();
+ LintName::of(name)
}
}
@@ -421,7 +431,7 @@ pub mod clap_completion {
fn possible_values(&self) -> Option<Box<dyn Iterator<Item = PossibleValue> + '_>> {
Some(Box::new(Rule::iter().map(|rule| {
let name = rule.noqa_code().to_string();
- let help = rule.as_ref().to_string();
+ let help: &'static str = rule.into();
PossibleValue::new(name).help(help)
})))
}
@@ -443,7 +453,7 @@ mod tests {
assert!(
rule.explanation().is_some(),
"Rule {} is missing documentation",
- rule.as_ref()
+ rule.name()
);
}
}
@@ -460,10 +470,10 @@ mod tests {
.collect();
for rule in Rule::iter() {
- let rule_name = rule.as_ref();
+ let rule_name = rule.name();
for pattern in &patterns {
assert!(
- !pattern.matches(rule_name),
+ !pattern.matches(&*rule_name),
"{rule_name} does not match naming convention, see CONTRIBUTING.md"
);
}
diff --git a/crates/ruff_linter/src/registry/rule_set.rs b/crates/ruff_linter/src/registry/rule_set.rs
index d83ff0771..62601d722 100644
--- a/crates/ruff_linter/src/registry/rule_set.rs
+++ b/crates/ruff_linter/src/registry/rule_set.rs
@@ -302,9 +302,8 @@ impl Display for RuleSet {
} else {
writeln!(f, "[")?;
for rule in self {
- let name = rule.as_ref();
let code = rule.noqa_code();
- writeln!(f, "\t{name} ({code}),")?;
+ writeln!(f, "\t{name} ({code}),", name = rule.name())?;
}
write!(f, "]")?;
}
diff --git a/crates/ruff_linter/src/rule_selector.rs b/crates/ruff_linter/src/rule_selector.rs
index 7588aa9f6..74f069b97 100644
--- a/crates/ruff_linter/src/rule_selector.rs
+++ b/crates/ruff_linter/src/rule_selector.rs
@@ -485,8 +485,7 @@ pub mod clap_completion {
prefix.linter().common_prefix(),
prefix.short_code()
);
- let name: &'static str = rule.into();
- return Some(PossibleValue::new(code).help(name));
+ return Some(PossibleValue::new(code).help(rule.name().as_str()));
}
None
diff --git a/crates/ruff_linter/src/rules/fastapi/mod.rs b/crates/ruff_linter/src/rules/fastapi/mod.rs
index 90f52b7d6..60f180973 100644
--- a/crates/ruff_linter/src/rules/fastapi/mod.rs
+++ b/crates/ruff_linter/src/rules/fastapi/mod.rs
@@ -3,7 +3,6 @@ pub(crate) mod rules;
#[cfg(test)]
mod tests {
- use std::convert::AsRef;
use std::path::Path;
use anyhow::Result;
@@ -18,7 +17,7 @@ mod tests {
#[test_case(Rule::FastApiNonAnnotatedDependency, Path::new("FAST002_1.py"))]
#[test_case(Rule::FastApiUnusedPathParameter, Path::new("FAST003.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("fastapi").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code),
@@ -32,7 +31,7 @@ mod tests {
#[test_case(Rule::FastApiNonAnnotatedDependency, Path::new("FAST002_0.py"))]
#[test_case(Rule::FastApiNonAnnotatedDependency, Path::new("FAST002_1.py"))]
fn rules_py38(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}_py38", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}_py38", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("fastapi").join(path).as_path(),
&settings::LinterSettings {
diff --git a/crates/ruff_linter/src/rules/flake8_fixme/mod.rs b/crates/ruff_linter/src/rules/flake8_fixme/mod.rs
index d2433fc8b..44071d1b7 100644
--- a/crates/ruff_linter/src/rules/flake8_fixme/mod.rs
+++ b/crates/ruff_linter/src/rules/flake8_fixme/mod.rs
@@ -16,7 +16,7 @@ mod tests {
#[test_case(Rule::LineContainsTodo; "T003")]
#[test_case(Rule::LineContainsXxx; "T004")]
fn rules(rule_code: Rule) -> Result<()> {
- let snapshot = format!("{}_T00.py", rule_code.as_ref());
+ let snapshot = format!("{}_T00.py", rule_code.name());
let diagnostics = test_path(
Path::new("flake8_fixme/T00.py"),
&settings::LinterSettings::for_rule(rule_code),
diff --git a/crates/ruff_linter/src/rules/flake8_gettext/mod.rs b/crates/ruff_linter/src/rules/flake8_gettext/mod.rs
index 09d440526..cd385932a 100644
--- a/crates/ruff_linter/src/rules/flake8_gettext/mod.rs
+++ b/crates/ruff_linter/src/rules/flake8_gettext/mod.rs
@@ -29,7 +29,7 @@ mod tests {
#[test_case(Rule::FormatInGetTextFuncCall, Path::new("INT002.py"))]
#[test_case(Rule::PrintfInGetTextFuncCall, Path::new("INT003.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("flake8_gettext").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code),
diff --git a/crates/ruff_linter/src/rules/flake8_raise/mod.rs b/crates/ruff_linter/src/rules/flake8_raise/mod.rs
index d2d636b1e..178045453 100644
--- a/crates/ruff_linter/src/rules/flake8_raise/mod.rs
+++ b/crates/ruff_linter/src/rules/flake8_raise/mod.rs
@@ -3,7 +3,6 @@ pub(crate) mod rules;
#[cfg(test)]
mod tests {
- use std::convert::AsRef;
use std::path::Path;
use anyhow::Result;
@@ -15,7 +14,7 @@ mod tests {
#[test_case(Rule::UnnecessaryParenOnRaiseException, Path::new("RSE102.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("flake8_raise").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code),
diff --git a/crates/ruff_linter/src/rules/flake8_self/mod.rs b/crates/ruff_linter/src/rules/flake8_self/mod.rs
index a445b40ba..7a3f83ddd 100644
--- a/crates/ruff_linter/src/rules/flake8_self/mod.rs
+++ b/crates/ruff_linter/src/rules/flake8_self/mod.rs
@@ -4,7 +4,6 @@ pub mod settings;
#[cfg(test)]
mod tests {
- use std::convert::AsRef;
use std::path::Path;
use crate::registry::Rule;
@@ -18,7 +17,7 @@ mod tests {
#[test_case(Rule::PrivateMemberAccess, Path::new("SLF001.py"))]
#[test_case(Rule::PrivateMemberAccess, Path::new("SLF001_1.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("flake8_self").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code),
diff --git a/crates/ruff_linter/src/rules/flake8_todos/mod.rs b/crates/ruff_linter/src/rules/flake8_todos/mod.rs
index 7a4129a78..486c46af0 100644
--- a/crates/ruff_linter/src/rules/flake8_todos/mod.rs
+++ b/crates/ruff_linter/src/rules/flake8_todos/mod.rs
@@ -2,7 +2,6 @@ pub(crate) mod rules;
#[cfg(test)]
mod tests {
- use std::convert::AsRef;
use std::path::Path;
use anyhow::Result;
@@ -20,7 +19,7 @@ mod tests {
#[test_case(Rule::InvalidTodoCapitalization, Path::new("TD006.py"))]
#[test_case(Rule::MissingSpaceAfterTodoColon, Path::new("TD007.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("flake8_todos").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code),
diff --git a/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs b/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs
index f5b777ec4..acdb788f5 100644
--- a/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs
+++ b/crates/ruff_linter/src/rules/flake8_type_checking/mod.rs
@@ -6,7 +6,6 @@ pub mod settings;
#[cfg(test)]
mod tests {
- use std::convert::AsRef;
use std::path::Path;
use anyhow::Result;
@@ -55,7 +54,7 @@ mod tests {
#[test_case(Rule::TypingOnlyThirdPartyImport, Path::new("typing_modules_1.py"))]
#[test_case(Rule::TypingOnlyThirdPartyImport, Path::new("typing_modules_2.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("flake8_type_checking").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code),
@@ -70,7 +69,7 @@ mod tests {
#[test_case(Rule::QuotedTypeAlias, Path::new("TC008.py"))]
#[test_case(Rule::QuotedTypeAlias, Path::new("TC008_typing_execution_context.py"))]
fn type_alias_rules(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("flake8_type_checking").join(path).as_path(),
&settings::LinterSettings::for_rules(vec![
@@ -84,11 +83,7 @@ mod tests {
#[test_case(Rule::QuotedTypeAlias, Path::new("TC008_union_syntax_pre_py310.py"))]
fn type_alias_rules_pre_py310(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!(
- "pre_py310_{}_{}",
- rule_code.as_ref(),
- path.to_string_lossy()
- );
+ let snapshot = format!("pre_py310_{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("flake8_type_checking").join(path).as_path(),
&settings::LinterSettings {
@@ -107,7 +102,7 @@ mod tests {
#[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("quote3.py"))]
#[test_case(Rule::TypingOnlyThirdPartyImport, Path::new("quote3.py"))]
fn quote(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("quote_{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("quote_{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("flake8_type_checking").join(path).as_path(),
&settings::LinterSettings {
@@ -126,7 +121,7 @@ mod tests {
#[test_case(Rule::TypingOnlyStandardLibraryImport, Path::new("init_var.py"))]
#[test_case(Rule::TypingOnlyStandardLibraryImport, Path::new("kw_only.py"))]
fn strict(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("strict_{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("strict_{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("flake8_type_checking").join(path).as_path(),
&settings::LinterSettings {
@@ -170,7 +165,7 @@ mod tests {
Path::new("exempt_type_checking_3.py")
)]
fn exempt_type_checking(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("flake8_type_checking").join(path).as_path(),
&settings::LinterSettings {
@@ -207,7 +202,7 @@ mod tests {
Path::new("runtime_evaluated_base_classes_5.py")
)]
fn runtime_evaluated_base_classes(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("flake8_type_checking").join(path).as_path(),
&settings::LinterSettings {
@@ -238,7 +233,7 @@ mod tests {
Path::new("runtime_evaluated_decorators_3.py")
)]
fn runtime_evaluated_decorators(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("flake8_type_checking").join(path).as_path(),
&settings::LinterSettings {
@@ -264,7 +259,7 @@ mod tests {
Path::new("module/undefined.py")
)]
fn base_class_same_file(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("flake8_type_checking").join(path).as_path(),
&settings::LinterSettings {
@@ -282,7 +277,7 @@ mod tests {
#[test_case(Rule::RuntimeImportInTypeCheckingBlock, Path::new("module/app.py"))]
#[test_case(Rule::TypingOnlyStandardLibraryImport, Path::new("module/routes.py"))]
fn decorator_same_file(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("flake8_type_checking").join(path).as_path(),
&settings::LinterSettings {
diff --git a/crates/ruff_linter/src/rules/numpy/mod.rs b/crates/ruff_linter/src/rules/numpy/mod.rs
index 7a313eac2..9403f2501 100644
--- a/crates/ruff_linter/src/rules/numpy/mod.rs
+++ b/crates/ruff_linter/src/rules/numpy/mod.rs
@@ -4,7 +4,6 @@ pub(crate) mod rules;
#[cfg(test)]
mod tests {
- use std::convert::AsRef;
use std::path::Path;
use anyhow::Result;
@@ -22,7 +21,7 @@ mod tests {
#[test_case(Rule::Numpy2Deprecation, Path::new("NPY201_2.py"))]
#[test_case(Rule::Numpy2Deprecation, Path::new("NPY201_3.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("numpy").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code),
diff --git a/crates/ruff_linter/src/rules/pydoclint/mod.rs b/crates/ruff_linter/src/rules/pydoclint/mod.rs
index af4131e42..6e2ff9402 100644
--- a/crates/ruff_linter/src/rules/pydoclint/mod.rs
+++ b/crates/ruff_linter/src/rules/pydoclint/mod.rs
@@ -4,7 +4,6 @@ pub mod settings;
#[cfg(test)]
mod tests {
- use std::convert::AsRef;
use std::path::Path;
use anyhow::Result;
@@ -20,7 +19,7 @@ mod tests {
#[test_case(Rule::DocstringMissingException, Path::new("DOC501.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("pydoclint").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code),
@@ -36,7 +35,7 @@ mod tests {
#[test_case(Rule::DocstringMissingException, Path::new("DOC501_google.py"))]
#[test_case(Rule::DocstringExtraneousException, Path::new("DOC502_google.py"))]
fn rules_google_style(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("pydoclint").join(path).as_path(),
&settings::LinterSettings {
@@ -58,7 +57,7 @@ mod tests {
#[test_case(Rule::DocstringMissingException, Path::new("DOC501_numpy.py"))]
#[test_case(Rule::DocstringExtraneousException, Path::new("DOC502_numpy.py"))]
fn rules_numpy_style(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("pydoclint").join(path).as_path(),
&settings::LinterSettings {
@@ -79,7 +78,7 @@ mod tests {
fn rules_google_style_ignore_one_line(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!(
"{}_{}_ignore_one_line",
- rule_code.as_ref(),
+ rule_code.name(),
path.to_string_lossy()
);
let diagnostics = test_path(
diff --git a/crates/ruff_linter/src/rules/tryceratops/mod.rs b/crates/ruff_linter/src/rules/tryceratops/mod.rs
index 21f3a0138..8d431aae6 100644
--- a/crates/ruff_linter/src/rules/tryceratops/mod.rs
+++ b/crates/ruff_linter/src/rules/tryceratops/mod.rs
@@ -4,7 +4,6 @@ pub(crate) mod rules;
#[cfg(test)]
mod tests {
- use std::convert::AsRef;
use std::path::Path;
use anyhow::Result;
@@ -25,7 +24,7 @@ mod tests {
#[test_case(Rule::ErrorInsteadOfException, Path::new("TRY400.py"))]
#[test_case(Rule::VerboseLogMessage, Path::new("TRY401.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
- let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
+ let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("tryceratops").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code),
diff --git a/crates/ruff_macros/src/map_codes.rs b/crates/ruff_macros/src/map_codes.rs
index 7d1ccaf02..39993af6a 100644
--- a/crates/ruff_macros/src/map_codes.rs
+++ b/crates/ruff_macros/src/map_codes.rs
@@ -174,7 +174,7 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result<TokenStream> {
output.extend(quote! {
impl #linter {
- pub fn rules(&self) -> ::std::vec::IntoIter<Rule> {
+ pub(crate) fn rules(&self) -> ::std::vec::IntoIter<Rule> {
match self { #prefix_into_iter_match_arms }
}
}
@@ -182,7 +182,7 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result<TokenStream> {
}
output.extend(quote! {
impl RuleCodePrefix {
- pub fn parse(linter: &Linter, code: &str) -> Result<Self, crate::registry::FromCodeError> {
+ pub(crate) fn parse(linter: &Linter, code: &str) -> Result<Self, crate::registry::FromCodeError> {
use std::str::FromStr;
Ok(match linter {
@@ -190,7 +190,7 @@ pub(crate) fn map_codes(func: &ItemFn) -> syn::Result<TokenStream> {
})
}
- pub fn rules(&self) -> ::std::vec::IntoIter<Rule> {
+ pub(crate) fn rules(&self) -> ::std::vec::IntoIter<Rule> {
match self {
#(RuleCodePrefix::#linter_idents(prefix) => prefix.clone().rules(),)*
}
@@ -319,7 +319,7 @@ See also https://github.com/astral-sh/ruff/issues/2186.
matches!(self.group(), RuleGroup::Preview)
}
- pub fn is_stable(&self) -> bool {
+ pub(crate) fn is_stable(&self) -> bool {
matches!(self.group(), RuleGroup::Stable)
}
@@ -371,7 +371,7 @@ fn generate_iter_impl(
quote! {
impl Linter {
/// Rules not in the preview.
- pub fn rules(self: &Linter) -> ::std::vec::IntoIter<Rule> {
+ pub(crate) fn rules(self: &Linter) -> ::std::vec::IntoIter<Rule> {
match self {
#linter_rules_match_arms
}
@@ -385,7 +385,7 @@ fn generate_iter_impl(
}
impl RuleCodePrefix {
- pub fn iter() -> impl Iterator<Item = RuleCodePrefix> {
+ pub(crate) fn iter() -> impl Iterator<Item = RuleCodePrefix> {
use strum::IntoEnumIterator;
let mut prefixes = Vec::new();
@@ -436,7 +436,6 @@ fn register_rules<'a>(input: impl Iterator<Item = &'a Rule>) -> TokenStream {
PartialOrd,
Ord,
::ruff_macros::CacheKey,
- AsRefStr,
::strum_macros::IntoStaticStr,
::strum_macros::EnumString,
::serde::Serialize,
diff --git a/crates/ruff_server/src/server/api/requests/hover.rs b/crates/ruff_server/src/server/api/requests/hover.rs
index 6b391e15b..846f3654c 100644
--- a/crates/ruff_server/src/server/api/requests/hover.rs
+++ b/crates/ruff_server/src/server/api/requests/hover.rs
@@ -85,7 +85,7 @@ pub(crate) fn hover(
fn format_rule_text(rule: Rule) -> String {
let mut output = String::new();
- let _ = write!(&mut output, "# {} ({})", rule.as_ref(), rule.noqa_code());
+ let _ = write!(&mut output, "# {} ({})", rule.name(), rule.noqa_code());
output.push('\n');
output.push('\n');
diff --git a/crates/ruff_workspace/src/configuration.rs b/crates/ruff_workspace/src/configuration.rs
index 684a2b434..ae0d23150 100644
--- a/crates/ruff_workspace/src/configuration.rs
+++ b/crates/ruff_workspace/src/configuration.rs
@@ -1098,7 +1098,7 @@ impl LintConfiguration {
// approach to give each pair it's own `warn_user_once`.
for (preferred, expendable, message) in INCOMPATIBLE_CODES {
if rules.enabled(*preferred) && rules.enabled(*expendable) {
- warn_user_once_by_id!(expendable.as_ref(), "{}", message);
+ warn_user_once_by_id!(expendable.name().as_str(), "{}", message);
rules.disable(*expendable);
}
} IMO, it improves readability over the |
Thanks for the patch! I also got confused a couple times by the various options but hadn't tried to fix it. This should help a lot. |
@@ -149,7 +149,7 @@ impl SarifResult { | |||
let end_location = message.compute_end_location(); | |||
let path = normalize_path(&*message.filename()); | |||
Ok(Self { | |||
code: message.to_noqa_code(), | |||
code: message.noqa_code(), |
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.
How do you feel about moving the cfg
attrs here just to the uri
attribute? Or alternatively something like
let uri = cfg!(target_arch = "wasm32") {
path.display().to_string()
} else {
url::Url::from_file_path(&path)
.map_err(|()| anyhow::anyhow!("Failed to convert path to URL: {}", path.display()))?
.to_string()
};
That's the only difference between these two from_message
implementations. I guess it's pretty minor in this case, but I'm curious about your thoughts in general. I've managed to forget to update the wasm version at least twice in this PR.
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 don't know if you can use the inline cfg
but I'm definetely in favor of reducing unnecessary code duplication
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.
Ah you're right. Url::from_file_path
isn't available on WASM. I'll just leave it alone for now, but good to know. Thanks!
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.
The easiest would be to extract the URI conversion into it's own function and gate that
## Summary This is a spin-off from #18447 (comment) to avoid using `Message::noqa_code` to differentiate between lints and syntax errors. I went through all of the calls on `main` and on the branch from #18447, and the instance in `ruff_server` noted in the linked comment was actually the primary place where this was being done. Other calls to `noqa_code` are typically some variation of `message.noqa_code().map_or(String::new, format!(...))`, with the major exception of the gitlab output format: https://github.com/astral-sh/ruff/blob/a120610b5b01a9e7bb91740a23f6c2b5bbcd4b5f/crates/ruff_linter/src/message/gitlab.rs#L93-L105 which obviously assumes that `None` means syntax error. A simple fix here would be to use `message.name()` for `check_name` instead of the noqa code, but I'm not sure how breaking that would be. This could just be: ```rust let description = message.body(); let description = description.strip_prefix("SyntaxError: ").unwrap_or(description).to_string(); let check_name = message.name(); ``` In that case. This sounds reasonable based on the [Code Quality report format](https://docs.gitlab.com/ci/testing/code_quality/#code-quality-report-format) docs: > | Name | Type | Description| > |-----|-----|----| > |`check_name` | String | A unique name representing the check, or rule, associated with this violation. | ## Test Plan Existing tests
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.
Nice cleanup in this commit!
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.
Thank you!
Summary
As the title says, this PR removes the
Message::to_rule
method by replacing related uses ofRule
withNoqaCode
(or the rule's name in the case of the cache). Where it seemed aRule
was really needed, we convert back to theRule
by parsing either the rule name (withstr::parse
) or theNoqaCode
(withRule::from_code
).I thought this was kind of like cheating and that it might not resolve this part of Micha's comment:
but after looking again, the only remaining
Rule
conversion in rendering code is for the SARIF output format. The other two non-testRule
conversions are for caching and writing a fix summary, which I don't think fall into the shared rendering logic. That leaves the SARIF format as the only real problem, but maybe we can delay that for now.The motivation here is that we won't be able to store a
Rule
on the newDiagnostic
type, but we should be able to store aNoqaCode
, likely as a string.Test Plan
Existing tests
Benchmarks
Almost no perf regression, only -1% on
linter/default-rules[large/dataset.py]
.