diff --git a/ruff_cli/src/cli.rs b/ruff_cli/src/cli.rs index cfacd30d52..4c1c8bc00a 100644 --- a/ruff_cli/src/cli.rs +++ b/ruff_cli/src/cli.rs @@ -3,11 +3,12 @@ use std::path::PathBuf; use clap::{command, Parser}; use regex::Regex; use ruff::logging::LogLevel; -use ruff::registry::{Rule, RuleSelector}; +use ruff::registry::Rule; use ruff::resolver::ConfigProcessor; use ruff::settings::types::{ FilePattern, PatternPrefixPair, PerFileIgnore, PythonVersion, SerializationFormat, }; +use ruff::RuleSelector; use rustc_hash::FxHashMap; #[derive(Debug, Parser)] diff --git a/ruff_macros/src/define_rule_mapping.rs b/ruff_macros/src/define_rule_mapping.rs index c96fb5d671..5d87f5a09f 100644 --- a/ruff_macros/src/define_rule_mapping.rs +++ b/ruff_macros/src/define_rule_mapping.rs @@ -53,7 +53,7 @@ pub fn define_rule_mapping(mapping: &Mapping) -> proc_macro2::TokenStream { let rulecodeprefix = super::rule_code_prefix::expand( &Ident::new("Rule", Span::call_site()), - &Ident::new("RuleSelector", Span::call_site()), + &Ident::new("RuleCodePrefix", Span::call_site()), mapping.entries.iter().map(|(code, ..)| code), |code| code_to_name[code], ); diff --git a/ruff_macros/src/rule_code_prefix.rs b/ruff_macros/src/rule_code_prefix.rs index 6cf2210c46..a91c5fab72 100644 --- a/ruff_macros/src/rule_code_prefix.rs +++ b/ruff_macros/src/rule_code_prefix.rs @@ -147,17 +147,6 @@ pub fn expand<'a>( }); quote! { - #[derive(PartialEq, Eq, PartialOrd, Ord)] - pub enum Specificity { - All, - Linter, - Code1Char, - Code2Chars, - Code3Chars, - Code4Chars, - Code5Chars, - } - #[derive( ::strum_macros::EnumString, ::strum_macros::AsRefStr, @@ -244,7 +233,9 @@ fn generate_impls<'a>( quote! { impl #prefix_ident { - pub fn specificity(&self) -> Specificity { + pub(crate) fn specificity(&self) -> crate::rule_selector::Specificity { + use crate::rule_selector::Specificity; + #[allow(clippy::match_same_arms)] match self { #(#specificity_match_arms)* diff --git a/ruff_macros/src/rule_namespace.rs b/ruff_macros/src/rule_namespace.rs index c805cace0b..ae77da7955 100644 --- a/ruff_macros/src/rule_namespace.rs +++ b/ruff_macros/src/rule_namespace.rs @@ -84,14 +84,14 @@ pub fn derive_impl(input: DeriveInput) -> syn::Result if field != "Pycodestyle" { into_iter_match_arms.extend(quote! { - #ident::#field => RuleSelector::#prefix_ident.into_iter(), + #ident::#field => RuleCodePrefix::#prefix_ident.into_iter(), }); } } into_iter_match_arms.extend(quote! { #ident::Pycodestyle => { - let rules: Vec<_> = (&RuleSelector::E).into_iter().chain(&RuleSelector::W).collect(); + let rules: Vec<_> = (&RuleCodePrefix::E).into_iter().chain(&RuleCodePrefix::W).collect(); rules.into_iter() } }); diff --git a/src/flake8_to_ruff/converter.rs b/src/flake8_to_ruff/converter.rs index 6ff038eed7..eb518faa9d 100644 --- a/src/flake8_to_ruff/converter.rs +++ b/src/flake8_to_ruff/converter.rs @@ -5,7 +5,8 @@ use anyhow::Result; use super::external_config::ExternalConfig; use super::plugin::Plugin; use super::{parser, plugin}; -use crate::registry::RuleSelector; +use crate::registry::RuleCodePrefix; +use crate::rule_selector::{prefix_to_selector, RuleSelector}; use crate::rules::flake8_pytest_style::types::{ ParametrizeNameType, ParametrizeValuesRowType, ParametrizeValuesType, }; @@ -20,7 +21,11 @@ use crate::settings::options::Options; use crate::settings::pyproject::Pyproject; use crate::warn_user; -const DEFAULT_SELECTORS: &[RuleSelector] = &[RuleSelector::F, RuleSelector::E, RuleSelector::W]; +const DEFAULT_SELECTORS: &[RuleSelector] = &[ + prefix_to_selector(RuleCodePrefix::F), + prefix_to_selector(RuleCodePrefix::E), + prefix_to_selector(RuleCodePrefix::W), +]; pub fn convert( config: &HashMap>>, @@ -426,7 +431,8 @@ mod tests { use super::convert; use crate::flake8_to_ruff::converter::DEFAULT_SELECTORS; use crate::flake8_to_ruff::ExternalConfig; - use crate::registry::RuleSelector; + use crate::registry::RuleCodePrefix; + use crate::rule_selector::RuleSelector; use crate::rules::pydocstyle::settings::Convention; use crate::rules::{flake8_quotes, pydocstyle}; use crate::settings::options::Options; @@ -555,7 +561,7 @@ mod tests { pydocstyle: Some(pydocstyle::settings::Options { convention: Some(Convention::Numpy), }), - ..default_options([RuleSelector::D]) + ..default_options([RuleCodePrefix::D.into()]) }); assert_eq!(actual, expected); @@ -579,7 +585,7 @@ mod tests { docstring_quotes: None, avoid_escape: None, }), - ..default_options([RuleSelector::Q]) + ..default_options([RuleCodePrefix::Q.into()]) }); assert_eq!(actual, expected); diff --git a/src/flake8_to_ruff/parser.rs b/src/flake8_to_ruff/parser.rs index 8c1c12d3e9..def1e226d1 100644 --- a/src/flake8_to_ruff/parser.rs +++ b/src/flake8_to_ruff/parser.rs @@ -5,7 +5,8 @@ use once_cell::sync::Lazy; use regex::Regex; use rustc_hash::FxHashMap; -use crate::registry::{RuleSelector, PREFIX_REDIRECTS}; +use crate::registry::PREFIX_REDIRECTS; +use crate::rule_selector::RuleSelector; use crate::settings::types::PatternPrefixPair; use crate::warn_user; @@ -21,7 +22,7 @@ pub fn parse_prefix_codes(value: &str) -> Vec { continue; } if let Some(code) = PREFIX_REDIRECTS.get(code) { - codes.push(code.clone()); + codes.push(code.clone().into()); } else if let Ok(code) = RuleSelector::from_str(code) { codes.push(code); } else { @@ -92,7 +93,7 @@ impl State { for filename in &self.filenames { codes.push(PatternPrefixPair { pattern: filename.clone(), - prefix: code.clone(), + prefix: code.clone().into(), }); } } else if let Ok(code) = RuleSelector::from_str(code) { @@ -205,7 +206,8 @@ mod tests { use anyhow::Result; use super::{parse_files_to_codes_mapping, parse_prefix_codes, parse_strings}; - use crate::registry::RuleSelector; + use crate::registry::RuleCodePrefix; + use crate::rule_selector::RuleSelector; use crate::settings::types::PatternPrefixPair; #[test] @@ -219,19 +221,19 @@ mod tests { assert_eq!(actual, expected); let actual = parse_prefix_codes("F401"); - let expected = vec![RuleSelector::F401]; + let expected = vec![RuleCodePrefix::F401.into()]; assert_eq!(actual, expected); let actual = parse_prefix_codes("F401,"); - let expected = vec![RuleSelector::F401]; + let expected = vec![RuleCodePrefix::F401.into()]; assert_eq!(actual, expected); let actual = parse_prefix_codes("F401,E501"); - let expected = vec![RuleSelector::F401, RuleSelector::E501]; + let expected = vec![RuleCodePrefix::F401.into(), RuleCodePrefix::E501.into()]; assert_eq!(actual, expected); let actual = parse_prefix_codes("F401, E501"); - let expected = vec![RuleSelector::F401, RuleSelector::E501]; + let expected = vec![RuleCodePrefix::F401.into(), RuleCodePrefix::E501.into()]; assert_eq!(actual, expected); } @@ -284,11 +286,11 @@ mod tests { let expected: Vec = vec![ PatternPrefixPair { pattern: "locust/test/*".to_string(), - prefix: RuleSelector::F841, + prefix: RuleCodePrefix::F841.into(), }, PatternPrefixPair { pattern: "examples/*".to_string(), - prefix: RuleSelector::F841, + prefix: RuleCodePrefix::F841.into(), }, ]; assert_eq!(actual, expected); @@ -304,23 +306,23 @@ mod tests { let expected: Vec = vec![ PatternPrefixPair { pattern: "t/*".to_string(), - prefix: RuleSelector::D, + prefix: RuleCodePrefix::D.into(), }, PatternPrefixPair { pattern: "setup.py".to_string(), - prefix: RuleSelector::D, + prefix: RuleCodePrefix::D.into(), }, PatternPrefixPair { pattern: "examples/*".to_string(), - prefix: RuleSelector::D, + prefix: RuleCodePrefix::D.into(), }, PatternPrefixPair { pattern: "docs/*".to_string(), - prefix: RuleSelector::D, + prefix: RuleCodePrefix::D.into(), }, PatternPrefixPair { pattern: "extra/*".to_string(), - prefix: RuleSelector::D, + prefix: RuleCodePrefix::D.into(), }, ]; assert_eq!(actual, expected); @@ -342,47 +344,47 @@ mod tests { let expected: Vec = vec![ PatternPrefixPair { pattern: "scrapy/__init__.py".to_string(), - prefix: RuleSelector::E402, + prefix: RuleCodePrefix::E402.into(), }, PatternPrefixPair { pattern: "scrapy/core/downloader/handlers/http.py".to_string(), - prefix: RuleSelector::F401, + prefix: RuleCodePrefix::F401.into(), }, PatternPrefixPair { pattern: "scrapy/http/__init__.py".to_string(), - prefix: RuleSelector::F401, + prefix: RuleCodePrefix::F401.into(), }, PatternPrefixPair { pattern: "scrapy/linkextractors/__init__.py".to_string(), - prefix: RuleSelector::E402, + prefix: RuleCodePrefix::E402.into(), }, PatternPrefixPair { pattern: "scrapy/linkextractors/__init__.py".to_string(), - prefix: RuleSelector::F401, + prefix: RuleCodePrefix::F401.into(), }, PatternPrefixPair { pattern: "scrapy/selector/__init__.py".to_string(), - prefix: RuleSelector::F401, + prefix: RuleCodePrefix::F401.into(), }, PatternPrefixPair { pattern: "scrapy/spiders/__init__.py".to_string(), - prefix: RuleSelector::E402, + prefix: RuleCodePrefix::E402.into(), }, PatternPrefixPair { pattern: "scrapy/spiders/__init__.py".to_string(), - prefix: RuleSelector::F401, + prefix: RuleCodePrefix::F401.into(), }, PatternPrefixPair { pattern: "scrapy/utils/url.py".to_string(), - prefix: RuleSelector::F403, + prefix: RuleCodePrefix::F403.into(), }, PatternPrefixPair { pattern: "scrapy/utils/url.py".to_string(), - prefix: RuleSelector::F405, + prefix: RuleCodePrefix::F405.into(), }, PatternPrefixPair { pattern: "tests/test_loader.py".to_string(), - prefix: RuleSelector::E741, + prefix: RuleCodePrefix::E741.into(), }, ]; assert_eq!(actual, expected); diff --git a/src/flake8_to_ruff/plugin.rs b/src/flake8_to_ruff/plugin.rs index cd3a5b96b6..de2196ac06 100644 --- a/src/flake8_to_ruff/plugin.rs +++ b/src/flake8_to_ruff/plugin.rs @@ -4,7 +4,8 @@ use std::str::FromStr; use anyhow::anyhow; -use crate::registry::RuleSelector; +use crate::registry::RuleCodePrefix; +use crate::rule_selector::RuleSelector; #[derive(Clone, Ord, PartialOrd, Eq, PartialEq)] pub enum Plugin { @@ -130,42 +131,43 @@ impl fmt::Debug for Plugin { } } +// TODO(martin): Convert into `impl From for Linter` impl Plugin { pub fn selector(&self) -> RuleSelector { match self { - Plugin::Flake82020 => RuleSelector::YTT, - Plugin::Flake8Annotations => RuleSelector::ANN, - Plugin::Flake8Bandit => RuleSelector::S, - Plugin::Flake8BlindExcept => RuleSelector::BLE, - Plugin::Flake8BooleanTrap => RuleSelector::FBT, - Plugin::Flake8Bugbear => RuleSelector::B, - Plugin::Flake8Builtins => RuleSelector::A, - Plugin::Flake8Commas => RuleSelector::COM, - Plugin::Flake8Comprehensions => RuleSelector::C4, - Plugin::Flake8Datetimez => RuleSelector::DTZ, - Plugin::Flake8Debugger => RuleSelector::T1, - Plugin::Flake8Docstrings => RuleSelector::D, - Plugin::Flake8Eradicate => RuleSelector::ERA, - Plugin::Flake8ErrMsg => RuleSelector::EM, - Plugin::Flake8Executable => RuleSelector::EXE, - Plugin::Flake8ImplicitStrConcat => RuleSelector::ISC, - Plugin::Flake8ImportConventions => RuleSelector::ICN, - Plugin::Flake8NoPep420 => RuleSelector::INP, - Plugin::Flake8Pie => RuleSelector::PIE, - Plugin::Flake8Print => RuleSelector::T2, - Plugin::Flake8PytestStyle => RuleSelector::PT, - Plugin::Flake8Quotes => RuleSelector::Q, - Plugin::Flake8Return => RuleSelector::RET, - Plugin::Flake8Simplify => RuleSelector::SIM, - Plugin::Flake8TidyImports => RuleSelector::TID, - Plugin::Flake8TypeChecking => RuleSelector::TYP, - Plugin::Flake8UnusedArguments => RuleSelector::ARG, - Plugin::Flake8UsePathlib => RuleSelector::PTH, - Plugin::McCabe => RuleSelector::C9, - Plugin::PEP8Naming => RuleSelector::N, - Plugin::PandasVet => RuleSelector::PD, - Plugin::Pyupgrade => RuleSelector::UP, - Plugin::Tryceratops => RuleSelector::TRY, + Plugin::Flake82020 => RuleCodePrefix::YTT.into(), + Plugin::Flake8Annotations => RuleCodePrefix::ANN.into(), + Plugin::Flake8Bandit => RuleCodePrefix::S.into(), + Plugin::Flake8BlindExcept => RuleCodePrefix::BLE.into(), + Plugin::Flake8BooleanTrap => RuleCodePrefix::FBT.into(), + Plugin::Flake8Bugbear => RuleCodePrefix::B.into(), + Plugin::Flake8Builtins => RuleCodePrefix::A.into(), + Plugin::Flake8Commas => RuleCodePrefix::COM.into(), + Plugin::Flake8Comprehensions => RuleCodePrefix::C4.into(), + Plugin::Flake8Datetimez => RuleCodePrefix::DTZ.into(), + Plugin::Flake8Debugger => RuleCodePrefix::T1.into(), + Plugin::Flake8Docstrings => RuleCodePrefix::D.into(), + Plugin::Flake8Eradicate => RuleCodePrefix::ERA.into(), + Plugin::Flake8ErrMsg => RuleCodePrefix::EM.into(), + Plugin::Flake8Executable => RuleCodePrefix::EXE.into(), + Plugin::Flake8ImplicitStrConcat => RuleCodePrefix::ISC.into(), + Plugin::Flake8ImportConventions => RuleCodePrefix::ICN.into(), + Plugin::Flake8NoPep420 => RuleCodePrefix::INP.into(), + Plugin::Flake8Pie => RuleCodePrefix::PIE.into(), + Plugin::Flake8Print => RuleCodePrefix::T2.into(), + Plugin::Flake8PytestStyle => RuleCodePrefix::PT.into(), + Plugin::Flake8Quotes => RuleCodePrefix::Q.into(), + Plugin::Flake8Return => RuleCodePrefix::RET.into(), + Plugin::Flake8Simplify => RuleCodePrefix::SIM.into(), + Plugin::Flake8TidyImports => RuleCodePrefix::TID.into(), + Plugin::Flake8TypeChecking => RuleCodePrefix::TYP.into(), + Plugin::Flake8UnusedArguments => RuleCodePrefix::ARG.into(), + Plugin::Flake8UsePathlib => RuleCodePrefix::PTH.into(), + Plugin::McCabe => RuleCodePrefix::C9.into(), + Plugin::PEP8Naming => RuleCodePrefix::N.into(), + Plugin::PandasVet => RuleCodePrefix::PD.into(), + Plugin::Pyupgrade => RuleCodePrefix::UP.into(), + Plugin::Tryceratops => RuleCodePrefix::TRY.into(), } } } diff --git a/src/lib.rs b/src/lib.rs index 9661eea822..26edb84494 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,6 +37,7 @@ mod noqa; mod python; pub mod registry; pub mod resolver; +mod rule_selector; mod rules; mod rustpython_helpers; pub mod settings; @@ -47,6 +48,7 @@ mod violations; mod visibility; use cfg_if::cfg_if; +pub use rule_selector::RuleSelector; pub use violation::{AutofixKind, Availability as AutofixAvailability}; pub use violations::IOError; diff --git a/src/registry.rs b/src/registry.rs index b9d0b69642..4fb7330305 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -9,6 +9,7 @@ use strum_macros::{AsRefStr, EnumIter}; use crate::ast::types::Range; use crate::fix::Fix; +use crate::rule_selector::{prefix_to_selector, RuleSelector}; use crate::violation::Violation; use crate::{rules, violations}; @@ -607,19 +608,25 @@ pub trait RuleNamespace: Sized { /// The prefix, name and selector for an upstream linter category. pub struct LinterCategory(pub &'static str, pub &'static str, pub RuleSelector); +// TODO(martin): Move these constant definitions back to Linter::categories impl +// once RuleSelector is an enum with a Linter variant +const PYCODESTYLE_CATEGORIES: &[LinterCategory] = &[ + LinterCategory("E", "Error", prefix_to_selector(RuleCodePrefix::E)), + LinterCategory("W", "Warning", prefix_to_selector(RuleCodePrefix::W)), +]; + +const PYLINT_CATEGORIES: &[LinterCategory] = &[ + LinterCategory("PLC", "Convention", prefix_to_selector(RuleCodePrefix::PLC)), + LinterCategory("PLE", "Error", prefix_to_selector(RuleCodePrefix::PLE)), + LinterCategory("PLR", "Refactor", prefix_to_selector(RuleCodePrefix::PLR)), + LinterCategory("PLW", "Warning", prefix_to_selector(RuleCodePrefix::PLW)), +]; + impl Linter { pub fn categories(&self) -> Option<&'static [LinterCategory]> { match self { - Linter::Pycodestyle => Some(&[ - LinterCategory("E", "Error", RuleSelector::E), - LinterCategory("W", "Warning", RuleSelector::W), - ]), - Linter::Pylint => Some(&[ - LinterCategory("PLC", "Convention", RuleSelector::PLC), - LinterCategory("PLE", "Error", RuleSelector::PLE), - LinterCategory("PLR", "Refactor", RuleSelector::PLR), - LinterCategory("PLW", "Warning", RuleSelector::PLW), - ]), + Linter::Pycodestyle => Some(PYCODESTYLE_CATEGORIES), + Linter::Pylint => Some(PYLINT_CATEGORIES), _ => None, } } diff --git a/src/rule_selector.rs b/src/rule_selector.rs new file mode 100644 index 0000000000..7074d91197 --- /dev/null +++ b/src/rule_selector.rs @@ -0,0 +1,68 @@ +use std::str::FromStr; + +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::registry::{Rule, RuleCodePrefix}; + +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] +pub struct RuleSelector(RuleCodePrefix); + +impl FromStr for RuleSelector { + type Err = strum::ParseError; + + fn from_str(s: &str) -> Result { + Ok(Self(RuleCodePrefix::from_str(s)?)) + } +} + +impl From for RuleSelector { + fn from(prefix: RuleCodePrefix) -> Self { + Self(prefix) + } +} + +impl IntoIterator for &RuleSelector { + type IntoIter = ::std::vec::IntoIter; + type Item = Rule; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +/// A const alternative to the `impl From for RuleSelector` +// to let us keep the fields of RuleSelector private. +// Note that Rust doesn't yet support `impl const From for +// RuleSelector` (see https://github.com/rust-lang/rust/issues/67792). +// TODO(martin): Remove once RuleSelector is an enum with Linter & Rule variants +pub(crate) const fn prefix_to_selector(prefix: RuleCodePrefix) -> RuleSelector { + RuleSelector(prefix) +} + +impl JsonSchema for RuleSelector { + fn schema_name() -> String { + "RuleSelector".to_string() + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + ::json_schema(gen) + } +} + +impl RuleSelector { + pub(crate) fn specificity(&self) -> Specificity { + self.0.specificity() + } +} + +#[derive(PartialEq, Eq, PartialOrd, Ord)] +pub(crate) enum Specificity { + All, + Linter, + Code1Char, + Code2Chars, + Code3Chars, + Code4Chars, + Code5Chars, +} diff --git a/src/rules/pandas_vet/mod.rs b/src/rules/pandas_vet/mod.rs index 182c0a22c1..6d58a11e7e 100644 --- a/src/rules/pandas_vet/mod.rs +++ b/src/rules/pandas_vet/mod.rs @@ -12,14 +12,14 @@ mod tests { use textwrap::dedent; use crate::linter::check_path; - use crate::registry::{Rule, RuleSelector}; + use crate::registry::{Rule, RuleCodePrefix}; use crate::settings::flags; use crate::source_code::{Indexer, Locator, Stylist}; use crate::{directives, rustpython_helpers, settings}; fn rule_code(contents: &str, expected: &[Rule]) -> Result<()> { let contents = dedent(contents); - let settings = settings::Settings::for_rules(&RuleSelector::PD); + let settings = settings::Settings::for_rules(&RuleCodePrefix::PD); let tokens: Vec = rustpython_helpers::tokenize(&contents); let locator = Locator::new(&contents); let stylist = Stylist::from_contents(&contents, &locator); diff --git a/src/rules/pyflakes/mod.rs b/src/rules/pyflakes/mod.rs index 5f55d82715..da99bc9c70 100644 --- a/src/rules/pyflakes/mod.rs +++ b/src/rules/pyflakes/mod.rs @@ -15,7 +15,7 @@ mod tests { use textwrap::dedent; use crate::linter::{check_path, test_path}; - use crate::registry::{Rule, RuleSelector}; + use crate::registry::{Rule, RuleCodePrefix}; use crate::settings::flags; use crate::source_code::{Indexer, Locator, Stylist}; use crate::{directives, rustpython_helpers, settings}; @@ -209,7 +209,7 @@ mod tests { /// Note that all tests marked with `#[ignore]` should be considered TODOs. fn flakes(contents: &str, expected: &[Rule]) -> Result<()> { let contents = dedent(contents); - let settings = settings::Settings::for_rules(&RuleSelector::F); + let settings = settings::Settings::for_rules(&RuleCodePrefix::F); let tokens: Vec = rustpython_helpers::tokenize(&contents); let locator = Locator::new(&contents); let stylist = Stylist::from_contents(&contents, &locator); diff --git a/src/settings/configuration.rs b/src/settings/configuration.rs index 32f0ba12f6..4dad1954e1 100644 --- a/src/settings/configuration.rs +++ b/src/settings/configuration.rs @@ -13,7 +13,7 @@ use shellexpand; use shellexpand::LookupError; use crate::fs; -use crate::registry::RuleSelector; +use crate::rule_selector::RuleSelector; use crate::rules::{ flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins, flake8_errmsg, flake8_implicit_str_concat, flake8_import_conventions, flake8_pytest_style, flake8_quotes, diff --git a/src/settings/defaults.rs b/src/settings/defaults.rs index 1b5f64c80a..403a179d9d 100644 --- a/src/settings/defaults.rs +++ b/src/settings/defaults.rs @@ -6,7 +6,8 @@ use rustc_hash::FxHashSet; use super::hashable::{HashableGlobSet, HashableHashSet}; use super::types::{FilePattern, PythonVersion}; use super::Settings; -use crate::registry::RuleSelector; +use crate::registry::RuleCodePrefix; +use crate::rule_selector::{prefix_to_selector, RuleSelector}; use crate::rules::{ flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins, flake8_errmsg, flake8_implicit_str_concat, flake8_import_conventions, flake8_pytest_style, flake8_quotes, @@ -14,7 +15,10 @@ use crate::rules::{ pydocstyle, pylint, pyupgrade, }; -pub const PREFIXES: &[RuleSelector] = &[RuleSelector::E, RuleSelector::F]; +pub const PREFIXES: &[RuleSelector] = &[ + prefix_to_selector(RuleCodePrefix::E), + prefix_to_selector(RuleCodePrefix::F), +]; pub const TARGET_VERSION: PythonVersion = PythonVersion::Py310; diff --git a/src/settings/mod.rs b/src/settings/mod.rs index 598ebd6158..efea2864c2 100644 --- a/src/settings/mod.rs +++ b/src/settings/mod.rs @@ -11,7 +11,8 @@ use rustc_hash::FxHashSet; use self::hashable::{HashableGlobMatcher, HashableGlobSet, HashableHashSet, HashableRegex}; use self::rule_table::RuleTable; use crate::cache::cache_dir; -use crate::registry::{Rule, RuleSelector, Specificity, INCOMPATIBLE_CODES}; +use crate::registry::{Rule, INCOMPATIBLE_CODES}; +use crate::rule_selector::{RuleSelector, Specificity}; use crate::rules::{ flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins, flake8_errmsg, flake8_implicit_str_concat, flake8_import_conventions, flake8_pytest_style, flake8_quotes, @@ -238,7 +239,10 @@ impl From<&Configuration> for RuleTable { let mut rules = RuleTable::empty(); let fixable = resolve_codes([RuleCodeSpec { - select: config.fixable.as_deref().unwrap_or(&[RuleSelector::ALL]), + select: config + .fixable + .as_deref() + .unwrap_or(&[crate::registry::RuleCodePrefix::ALL.into()]), ignore: config.unfixable.as_deref().unwrap_or_default(), }]); @@ -352,13 +356,13 @@ fn validate_enabled(enabled: FxHashSet) -> FxHashSet { mod tests { use rustc_hash::FxHashSet; - use crate::registry::{Rule, RuleSelector}; + use crate::registry::{Rule, RuleCodePrefix}; use crate::settings::{resolve_codes, RuleCodeSpec}; #[test] fn rule_codes() { let actual = resolve_codes([RuleCodeSpec { - select: &[RuleSelector::W], + select: &[RuleCodePrefix::W.into()], ignore: &[], }]); let expected = FxHashSet::from_iter([ @@ -369,33 +373,33 @@ mod tests { assert_eq!(actual, expected); let actual = resolve_codes([RuleCodeSpec { - select: &[RuleSelector::W6], + select: &[RuleCodePrefix::W6.into()], ignore: &[], }]); let expected = FxHashSet::from_iter([Rule::InvalidEscapeSequence]); assert_eq!(actual, expected); let actual = resolve_codes([RuleCodeSpec { - select: &[RuleSelector::W], - ignore: &[RuleSelector::W292], + select: &[RuleCodePrefix::W.into()], + ignore: &[RuleCodePrefix::W292.into()], }]); let expected = FxHashSet::from_iter([Rule::DocLineTooLong, Rule::InvalidEscapeSequence]); assert_eq!(actual, expected); let actual = resolve_codes([RuleCodeSpec { - select: &[RuleSelector::W605], - ignore: &[RuleSelector::W605], + select: &[RuleCodePrefix::W605.into()], + ignore: &[RuleCodePrefix::W605.into()], }]); let expected = FxHashSet::from_iter([]); assert_eq!(actual, expected); let actual = resolve_codes([ RuleCodeSpec { - select: &[RuleSelector::W], - ignore: &[RuleSelector::W292], + select: &[RuleCodePrefix::W.into()], + ignore: &[RuleCodePrefix::W292.into()], }, RuleCodeSpec { - select: &[RuleSelector::W292], + select: &[RuleCodePrefix::W292.into()], ignore: &[], }, ]); @@ -408,12 +412,12 @@ mod tests { let actual = resolve_codes([ RuleCodeSpec { - select: &[RuleSelector::W], - ignore: &[RuleSelector::W292], + select: &[RuleCodePrefix::W.into()], + ignore: &[RuleCodePrefix::W292.into()], }, RuleCodeSpec { - select: &[RuleSelector::W292], - ignore: &[RuleSelector::W], + select: &[RuleCodePrefix::W292.into()], + ignore: &[RuleCodePrefix::W.into()], }, ]); let expected = FxHashSet::from_iter([Rule::NoNewLineAtEndOfFile]); diff --git a/src/settings/options.rs b/src/settings/options.rs index 2952fb4c5d..ce45dd60f3 100644 --- a/src/settings/options.rs +++ b/src/settings/options.rs @@ -5,7 +5,7 @@ use rustc_hash::FxHashMap; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use crate::registry::RuleSelector; +use crate::rule_selector::RuleSelector; use crate::rules::{ flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins, flake8_errmsg, flake8_implicit_str_concat, flake8_import_conventions, flake8_pytest_style, flake8_quotes, diff --git a/src/settings/pyproject.rs b/src/settings/pyproject.rs index 447cd62e0f..ab2e4c8526 100644 --- a/src/settings/pyproject.rs +++ b/src/settings/pyproject.rs @@ -129,7 +129,7 @@ mod tests { use anyhow::Result; use rustc_hash::FxHashMap; - use crate::registry::RuleSelector; + use crate::registry::RuleCodePrefix; use crate::rules::flake8_quotes::settings::Quote; use crate::rules::flake8_tidy_imports::banned_api::ApiBan; use crate::rules::flake8_tidy_imports::relative_imports::Strictness; @@ -212,7 +212,7 @@ select = ["E501"] pyproject.tool, Some(Tools { ruff: Some(Options { - select: Some(vec![RuleSelector::E501]), + select: Some(vec![RuleCodePrefix::E501.into()]), ..Options::default() }) }) @@ -230,8 +230,8 @@ ignore = ["E501"] pyproject.tool, Some(Tools { ruff: Some(Options { - extend_select: Some(vec![RuleSelector::RUF100]), - ignore: Some(vec![RuleSelector::E501]), + extend_select: Some(vec![RuleCodePrefix::RUF100.into()]), + ignore: Some(vec![RuleCodePrefix::E501.into()]), ..Options::default() }) }) @@ -293,7 +293,7 @@ other-attribute = 1 external: Some(vec!["V101".to_string()]), per_file_ignores: Some(FxHashMap::from_iter([( "__init__.py".to_string(), - vec![RuleSelector::F401] + vec![RuleCodePrefix::F401.into()] )])), flake8_bugbear: Some(flake8_bugbear::settings::Options { extend_immutable_calls: Some(vec![ diff --git a/src/settings/types.rs b/src/settings/types.rs index 3b4ea5dfa7..3041515c38 100644 --- a/src/settings/types.rs +++ b/src/settings/types.rs @@ -12,7 +12,8 @@ use serde::{de, Deserialize, Deserializer, Serialize}; use super::hashable::HashableHashSet; use crate::fs; -use crate::registry::{Rule, RuleSelector}; +use crate::registry::Rule; +use crate::rule_selector::RuleSelector; #[derive( Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize, Hash, JsonSchema,