Support code redirects in flake8-to-ruff (#1318)

This commit is contained in:
Charlie Marsh 2022-12-21 19:31:20 -05:00 committed by GitHub
parent 07dba46039
commit 953d141ab2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 329 additions and 60 deletions

View file

@ -275,7 +275,11 @@ mod tests {
#[test] #[test]
fn it_converts_empty() -> Result<()> { fn it_converts_empty() -> Result<()> {
let actual = convert(&HashMap::from([]), None, None)?; let actual = convert(
&HashMap::from([("flake8".to_string(), HashMap::default())]),
None,
None,
)?;
let expected = Pyproject::new(Options { let expected = Pyproject::new(Options {
allowed_confusables: None, allowed_confusables: None,
dummy_variable_rgx: None, dummy_variable_rgx: None,

View file

@ -3,6 +3,7 @@ use std::str::FromStr;
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use regex::Regex; use regex::Regex;
use ruff::checks::PREFIX_REDIRECTS;
use ruff::checks_gen::CheckCodePrefix; use ruff::checks_gen::CheckCodePrefix;
use ruff::settings::types::PatternPrefixPair; use ruff::settings::types::PatternPrefixPair;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
@ -18,7 +19,9 @@ pub fn parse_prefix_codes(value: &str) -> Vec<CheckCodePrefix> {
if code.is_empty() { if code.is_empty() {
continue; continue;
} }
if let Ok(code) = CheckCodePrefix::from_str(code) { if let Some(code) = PREFIX_REDIRECTS.get(code) {
codes.push(code.clone());
} else if let Ok(code) = CheckCodePrefix::from_str(code) {
codes.push(code); codes.push(code);
} else { } else {
eprintln!("Unsupported prefix code: {code}"); eprintln!("Unsupported prefix code: {code}");
@ -83,16 +86,22 @@ impl State {
fn parse(&self) -> Vec<PatternPrefixPair> { fn parse(&self) -> Vec<PatternPrefixPair> {
let mut codes: Vec<PatternPrefixPair> = vec![]; let mut codes: Vec<PatternPrefixPair> = vec![];
for code in &self.codes { for code in &self.codes {
match CheckCodePrefix::from_str(code) { if let Some(code) = PREFIX_REDIRECTS.get(code.as_str()) {
Ok(code) => {
for filename in &self.filenames { for filename in &self.filenames {
codes.push(PatternPrefixPair { codes.push(PatternPrefixPair {
pattern: filename.clone(), pattern: filename.clone(),
prefix: code.clone(), prefix: code.clone(),
}); });
} }
} else if let Ok(code) = CheckCodePrefix::from_str(code) {
for filename in &self.filenames {
codes.push(PatternPrefixPair {
pattern: filename.clone(),
prefix: code.clone(),
});
} }
Err(_) => eprintln!("Skipping unrecognized prefix: {code}"), } else {
eprintln!("Unsupported prefix code: {code}");
} }
} }
codes codes

View file

@ -78,11 +78,11 @@ impl Plugin {
Plugin::Flake8Quotes => CheckCodePrefix::Q, Plugin::Flake8Quotes => CheckCodePrefix::Q,
Plugin::Flake8Return => CheckCodePrefix::RET, Plugin::Flake8Return => CheckCodePrefix::RET,
Plugin::Flake8Simplify => CheckCodePrefix::SIM, Plugin::Flake8Simplify => CheckCodePrefix::SIM,
Plugin::Flake8TidyImports => CheckCodePrefix::I25, Plugin::Flake8TidyImports => CheckCodePrefix::TID25,
Plugin::McCabe => CheckCodePrefix::C9, Plugin::McCabe => CheckCodePrefix::C9,
Plugin::PandasVet => CheckCodePrefix::PD, Plugin::PandasVet => CheckCodePrefix::PD,
Plugin::PEP8Naming => CheckCodePrefix::N, Plugin::PEP8Naming => CheckCodePrefix::N,
Plugin::Pyupgrade => CheckCodePrefix::U, Plugin::Pyupgrade => CheckCodePrefix::UP,
} }
} }
@ -424,7 +424,6 @@ pub fn infer_plugins_from_codes(codes: &BTreeSet<CheckCodePrefix>) -> Vec<Plugin
Plugin::Flake8TidyImports, Plugin::Flake8TidyImports,
Plugin::PandasVet, Plugin::PandasVet,
Plugin::PEP8Naming, Plugin::PEP8Naming,
Plugin::Pyupgrade,
] ]
.into_iter() .into_iter()
.filter(|plugin| { .filter(|plugin| {

View file

@ -10,7 +10,7 @@ use anyhow::{ensure, Result};
use clap::Parser; use clap::Parser;
use codegen::{Scope, Type, Variant}; use codegen::{Scope, Type, Variant};
use itertools::Itertools; use itertools::Itertools;
use ruff::checks::{CheckCode, CODE_REDIRECTS, PREFIX_REDIRECTS}; use ruff::checks::{CheckCode, PREFIX_REDIRECTS};
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
#[derive(Parser)] #[derive(Parser)]
@ -40,18 +40,7 @@ pub fn main(cli: &Cli) -> Result<()> {
} }
// Add any prefix aliases (e.g., "U" to "UP"). // Add any prefix aliases (e.g., "U" to "UP").
for (alias, source) in PREFIX_REDIRECTS.iter() { for (alias, check_code) in PREFIX_REDIRECTS.iter() {
prefix_to_codes.insert(
(*alias).to_string(),
prefix_to_codes
.get(&(*source).to_string())
.unwrap_or_else(|| panic!("Unknown CheckCode: {source:?}"))
.clone(),
);
}
// Add any check code aliases (e.g., "U001" to "UP001").
for (alias, check_code) in CODE_REDIRECTS.iter() {
prefix_to_codes.insert( prefix_to_codes.insert(
(*alias).to_string(), (*alias).to_string(),
prefix_to_codes prefix_to_codes
@ -105,7 +94,7 @@ pub fn main(cli: &Cli) -> Result<()> {
.line("#[allow(clippy::match_same_arms)]") .line("#[allow(clippy::match_same_arms)]")
.line("match self {"); .line("match self {");
for (prefix, codes) in &prefix_to_codes { for (prefix, codes) in &prefix_to_codes {
if let Some(target) = CODE_REDIRECTS.get(&prefix.as_str()) { if let Some(target) = PREFIX_REDIRECTS.get(&prefix.as_str()) {
gen = gen.line(format!( gen = gen.line(format!(
"CheckCodePrefix::{prefix} => {{ one_time_warning!(\"{{}}{{}} {{}}\", \ "CheckCodePrefix::{prefix} => {{ one_time_warning!(\"{{}}{{}} {{}}\", \
\"warning\".yellow().bold(), \":\".bold(), \"`{}` has been remapped to \ \"warning\".yellow().bold(), \":\".bold(), \"`{}` has been remapped to \
@ -117,18 +106,6 @@ pub fn main(cli: &Cli) -> Result<()> {
.map(|code| format!("CheckCode::{}", code.as_ref())) .map(|code| format!("CheckCode::{}", code.as_ref()))
.join(", ") .join(", ")
)); ));
} else if let Some(target) = PREFIX_REDIRECTS.get(&prefix.as_str()) {
gen = gen.line(format!(
"CheckCodePrefix::{prefix} => {{ one_time_warning!(\"{{}}{{}} {{}}\", \
\"warning\".yellow().bold(), \":\".bold(), \"`{}` has been remapped to \
`{}`\".bold()); \n vec![{}] }}",
prefix,
target,
codes
.iter()
.map(|code| format!("CheckCode::{}", code.as_ref()))
.join(", ")
));
} else { } else {
gen = gen.line(format!( gen = gen.line(format!(
"CheckCodePrefix::{prefix} => vec![{}],", "CheckCodePrefix::{prefix} => vec![{}],",

View file

@ -3043,6 +3043,80 @@ impl Check {
} }
} }
/// A hash map from deprecated `CheckCodePrefix` to latest `CheckCodePrefix`.
pub static PREFIX_REDIRECTS: Lazy<FxHashMap<&'static str, CheckCodePrefix>> = Lazy::new(|| {
FxHashMap::from_iter([
// TODO(charlie): Remove by 2023-01-01.
("U001", CheckCodePrefix::UP001),
("U003", CheckCodePrefix::UP003),
("U004", CheckCodePrefix::UP004),
("U005", CheckCodePrefix::UP005),
("U006", CheckCodePrefix::UP006),
("U007", CheckCodePrefix::UP007),
("U008", CheckCodePrefix::UP008),
("U009", CheckCodePrefix::UP009),
("U010", CheckCodePrefix::UP010),
("U011", CheckCodePrefix::UP011),
("U012", CheckCodePrefix::UP012),
("U013", CheckCodePrefix::UP013),
("U014", CheckCodePrefix::UP014),
("U015", CheckCodePrefix::UP015),
("U016", CheckCodePrefix::UP016),
// TODO(charlie): Remove by 2023-02-01.
("I252", CheckCodePrefix::TID252),
("M001", CheckCodePrefix::RUF100),
// TODO(charlie): Remove by 2023-02-01.
("PDV002", CheckCodePrefix::PD002),
("PDV003", CheckCodePrefix::PD003),
("PDV004", CheckCodePrefix::PD004),
("PDV007", CheckCodePrefix::PD007),
("PDV008", CheckCodePrefix::PD008),
("PDV009", CheckCodePrefix::PD009),
("PDV010", CheckCodePrefix::PD010),
("PDV011", CheckCodePrefix::PD011),
("PDV012", CheckCodePrefix::PD012),
("PDV013", CheckCodePrefix::PD013),
("PDV015", CheckCodePrefix::PD015),
("PDV901", CheckCodePrefix::PD901),
// TODO(charlie): Remove by 2023-02-01.
("R501", CheckCodePrefix::RET501),
("R502", CheckCodePrefix::RET502),
("R503", CheckCodePrefix::RET503),
("R504", CheckCodePrefix::RET504),
("R505", CheckCodePrefix::RET505),
("R506", CheckCodePrefix::RET506),
("R507", CheckCodePrefix::RET507),
("R508", CheckCodePrefix::RET508),
("IC001", CheckCodePrefix::ICN001),
("IC002", CheckCodePrefix::ICN001),
("IC003", CheckCodePrefix::ICN001),
("IC004", CheckCodePrefix::ICN001),
// TODO(charlie): Remove by 2023-01-01.
("U", CheckCodePrefix::UP),
("U0", CheckCodePrefix::UP0),
("U00", CheckCodePrefix::UP00),
("U01", CheckCodePrefix::UP01),
// TODO(charlie): Remove by 2023-02-01.
("I2", CheckCodePrefix::TID2),
("I25", CheckCodePrefix::TID25),
("M", CheckCodePrefix::RUF100),
("M0", CheckCodePrefix::RUF100),
// TODO(charlie): Remove by 2023-02-01.
("PDV", CheckCodePrefix::PD),
("PDV0", CheckCodePrefix::PD0),
("PDV01", CheckCodePrefix::PD01),
("PDV9", CheckCodePrefix::PD9),
("PDV90", CheckCodePrefix::PD90),
// TODO(charlie): Remove by 2023-02-01.
("R", CheckCodePrefix::RET),
("R5", CheckCodePrefix::RET5),
("R50", CheckCodePrefix::RET50),
// TODO(charlie): Remove by 2023-02-01.
("IC", CheckCodePrefix::ICN),
("IC0", CheckCodePrefix::ICN0),
])
});
/// A hash map from deprecated to latest `CheckCode`. /// A hash map from deprecated to latest `CheckCode`.
pub static CODE_REDIRECTS: Lazy<FxHashMap<&'static str, CheckCode>> = Lazy::new(|| { pub static CODE_REDIRECTS: Lazy<FxHashMap<&'static str, CheckCode>> = Lazy::new(|| {
FxHashMap::from_iter([ FxHashMap::from_iter([
@ -3078,28 +3152,20 @@ pub static CODE_REDIRECTS: Lazy<FxHashMap<&'static str, CheckCode>> = Lazy::new(
("PDV013", CheckCode::PD013), ("PDV013", CheckCode::PD013),
("PDV015", CheckCode::PD015), ("PDV015", CheckCode::PD015),
("PDV901", CheckCode::PD901), ("PDV901", CheckCode::PD901),
])
});
/// A hash map from deprecated `CheckCodePrefix` to latest `CheckCodePrefix`.
pub static PREFIX_REDIRECTS: Lazy<FxHashMap<&'static str, &'static str>> = Lazy::new(|| {
FxHashMap::from_iter([
// TODO(charlie): Remove by 2023-01-01.
("U", "UP"),
("U0", "UP0"),
("U00", "UP00"),
("U01", "UP01"),
// TODO(charlie): Remove by 2023-02-01. // TODO(charlie): Remove by 2023-02-01.
("I2", "TID2"), ("R501", CheckCode::RET501),
("I25", "TID25"), ("R502", CheckCode::RET502),
("M", "RUF100"), ("R503", CheckCode::RET503),
("M0", "RUF100"), ("R504", CheckCode::RET504),
("R505", CheckCode::RET505),
("R506", CheckCode::RET506),
("R507", CheckCode::RET507),
("R508", CheckCode::RET508),
// TODO(charlie): Remove by 2023-02-01. // TODO(charlie): Remove by 2023-02-01.
("PDV", "PD"), ("IC001", CheckCode::ICN001),
("PDV0", "PD0"), ("IC002", CheckCode::ICN001),
("PDV01", "PD01"), ("IC003", CheckCode::ICN001),
("PDV9", "PD9"), ("IC004", CheckCode::ICN001),
("PDV90", "PD90"),
]) ])
}); });

View file

@ -291,6 +291,12 @@ pub enum CheckCodePrefix {
I2, I2,
I25, I25,
I252, I252,
IC,
IC0,
IC001,
IC002,
IC003,
IC004,
ICN, ICN,
ICN0, ICN0,
ICN00, ICN00,
@ -410,6 +416,17 @@ pub enum CheckCodePrefix {
Q001, Q001,
Q002, Q002,
Q003, Q003,
R,
R5,
R50,
R501,
R502,
R503,
R504,
R505,
R506,
R507,
R508,
RET, RET,
RET5, RET5,
RET50, RET50,
@ -1343,6 +1360,60 @@ impl CheckCodePrefix {
); );
vec![CheckCode::TID252] vec![CheckCode::TID252]
} }
CheckCodePrefix::IC => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`IC` has been remapped to `ICN`".bold()
);
vec![CheckCode::ICN001]
}
CheckCodePrefix::IC0 => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`IC0` has been remapped to `ICN0`".bold()
);
vec![CheckCode::ICN001]
}
CheckCodePrefix::IC001 => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`IC001` has been remapped to `ICN001`".bold()
);
vec![CheckCode::ICN001]
}
CheckCodePrefix::IC002 => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`IC002` has been remapped to `ICN001`".bold()
);
vec![CheckCode::ICN001]
}
CheckCodePrefix::IC003 => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`IC003` has been remapped to `ICN001`".bold()
);
vec![CheckCode::ICN001]
}
CheckCodePrefix::IC004 => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`IC004` has been remapped to `ICN001`".bold()
);
vec![CheckCode::ICN001]
}
CheckCodePrefix::ICN => vec![CheckCode::ICN001], CheckCodePrefix::ICN => vec![CheckCode::ICN001],
CheckCodePrefix::ICN0 => vec![CheckCode::ICN001], CheckCodePrefix::ICN0 => vec![CheckCode::ICN001],
CheckCodePrefix::ICN00 => vec![CheckCode::ICN001], CheckCodePrefix::ICN00 => vec![CheckCode::ICN001],
@ -1764,6 +1835,132 @@ impl CheckCodePrefix {
CheckCodePrefix::Q001 => vec![CheckCode::Q001], CheckCodePrefix::Q001 => vec![CheckCode::Q001],
CheckCodePrefix::Q002 => vec![CheckCode::Q002], CheckCodePrefix::Q002 => vec![CheckCode::Q002],
CheckCodePrefix::Q003 => vec![CheckCode::Q003], CheckCodePrefix::Q003 => vec![CheckCode::Q003],
CheckCodePrefix::R => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`R` has been remapped to `RET`".bold()
);
vec![
CheckCode::RET501,
CheckCode::RET502,
CheckCode::RET503,
CheckCode::RET504,
CheckCode::RET505,
CheckCode::RET506,
CheckCode::RET507,
CheckCode::RET508,
]
}
CheckCodePrefix::R5 => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`R5` has been remapped to `RET5`".bold()
);
vec![
CheckCode::RET501,
CheckCode::RET502,
CheckCode::RET503,
CheckCode::RET504,
CheckCode::RET505,
CheckCode::RET506,
CheckCode::RET507,
CheckCode::RET508,
]
}
CheckCodePrefix::R50 => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`R50` has been remapped to `RET50`".bold()
);
vec![
CheckCode::RET501,
CheckCode::RET502,
CheckCode::RET503,
CheckCode::RET504,
CheckCode::RET505,
CheckCode::RET506,
CheckCode::RET507,
CheckCode::RET508,
]
}
CheckCodePrefix::R501 => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`R501` has been remapped to `RET501`".bold()
);
vec![CheckCode::RET501]
}
CheckCodePrefix::R502 => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`R502` has been remapped to `RET502`".bold()
);
vec![CheckCode::RET502]
}
CheckCodePrefix::R503 => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`R503` has been remapped to `RET503`".bold()
);
vec![CheckCode::RET503]
}
CheckCodePrefix::R504 => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`R504` has been remapped to `RET504`".bold()
);
vec![CheckCode::RET504]
}
CheckCodePrefix::R505 => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`R505` has been remapped to `RET505`".bold()
);
vec![CheckCode::RET505]
}
CheckCodePrefix::R506 => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`R506` has been remapped to `RET506`".bold()
);
vec![CheckCode::RET506]
}
CheckCodePrefix::R507 => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`R507` has been remapped to `RET507`".bold()
);
vec![CheckCode::RET507]
}
CheckCodePrefix::R508 => {
one_time_warning!(
"{}{} {}",
"warning".yellow().bold(),
":".bold(),
"`R508` has been remapped to `RET508`".bold()
);
vec![CheckCode::RET508]
}
CheckCodePrefix::RET => vec![ CheckCodePrefix::RET => vec![
CheckCode::RET501, CheckCode::RET501,
CheckCode::RET502, CheckCode::RET502,
@ -2483,6 +2680,12 @@ impl CheckCodePrefix {
CheckCodePrefix::I2 => SuffixLength::One, CheckCodePrefix::I2 => SuffixLength::One,
CheckCodePrefix::I25 => SuffixLength::Two, CheckCodePrefix::I25 => SuffixLength::Two,
CheckCodePrefix::I252 => SuffixLength::Three, CheckCodePrefix::I252 => SuffixLength::Three,
CheckCodePrefix::IC => SuffixLength::Zero,
CheckCodePrefix::IC0 => SuffixLength::One,
CheckCodePrefix::IC001 => SuffixLength::Three,
CheckCodePrefix::IC002 => SuffixLength::Three,
CheckCodePrefix::IC003 => SuffixLength::Three,
CheckCodePrefix::IC004 => SuffixLength::Three,
CheckCodePrefix::ICN => SuffixLength::Zero, CheckCodePrefix::ICN => SuffixLength::Zero,
CheckCodePrefix::ICN0 => SuffixLength::One, CheckCodePrefix::ICN0 => SuffixLength::One,
CheckCodePrefix::ICN00 => SuffixLength::Two, CheckCodePrefix::ICN00 => SuffixLength::Two,
@ -2602,6 +2805,17 @@ impl CheckCodePrefix {
CheckCodePrefix::Q001 => SuffixLength::Three, CheckCodePrefix::Q001 => SuffixLength::Three,
CheckCodePrefix::Q002 => SuffixLength::Three, CheckCodePrefix::Q002 => SuffixLength::Three,
CheckCodePrefix::Q003 => SuffixLength::Three, CheckCodePrefix::Q003 => SuffixLength::Three,
CheckCodePrefix::R => SuffixLength::Zero,
CheckCodePrefix::R5 => SuffixLength::One,
CheckCodePrefix::R50 => SuffixLength::Two,
CheckCodePrefix::R501 => SuffixLength::Three,
CheckCodePrefix::R502 => SuffixLength::Three,
CheckCodePrefix::R503 => SuffixLength::Three,
CheckCodePrefix::R504 => SuffixLength::Three,
CheckCodePrefix::R505 => SuffixLength::Three,
CheckCodePrefix::R506 => SuffixLength::Three,
CheckCodePrefix::R507 => SuffixLength::Three,
CheckCodePrefix::R508 => SuffixLength::Three,
CheckCodePrefix::RET => SuffixLength::Zero, CheckCodePrefix::RET => SuffixLength::Zero,
CheckCodePrefix::RET5 => SuffixLength::One, CheckCodePrefix::RET5 => SuffixLength::One,
CheckCodePrefix::RET50 => SuffixLength::Two, CheckCodePrefix::RET50 => SuffixLength::Two,