rule 8/8: Automatically rewrite RuleCode to Rule

# This commit was automatically generated by running the following
# script (followed by `cargo +nightly fmt`):

import glob
import re
from typing import NamedTuple

class Rule(NamedTuple):
    code: str
    name: str
    path: str

def rules() -> list[Rule]:
    """Returns all the rules defined in `src/registry.rs`."""
    file = open('src/registry.rs')

    rules = []

    while next(file) != 'ruff_macros::define_rule_mapping!(\n':
        continue

    while (line := next(file)) != ');\n':
        line = line.strip().rstrip(',')
        if line.startswith('//'):
            continue
        code, path = line.split(' => ')
        name = path.rsplit('::')[-1]
        rules.append(Rule(code, name, path))

    return rules

code2name = {r.code: r.name for r in rules()}

for pattern in ('src/**/*.rs', 'ruff_cli/**/*.rs', 'ruff_dev/**/*.rs', 'scripts/add_*.py'):
    for name in glob.glob(pattern, recursive=True):
        with open(name) as f:
            text = f.read()

        text = re.sub('Rule(?:Code)?::([A-Z]\w+)', lambda m: 'Rule::' + code2name[m.group(1)], text)
        text = re.sub(r'(?<!"<FilePattern>:<)RuleCode\b', 'Rule', text)
        text = re.sub('(use crate::registry::{.*, Rule), Rule(.*)', r'\1\2', text) # fix duplicate import

        with open(name, 'w') as f:
            f.write(text)
This commit is contained in:
Martin Fischer 2023-01-19 05:45:52 +01:00 committed by Charlie Marsh
parent 9e3083aa2c
commit 6649225167
90 changed files with 2427 additions and 1590 deletions

View File

@ -114,7 +114,7 @@ pub fn run(
.unwrap_or_else(|(path, message)| {
if let Some(path) = &path {
let settings = resolver.resolve(path, pyproject_strategy);
if settings.rules.enabled(&Rule::E902) {
if settings.rules.enabled(&Rule::IOError) {
Diagnostics::new(vec![Message {
kind: IOError(message).into(),
location: Location::default(),

View File

@ -47,11 +47,11 @@ mod tests {
use anyhow::Result;
use test_case::test_case;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::linter::test_path;
use crate::settings;
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
let diagnostics =test_path(
Path::new("./resources/test/fixtures/%s")

View File

@ -44,9 +44,9 @@ def main(*, name: str, code: str, origin: str) -> None:
with open(mod_rs, "w") as fp:
for line in content.splitlines():
if line.strip() == "fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {":
indent = line.split("fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {")[0]
fp.write(f'{indent}#[test_case(RuleCode::{code}, Path::new("{code}.py"); "{code}")]')
if line.strip() == "fn rules(rule_code: Rule, path: &Path) -> Result<()> {":
indent = line.split("fn rules(rule_code: Rule, path: &Path) -> Result<()> {")[0]
fp.write(f'{indent}#[test_case(Rule::{code}, Path::new("{code}.py"); "{code}")]')
fp.write("\n")
fp.write(line)

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
use std::path::Path;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::rules::flake8_no_pep420::rules::implicit_namespace_package;
use crate::settings::Settings;
@ -8,7 +8,7 @@ pub fn check_file_path(path: &Path, settings: &Settings) -> Vec<Diagnostic> {
let mut diagnostics: Vec<Diagnostic> = vec![];
// flake8-no-pep420
if settings.rules.enabled(&RuleCode::INP001) {
if settings.rules.enabled(&Rule::ImplicitNamespacePackage) {
if let Some(diagnostic) = implicit_namespace_package(path) {
diagnostics.push(diagnostic);
}

View File

@ -6,7 +6,7 @@ use rustpython_parser::ast::Suite;
use crate::ast::visitor::Visitor;
use crate::directives::IsortDirectives;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::rules::isort;
use crate::rules::isort::track::{Block, ImportTracker};
use crate::settings::{flags, Settings};
@ -36,7 +36,7 @@ pub fn check_imports(
// Enforce import rules.
let mut diagnostics = vec![];
if settings.rules.enabled(&RuleCode::I001) {
if settings.rules.enabled(&Rule::UnsortedImports) {
for block in &blocks {
if !block.imports.is_empty() {
if let Some(diagnostic) = isort::rules::organize_imports(
@ -47,7 +47,7 @@ pub fn check_imports(
}
}
}
if settings.rules.enabled(&RuleCode::I002) {
if settings.rules.enabled(&Rule::MissingRequiredImport) {
diagnostics.extend(isort::rules::add_required_imports(
&blocks, python_ast, locator, settings, autofix,
));

View File

@ -1,6 +1,6 @@
//! Lint rules based on checking raw physical lines.
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::rules::pycodestyle::rules::{
doc_line_too_long, line_too_long, no_newline_at_end_of_file,
};
@ -17,12 +17,14 @@ pub fn check_lines(
) -> Vec<Diagnostic> {
let mut diagnostics: Vec<Diagnostic> = vec![];
let enforce_blanket_noqa = settings.rules.enabled(&RuleCode::PGH004);
let enforce_blanket_type_ignore = settings.rules.enabled(&RuleCode::PGH003);
let enforce_doc_line_too_long = settings.rules.enabled(&RuleCode::W505);
let enforce_line_too_long = settings.rules.enabled(&RuleCode::E501);
let enforce_no_newline_at_end_of_file = settings.rules.enabled(&RuleCode::W292);
let enforce_unnecessary_coding_comment = settings.rules.enabled(&RuleCode::UP009);
let enforce_blanket_noqa = settings.rules.enabled(&Rule::BlanketNOQA);
let enforce_blanket_type_ignore = settings.rules.enabled(&Rule::BlanketTypeIgnore);
let enforce_doc_line_too_long = settings.rules.enabled(&Rule::DocLineTooLong);
let enforce_line_too_long = settings.rules.enabled(&Rule::LineTooLong);
let enforce_no_newline_at_end_of_file = settings.rules.enabled(&Rule::NoNewLineAtEndOfFile);
let enforce_unnecessary_coding_comment = settings
.rules
.enabled(&Rule::PEP3120UnnecessaryCodingComment);
let mut commented_lines_iter = commented_lines.iter().peekable();
let mut doc_lines_iter = doc_lines.iter().peekable();
@ -37,7 +39,9 @@ pub fn check_lines(
index,
line,
matches!(autofix, flags::Autofix::Enabled)
&& settings.rules.should_fix(&RuleCode::UP009),
&& settings
.rules
.should_fix(&Rule::PEP3120UnnecessaryCodingComment),
) {
diagnostics.push(diagnostic);
}
@ -79,7 +83,7 @@ pub fn check_lines(
if let Some(diagnostic) = no_newline_at_end_of_file(
contents,
matches!(autofix, flags::Autofix::Enabled)
&& settings.rules.should_fix(&RuleCode::W292),
&& settings.rules.should_fix(&Rule::NoNewLineAtEndOfFile),
) {
diagnostics.push(diagnostic);
}
@ -92,7 +96,7 @@ pub fn check_lines(
mod tests {
use super::check_lines;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings::{flags, Settings};
#[test]
@ -105,7 +109,7 @@ mod tests {
&[],
&Settings {
line_length,
..Settings::for_rule(RuleCode::E501)
..Settings::for_rule(Rule::LineTooLong)
},
flags::Autofix::Enabled,
)

View File

@ -6,7 +6,7 @@ use rustpython_parser::ast::Location;
use crate::ast::types::Range;
use crate::fix::Fix;
use crate::noqa::{is_file_exempt, Directive};
use crate::registry::{Diagnostic, DiagnosticKind, Rule, RuleCode, CODE_REDIRECTS};
use crate::registry::{Diagnostic, DiagnosticKind, Rule, CODE_REDIRECTS};
use crate::settings::{flags, Settings};
use crate::violations::UnusedCodes;
use crate::{noqa, violations};
@ -22,7 +22,7 @@ pub fn check_noqa(
let mut noqa_directives: IntMap<usize, (Directive, Vec<&str>)> = IntMap::default();
let mut ignored = vec![];
let enforce_noqa = settings.rules.enabled(&RuleCode::RUF100);
let enforce_noqa = settings.rules.enabled(&Rule::UnusedNOQA);
let lines: Vec<&str> = contents.lines().collect();
for lineno in commented_lines {
@ -124,7 +124,7 @@ pub fn check_noqa(
let mut self_ignore = false;
for code in codes {
let code = CODE_REDIRECTS.get(code).map_or(code, |r| r.code());
if code == RuleCode::RUF100.code() {
if code == Rule::UnusedNOQA.code() {
self_ignore = true;
break;
}

View File

@ -3,7 +3,7 @@
use rustpython_parser::lexer::{LexResult, Tok};
use crate::lex::docstring_detection::StateMachine;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::rules::ruff::rules::Context;
use crate::rules::{
eradicate, flake8_commas, flake8_implicit_str_concat, flake8_quotes, pycodestyle, ruff,
@ -19,20 +19,32 @@ pub fn check_tokens(
) -> Vec<Diagnostic> {
let mut diagnostics: Vec<Diagnostic> = vec![];
let enforce_ambiguous_unicode_character = settings.rules.enabled(&RuleCode::RUF001)
|| settings.rules.enabled(&RuleCode::RUF002)
|| settings.rules.enabled(&RuleCode::RUF003);
let enforce_quotes = settings.rules.enabled(&RuleCode::Q000)
|| settings.rules.enabled(&RuleCode::Q001)
|| settings.rules.enabled(&RuleCode::Q002)
|| settings.rules.enabled(&RuleCode::Q003);
let enforce_commented_out_code = settings.rules.enabled(&RuleCode::ERA001);
let enforce_invalid_escape_sequence = settings.rules.enabled(&RuleCode::W605);
let enforce_implicit_string_concatenation =
settings.rules.enabled(&RuleCode::ISC001) || settings.rules.enabled(&RuleCode::ISC002);
let enforce_trailing_comma = settings.rules.enabled(&RuleCode::COM812)
|| settings.rules.enabled(&RuleCode::COM818)
|| settings.rules.enabled(&RuleCode::COM819);
let enforce_ambiguous_unicode_character = settings
.rules
.enabled(&Rule::AmbiguousUnicodeCharacterString)
|| settings
.rules
.enabled(&Rule::AmbiguousUnicodeCharacterDocstring)
|| settings
.rules
.enabled(&Rule::AmbiguousUnicodeCharacterComment);
let enforce_quotes = settings.rules.enabled(&Rule::BadQuotesInlineString)
|| settings.rules.enabled(&Rule::BadQuotesMultilineString)
|| settings.rules.enabled(&Rule::BadQuotesDocstring)
|| settings.rules.enabled(&Rule::AvoidQuoteEscape);
let enforce_commented_out_code = settings.rules.enabled(&Rule::CommentedOutCode);
let enforce_invalid_escape_sequence = settings.rules.enabled(&Rule::InvalidEscapeSequence);
let enforce_implicit_string_concatenation = settings
.rules
.enabled(&Rule::SingleLineImplicitStringConcatenation)
|| settings
.rules
.enabled(&Rule::MultiLineImplicitStringConcatenation);
let enforce_trailing_comma = settings.rules.enabled(&Rule::TrailingCommaMissing)
|| settings
.rules
.enabled(&Rule::TrailingCommaOnBareTupleProhibited)
|| settings.rules.enabled(&Rule::TrailingCommaProhibited);
let mut state_machine = StateMachine::default();
for &(start, ref tok, end) in tokens.iter().flatten() {
@ -101,7 +113,7 @@ pub fn check_tokens(
start,
end,
matches!(autofix, flags::Autofix::Enabled)
&& settings.rules.should_fix(&RuleCode::W605),
&& settings.rules.should_fix(&Rule::InvalidEscapeSequence),
));
}
}

View File

@ -7,7 +7,7 @@ use anyhow::{anyhow, Result};
use path_absolutize::{path_dedot, Absolutize};
use rustc_hash::FxHashSet;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings::hashable::{HashableGlobMatcher, HashableHashSet};
/// Extract the absolute path and basename (as strings) from a Path.
@ -29,9 +29,9 @@ pub(crate) fn ignores_from_path<'a>(
pattern_code_pairs: &'a [(
HashableGlobMatcher,
HashableGlobMatcher,
HashableHashSet<RuleCode>,
HashableHashSet<Rule>,
)],
) -> Result<FxHashSet<&'a RuleCode>> {
) -> Result<FxHashSet<&'a Rule>> {
let (file_path, file_basename) = extract_path_names(path)?;
Ok(pattern_code_pairs
.iter()

View File

@ -7,7 +7,7 @@ use wasm_bindgen::prelude::*;
use crate::directives;
use crate::linter::check_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::rules::{
flake8_annotations, flake8_bandit, flake8_bugbear, flake8_errmsg, flake8_import_conventions,
flake8_pytest_style, flake8_quotes, flake8_tidy_imports, flake8_unused_arguments, isort,
@ -58,7 +58,7 @@ struct ExpandedMessage {
fix: Option<ExpandedFix>,
}
struct SerializeRuleAsCode(RuleCode);
struct SerializeRuleAsCode(Rule);
impl Serialize for SerializeRuleAsCode {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
@ -241,7 +241,7 @@ mod test {
"if (1, 2): pass",
r#"{}"#,
[ExpandedMessage {
code: RuleCode::F634.into(),
code: Rule::IfTuple.into(),
message: "If test is a tuple, which is always `True`".to_string(),
location: Location::new(1, 0),
end_location: Location::new(1, 15),

View File

@ -16,7 +16,7 @@ use crate::directives::Directives;
use crate::doc_lines::{doc_lines_from_ast, doc_lines_from_tokens};
use crate::message::{Message, Source};
use crate::noqa::add_noqa;
use crate::registry::{Diagnostic, LintSource, RuleCode};
use crate::registry::{Diagnostic, LintSource, Rule};
use crate::settings::{flags, Settings};
use crate::source_code::{Indexer, Locator, Stylist};
use crate::{directives, fs, rustpython_helpers, violations};
@ -48,7 +48,7 @@ pub fn check_path(
// Collect doc lines. This requires a rare mix of tokens (for comments) and AST
// (for docstrings), which demands special-casing at this level.
let use_doc_lines = settings.rules.enabled(&RuleCode::W505);
let use_doc_lines = settings.rules.enabled(&Rule::DocLineTooLong);
let mut doc_lines = vec![];
if use_doc_lines {
doc_lines.extend(doc_lines_from_tokens(&tokens));
@ -116,7 +116,7 @@ pub fn check_path(
}
}
Err(parse_error) => {
if settings.rules.enabled(&RuleCode::E999) {
if settings.rules.enabled(&Rule::SyntaxError) {
diagnostics.push(Diagnostic::new(
violations::SyntaxError(parse_error.error.to_string()),
Range::new(parse_error.location, parse_error.location),

View File

@ -8,7 +8,7 @@ use once_cell::sync::Lazy;
use regex::Regex;
use rustc_hash::{FxHashMap, FxHashSet};
use crate::registry::{Diagnostic, RuleCode, CODE_REDIRECTS};
use crate::registry::{Diagnostic, Rule, CODE_REDIRECTS};
use crate::settings::hashable::HashableHashSet;
use crate::source_code::LineEnding;
@ -69,7 +69,7 @@ pub fn extract_noqa_directive(line: &str) -> Directive {
/// Returns `true` if the string list of `codes` includes `code` (or an alias
/// thereof).
pub fn includes(needle: &RuleCode, haystack: &[&str]) -> bool {
pub fn includes(needle: &Rule, haystack: &[&str]) -> bool {
let needle: &str = needle.code();
haystack.iter().any(|candidate| {
if let Some(candidate) = CODE_REDIRECTS.get(candidate) {
@ -101,14 +101,14 @@ fn add_noqa_inner(
external: &HashableHashSet<String>,
line_ending: &LineEnding,
) -> (usize, String) {
let mut matches_by_line: FxHashMap<usize, FxHashSet<&RuleCode>> = FxHashMap::default();
let mut matches_by_line: FxHashMap<usize, FxHashSet<&Rule>> = FxHashMap::default();
for (lineno, line) in contents.lines().enumerate() {
// If we hit an exemption for the entire file, bail.
if is_file_exempt(line) {
return (0, contents.to_string());
}
let mut codes: FxHashSet<&RuleCode> = FxHashSet::default();
let mut codes: FxHashSet<&Rule> = FxHashSet::default();
for diagnostic in diagnostics {
// TODO(charlie): Consider respecting parent `noqa` directives. For now, we'll
// add a `noqa` for every diagnostic, on its own line. This could lead to

View File

@ -1,4 +1,4 @@
//! Registry of [`RuleCode`] to [`DiagnosticKind`] mappings.
//! Registry of [`Rule`] to [`DiagnosticKind`] mappings.
use itertools::Itertools;
use once_cell::sync::Lazy;
@ -542,35 +542,35 @@ pub enum LintSource {
Filesystem,
}
impl RuleCode {
impl Rule {
/// The source for the diagnostic (either the AST, the filesystem, or the
/// physical lines).
pub fn lint_source(&self) -> &'static LintSource {
match self {
RuleCode::RUF100 => &LintSource::NoQa,
RuleCode::E501
| RuleCode::W292
| RuleCode::W505
| RuleCode::UP009
| RuleCode::PGH003
| RuleCode::PGH004 => &LintSource::Lines,
RuleCode::ERA001
| RuleCode::ISC001
| RuleCode::ISC002
| RuleCode::Q000
| RuleCode::Q001
| RuleCode::Q002
| RuleCode::Q003
| RuleCode::W605
| RuleCode::COM812
| RuleCode::COM818
| RuleCode::COM819
| RuleCode::RUF001
| RuleCode::RUF002
| RuleCode::RUF003 => &LintSource::Tokens,
RuleCode::E902 => &LintSource::Io,
RuleCode::I001 | RuleCode::I002 => &LintSource::Imports,
RuleCode::INP001 => &LintSource::Filesystem,
Rule::UnusedNOQA => &LintSource::NoQa,
Rule::LineTooLong
| Rule::NoNewLineAtEndOfFile
| Rule::DocLineTooLong
| Rule::PEP3120UnnecessaryCodingComment
| Rule::BlanketTypeIgnore
| Rule::BlanketNOQA => &LintSource::Lines,
Rule::CommentedOutCode
| Rule::SingleLineImplicitStringConcatenation
| Rule::MultiLineImplicitStringConcatenation
| Rule::BadQuotesInlineString
| Rule::BadQuotesMultilineString
| Rule::BadQuotesDocstring
| Rule::AvoidQuoteEscape
| Rule::InvalidEscapeSequence
| Rule::TrailingCommaMissing
| Rule::TrailingCommaOnBareTupleProhibited
| Rule::TrailingCommaProhibited
| Rule::AmbiguousUnicodeCharacterString
| Rule::AmbiguousUnicodeCharacterDocstring
| Rule::AmbiguousUnicodeCharacterComment => &LintSource::Tokens,
Rule::IOError => &LintSource::Io,
Rule::UnsortedImports | Rule::MissingRequiredImport => &LintSource::Imports,
Rule::ImplicitNamespacePackage => &LintSource::Filesystem,
_ => &LintSource::Ast,
}
}
@ -649,64 +649,64 @@ impl Diagnostic {
}
/// Pairs of checks that shouldn't be enabled together.
pub const INCOMPATIBLE_CODES: &[(RuleCode, RuleCode, &str)] = &[(
RuleCode::D203,
RuleCode::D211,
pub const INCOMPATIBLE_CODES: &[(Rule, Rule, &str)] = &[(
Rule::OneBlankLineBeforeClass,
Rule::NoBlankLineBeforeClass,
"`D203` (OneBlankLineBeforeClass) and `D211` (NoBlankLinesBeforeClass) are incompatible. \
Consider adding `D203` to `ignore`.",
)];
/// A hash map from deprecated to latest `RuleCode`.
pub static CODE_REDIRECTS: Lazy<FxHashMap<&'static str, RuleCode>> = Lazy::new(|| {
/// A hash map from deprecated to latest `Rule`.
pub static CODE_REDIRECTS: Lazy<FxHashMap<&'static str, Rule>> = Lazy::new(|| {
FxHashMap::from_iter([
// TODO(charlie): Remove by 2023-01-01.
("U001", RuleCode::UP001),
("U003", RuleCode::UP003),
("U004", RuleCode::UP004),
("U005", RuleCode::UP005),
("U006", RuleCode::UP006),
("U007", RuleCode::UP007),
("U008", RuleCode::UP008),
("U009", RuleCode::UP009),
("U010", RuleCode::UP010),
("U011", RuleCode::UP011),
("U012", RuleCode::UP012),
("U013", RuleCode::UP013),
("U014", RuleCode::UP014),
("U015", RuleCode::UP015),
("U016", RuleCode::UP016),
("U017", RuleCode::UP017),
("U019", RuleCode::UP019),
("U001", Rule::UselessMetaclassType),
("U003", Rule::TypeOfPrimitive),
("U004", Rule::UselessObjectInheritance),
("U005", Rule::DeprecatedUnittestAlias),
("U006", Rule::UsePEP585Annotation),
("U007", Rule::UsePEP604Annotation),
("U008", Rule::SuperCallWithParameters),
("U009", Rule::PEP3120UnnecessaryCodingComment),
("U010", Rule::UnnecessaryFutureImport),
("U011", Rule::LRUCacheWithoutParameters),
("U012", Rule::UnnecessaryEncodeUTF8),
("U013", Rule::ConvertTypedDictFunctionalToClass),
("U014", Rule::ConvertNamedTupleFunctionalToClass),
("U015", Rule::RedundantOpenModes),
("U016", Rule::RemoveSixCompat),
("U017", Rule::DatetimeTimezoneUTC),
("U019", Rule::TypingTextStrAlias),
// TODO(charlie): Remove by 2023-02-01.
("I252", RuleCode::TID252),
("M001", RuleCode::RUF100),
("I252", Rule::RelativeImports),
("M001", Rule::UnusedNOQA),
// TODO(charlie): Remove by 2023-02-01.
("PDV002", RuleCode::PD002),
("PDV003", RuleCode::PD003),
("PDV004", RuleCode::PD004),
("PDV007", RuleCode::PD007),
("PDV008", RuleCode::PD008),
("PDV009", RuleCode::PD009),
("PDV010", RuleCode::PD010),
("PDV011", RuleCode::PD011),
("PDV012", RuleCode::PD012),
("PDV013", RuleCode::PD013),
("PDV015", RuleCode::PD015),
("PDV901", RuleCode::PD901),
("PDV002", Rule::UseOfInplaceArgument),
("PDV003", Rule::UseOfDotIsNull),
("PDV004", Rule::UseOfDotNotNull),
("PDV007", Rule::UseOfDotIx),
("PDV008", Rule::UseOfDotAt),
("PDV009", Rule::UseOfDotIat),
("PDV010", Rule::UseOfDotPivotOrUnstack),
("PDV011", Rule::UseOfDotValues),
("PDV012", Rule::UseOfDotReadTable),
("PDV013", Rule::UseOfDotStack),
("PDV015", Rule::UseOfPdMerge),
("PDV901", Rule::DfIsABadVariableName),
// TODO(charlie): Remove by 2023-02-01.
("R501", RuleCode::RET501),
("R502", RuleCode::RET502),
("R503", RuleCode::RET503),
("R504", RuleCode::RET504),
("R505", RuleCode::RET505),
("R506", RuleCode::RET506),
("R507", RuleCode::RET507),
("R508", RuleCode::RET508),
("R501", Rule::UnnecessaryReturnNone),
("R502", Rule::ImplicitReturnValue),
("R503", Rule::ImplicitReturn),
("R504", Rule::UnnecessaryAssign),
("R505", Rule::SuperfluousElseReturn),
("R506", Rule::SuperfluousElseRaise),
("R507", Rule::SuperfluousElseContinue),
("R508", Rule::SuperfluousElseBreak),
// TODO(charlie): Remove by 2023-02-01.
("IC001", RuleCode::ICN001),
("IC002", RuleCode::ICN001),
("IC003", RuleCode::ICN001),
("IC004", RuleCode::ICN001),
("IC001", Rule::ImportAliasIsNotConventional),
("IC002", Rule::ImportAliasIsNotConventional),
("IC003", Rule::ImportAliasIsNotConventional),
("IC004", Rule::ImportAliasIsNotConventional),
])
});

View File

@ -10,11 +10,11 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::ERA001, Path::new("ERA001.py"); "ERA001")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::CommentedOutCode, Path::new("ERA001.py"); "ERA001")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/eradicate")

View File

@ -3,7 +3,7 @@ use rustpython_ast::Location;
use super::detection::comment_contains_code;
use crate::ast::types::Range;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::settings::{flags, Settings};
use crate::source_code::Locator;
use crate::violations;
@ -35,7 +35,7 @@ pub fn commented_out_code(
if is_standalone_comment(&line) && comment_contains_code(&line, &settings.task_tags[..]) {
let mut diagnostic = Diagnostic::new(violations::CommentedOutCode, Range::new(start, end));
if matches!(autofix, flags::Autofix::Enabled)
&& settings.rules.should_fix(&RuleCode::ERA001)
&& settings.rules.should_fix(&Rule::CommentedOutCode)
{
diagnostic.amend(Fix::deletion(location, end_location));
}

View File

@ -9,20 +9,20 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::YTT101, Path::new("YTT101.py"); "YTT101")]
#[test_case(RuleCode::YTT102, Path::new("YTT102.py"); "YTT102")]
#[test_case(RuleCode::YTT103, Path::new("YTT103.py"); "YTT103")]
#[test_case(RuleCode::YTT201, Path::new("YTT201.py"); "YTT201")]
#[test_case(RuleCode::YTT202, Path::new("YTT202.py"); "YTT202")]
#[test_case(RuleCode::YTT203, Path::new("YTT203.py"); "YTT203")]
#[test_case(RuleCode::YTT204, Path::new("YTT204.py"); "YTT204")]
#[test_case(RuleCode::YTT301, Path::new("YTT301.py"); "YTT301")]
#[test_case(RuleCode::YTT302, Path::new("YTT302.py"); "YTT302")]
#[test_case(RuleCode::YTT303, Path::new("YTT303.py"); "YTT303")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::SysVersionSlice3Referenced, Path::new("YTT101.py"); "YTT101")]
#[test_case(Rule::SysVersion2Referenced, Path::new("YTT102.py"); "YTT102")]
#[test_case(Rule::SysVersionCmpStr3, Path::new("YTT103.py"); "YTT103")]
#[test_case(Rule::SysVersionInfo0Eq3Referenced, Path::new("YTT201.py"); "YTT201")]
#[test_case(Rule::SixPY3Referenced, Path::new("YTT202.py"); "YTT202")]
#[test_case(Rule::SysVersionInfo1CmpInt, Path::new("YTT203.py"); "YTT203")]
#[test_case(Rule::SysVersionInfoMinorCmpInt, Path::new("YTT204.py"); "YTT204")]
#[test_case(Rule::SysVersion0Referenced, Path::new("YTT301.py"); "YTT301")]
#[test_case(Rule::SysVersionCmpStr10, Path::new("YTT302.py"); "YTT302")]
#[test_case(Rule::SysVersionSlice1Referenced, Path::new("YTT303.py"); "YTT303")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_2020")

View File

@ -3,7 +3,7 @@ use rustpython_ast::{Cmpop, Constant, Expr, ExprKind, Located};
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
fn is_sys(checker: &Checker, expr: &Expr, target: &str) -> bool {
@ -27,13 +27,21 @@ pub fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) {
..
} = &upper.node
{
if *i == BigInt::from(1) && checker.settings.rules.enabled(&RuleCode::YTT303) {
if *i == BigInt::from(1)
&& checker
.settings
.rules
.enabled(&Rule::SysVersionSlice1Referenced)
{
checker.diagnostics.push(Diagnostic::new(
violations::SysVersionSlice1Referenced,
Range::from_located(value),
));
} else if *i == BigInt::from(3)
&& checker.settings.rules.enabled(&RuleCode::YTT101)
&& checker
.settings
.rules
.enabled(&Rule::SysVersionSlice3Referenced)
{
checker.diagnostics.push(Diagnostic::new(
violations::SysVersionSlice3Referenced,
@ -47,12 +55,15 @@ pub fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) {
value: Constant::Int(i),
..
} => {
if *i == BigInt::from(2) && checker.settings.rules.enabled(&RuleCode::YTT102) {
if *i == BigInt::from(2)
&& checker.settings.rules.enabled(&Rule::SysVersion2Referenced)
{
checker.diagnostics.push(Diagnostic::new(
violations::SysVersion2Referenced,
Range::from_located(value),
));
} else if *i == BigInt::from(0) && checker.settings.rules.enabled(&RuleCode::YTT301)
} else if *i == BigInt::from(0)
&& checker.settings.rules.enabled(&Rule::SysVersion0Referenced)
{
checker.diagnostics.push(Diagnostic::new(
violations::SysVersion0Referenced,
@ -89,7 +100,10 @@ pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &
) = (ops, comparators)
{
if *n == BigInt::from(3)
&& checker.settings.rules.enabled(&RuleCode::YTT201)
&& checker
.settings
.rules
.enabled(&Rule::SysVersionInfo0Eq3Referenced)
{
checker.diagnostics.push(Diagnostic::new(
violations::SysVersionInfo0Eq3Referenced,
@ -110,7 +124,7 @@ pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &
}],
) = (ops, comparators)
{
if checker.settings.rules.enabled(&RuleCode::YTT203) {
if checker.settings.rules.enabled(&Rule::SysVersionInfo1CmpInt) {
checker.diagnostics.push(Diagnostic::new(
violations::SysVersionInfo1CmpInt,
Range::from_located(left),
@ -136,7 +150,11 @@ pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &
}],
) = (ops, comparators)
{
if checker.settings.rules.enabled(&RuleCode::YTT204) {
if checker
.settings
.rules
.enabled(&Rule::SysVersionInfoMinorCmpInt)
{
checker.diagnostics.push(Diagnostic::new(
violations::SysVersionInfoMinorCmpInt,
Range::from_located(left),
@ -162,13 +180,13 @@ pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &
) = (ops, comparators)
{
if s.len() == 1 {
if checker.settings.rules.enabled(&RuleCode::YTT302) {
if checker.settings.rules.enabled(&Rule::SysVersionCmpStr10) {
checker.diagnostics.push(Diagnostic::new(
violations::SysVersionCmpStr10,
Range::from_located(left),
));
}
} else if checker.settings.rules.enabled(&RuleCode::YTT103) {
} else if checker.settings.rules.enabled(&Rule::SysVersionCmpStr3) {
checker.diagnostics.push(Diagnostic::new(
violations::SysVersionCmpStr3,
Range::from_located(left),

View File

@ -11,7 +11,7 @@ mod tests {
use anyhow::Result;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings::Settings;
#[test]
@ -20,17 +20,17 @@ mod tests {
Path::new("./resources/test/fixtures/flake8_annotations/annotation_presence.py"),
&Settings {
..Settings::for_rules(vec![
RuleCode::ANN001,
RuleCode::ANN002,
RuleCode::ANN003,
RuleCode::ANN101,
RuleCode::ANN102,
RuleCode::ANN201,
RuleCode::ANN202,
RuleCode::ANN204,
RuleCode::ANN205,
RuleCode::ANN206,
RuleCode::ANN401,
Rule::MissingTypeFunctionArgument,
Rule::MissingTypeArgs,
Rule::MissingTypeKwargs,
Rule::MissingTypeSelf,
Rule::MissingTypeCls,
Rule::MissingReturnTypePublicFunction,
Rule::MissingReturnTypePrivateFunction,
Rule::MissingReturnTypeSpecialMethod,
Rule::MissingReturnTypeStaticMethod,
Rule::MissingReturnTypeClassMethod,
Rule::DynamicallyTypedExpression,
])
},
)?;
@ -50,11 +50,11 @@ mod tests {
allow_star_arg_any: false,
},
..Settings::for_rules(vec![
RuleCode::ANN001,
RuleCode::ANN002,
RuleCode::ANN003,
RuleCode::ANN101,
RuleCode::ANN102,
Rule::MissingTypeFunctionArgument,
Rule::MissingTypeArgs,
Rule::MissingTypeKwargs,
Rule::MissingTypeSelf,
Rule::MissingTypeCls,
])
},
)?;
@ -74,11 +74,11 @@ mod tests {
allow_star_arg_any: false,
},
..Settings::for_rules(vec![
RuleCode::ANN201,
RuleCode::ANN202,
RuleCode::ANN204,
RuleCode::ANN205,
RuleCode::ANN206,
Rule::MissingReturnTypePublicFunction,
Rule::MissingReturnTypePrivateFunction,
Rule::MissingReturnTypeSpecialMethod,
Rule::MissingReturnTypeStaticMethod,
Rule::MissingReturnTypeClassMethod,
])
},
)?;
@ -98,11 +98,11 @@ mod tests {
allow_star_arg_any: false,
},
..Settings::for_rules(vec![
RuleCode::ANN201,
RuleCode::ANN202,
RuleCode::ANN204,
RuleCode::ANN205,
RuleCode::ANN206,
Rule::MissingReturnTypePublicFunction,
Rule::MissingReturnTypePrivateFunction,
Rule::MissingReturnTypeSpecialMethod,
Rule::MissingReturnTypeStaticMethod,
Rule::MissingReturnTypeClassMethod,
])
},
)?;
@ -121,7 +121,7 @@ mod tests {
suppress_none_returning: false,
allow_star_arg_any: true,
},
..Settings::for_rules(vec![RuleCode::ANN401])
..Settings::for_rules(vec![Rule::DynamicallyTypedExpression])
},
)?;
insta::assert_yaml_snapshot!(diagnostics);
@ -134,11 +134,11 @@ mod tests {
Path::new("./resources/test/fixtures/flake8_annotations/allow_overload.py"),
&Settings {
..Settings::for_rules(vec![
RuleCode::ANN201,
RuleCode::ANN202,
RuleCode::ANN204,
RuleCode::ANN205,
RuleCode::ANN206,
Rule::MissingReturnTypePublicFunction,
Rule::MissingReturnTypePrivateFunction,
Rule::MissingReturnTypeSpecialMethod,
Rule::MissingReturnTypeStaticMethod,
Rule::MissingReturnTypeClassMethod,
])
},
)?;
@ -152,11 +152,11 @@ mod tests {
Path::new("./resources/test/fixtures/flake8_annotations/allow_nested_overload.py"),
&Settings {
..Settings::for_rules(vec![
RuleCode::ANN201,
RuleCode::ANN202,
RuleCode::ANN204,
RuleCode::ANN205,
RuleCode::ANN206,
Rule::MissingReturnTypePublicFunction,
Rule::MissingReturnTypePrivateFunction,
Rule::MissingReturnTypeSpecialMethod,
Rule::MissingReturnTypeStaticMethod,
Rule::MissingReturnTypeClassMethod,
])
},
)?;

View File

@ -8,7 +8,7 @@ use crate::ast::visitor::Visitor;
use crate::ast::{cast, helpers, visitor};
use crate::checkers::ast::Checker;
use crate::docstrings::definition::{Definition, DefinitionKind};
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::visibility::Visibility;
use crate::{violations, visibility};
@ -85,14 +85,22 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
.chain(args.kwonlyargs.iter())
{
if let Some(expr) = &arg.node.annotation {
if checker.settings.rules.enabled(&RuleCode::ANN401) {
if checker
.settings
.rules
.enabled(&Rule::DynamicallyTypedExpression)
{
check_dynamically_typed(checker, expr, || arg.node.arg.to_string());
};
} else {
if !(checker.settings.flake8_annotations.suppress_dummy_args
&& checker.settings.dummy_variable_rgx.is_match(&arg.node.arg))
{
if checker.settings.rules.enabled(&RuleCode::ANN001) {
if checker
.settings
.rules
.enabled(&Rule::MissingTypeFunctionArgument)
{
checker.diagnostics.push(Diagnostic::new(
violations::MissingTypeFunctionArgument(arg.node.arg.to_string()),
Range::from_located(arg),
@ -106,7 +114,11 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
if let Some(arg) = &args.vararg {
if let Some(expr) = &arg.node.annotation {
if !checker.settings.flake8_annotations.allow_star_arg_any {
if checker.settings.rules.enabled(&RuleCode::ANN401) {
if checker
.settings
.rules
.enabled(&Rule::DynamicallyTypedExpression)
{
let name = arg.node.arg.to_string();
check_dynamically_typed(checker, expr, || format!("*{name}"));
}
@ -115,7 +127,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
if !(checker.settings.flake8_annotations.suppress_dummy_args
&& checker.settings.dummy_variable_rgx.is_match(&arg.node.arg))
{
if checker.settings.rules.enabled(&RuleCode::ANN002) {
if checker.settings.rules.enabled(&Rule::MissingTypeArgs) {
checker.diagnostics.push(Diagnostic::new(
violations::MissingTypeArgs(arg.node.arg.to_string()),
Range::from_located(arg),
@ -129,7 +141,11 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
if let Some(arg) = &args.kwarg {
if let Some(expr) = &arg.node.annotation {
if !checker.settings.flake8_annotations.allow_star_arg_any {
if checker.settings.rules.enabled(&RuleCode::ANN401) {
if checker
.settings
.rules
.enabled(&Rule::DynamicallyTypedExpression)
{
let name = arg.node.arg.to_string();
check_dynamically_typed(checker, expr, || format!("**{name}"));
}
@ -138,7 +154,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
if !(checker.settings.flake8_annotations.suppress_dummy_args
&& checker.settings.dummy_variable_rgx.is_match(&arg.node.arg))
{
if checker.settings.rules.enabled(&RuleCode::ANN003) {
if checker.settings.rules.enabled(&Rule::MissingTypeKwargs) {
checker.diagnostics.push(Diagnostic::new(
violations::MissingTypeKwargs(arg.node.arg.to_string()),
Range::from_located(arg),
@ -150,7 +166,11 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
// ANN201, ANN202, ANN401
if let Some(expr) = &returns {
if checker.settings.rules.enabled(&RuleCode::ANN401) {
if checker
.settings
.rules
.enabled(&Rule::DynamicallyTypedExpression)
{
check_dynamically_typed(checker, expr, || name.to_string());
};
} else {
@ -164,7 +184,11 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
match visibility {
Visibility::Public => {
if checker.settings.rules.enabled(&RuleCode::ANN201) {
if checker
.settings
.rules
.enabled(&Rule::MissingReturnTypePublicFunction)
{
checker.diagnostics.push(Diagnostic::new(
violations::MissingReturnTypePublicFunction(name.to_string()),
helpers::identifier_range(stmt, checker.locator),
@ -172,7 +196,11 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
}
}
Visibility::Private => {
if checker.settings.rules.enabled(&RuleCode::ANN202) {
if checker
.settings
.rules
.enabled(&Rule::MissingReturnTypePrivateFunction)
{
checker.diagnostics.push(Diagnostic::new(
violations::MissingReturnTypePrivateFunction(name.to_string()),
helpers::identifier_range(stmt, checker.locator),
@ -203,14 +231,22 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
// ANN401 for dynamically typed arguments
if let Some(annotation) = &arg.node.annotation {
has_any_typed_arg = true;
if checker.settings.rules.enabled(&RuleCode::ANN401) {
if checker
.settings
.rules
.enabled(&Rule::DynamicallyTypedExpression)
{
check_dynamically_typed(checker, annotation, || arg.node.arg.to_string());
}
} else {
if !(checker.settings.flake8_annotations.suppress_dummy_args
&& checker.settings.dummy_variable_rgx.is_match(&arg.node.arg))
{
if checker.settings.rules.enabled(&RuleCode::ANN001) {
if checker
.settings
.rules
.enabled(&Rule::MissingTypeFunctionArgument)
{
checker.diagnostics.push(Diagnostic::new(
violations::MissingTypeFunctionArgument(arg.node.arg.to_string()),
Range::from_located(arg),
@ -225,7 +261,11 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
has_any_typed_arg = true;
if let Some(expr) = &arg.node.annotation {
if !checker.settings.flake8_annotations.allow_star_arg_any {
if checker.settings.rules.enabled(&RuleCode::ANN401) {
if checker
.settings
.rules
.enabled(&Rule::DynamicallyTypedExpression)
{
let name = arg.node.arg.to_string();
check_dynamically_typed(checker, expr, || format!("*{name}"));
}
@ -234,7 +274,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
if !(checker.settings.flake8_annotations.suppress_dummy_args
&& checker.settings.dummy_variable_rgx.is_match(&arg.node.arg))
{
if checker.settings.rules.enabled(&RuleCode::ANN002) {
if checker.settings.rules.enabled(&Rule::MissingTypeArgs) {
checker.diagnostics.push(Diagnostic::new(
violations::MissingTypeArgs(arg.node.arg.to_string()),
Range::from_located(arg),
@ -249,7 +289,11 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
has_any_typed_arg = true;
if let Some(expr) = &arg.node.annotation {
if !checker.settings.flake8_annotations.allow_star_arg_any {
if checker.settings.rules.enabled(&RuleCode::ANN401) {
if checker
.settings
.rules
.enabled(&Rule::DynamicallyTypedExpression)
{
let name = arg.node.arg.to_string();
check_dynamically_typed(checker, expr, || format!("**{name}"));
}
@ -258,7 +302,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
if !(checker.settings.flake8_annotations.suppress_dummy_args
&& checker.settings.dummy_variable_rgx.is_match(&arg.node.arg))
{
if checker.settings.rules.enabled(&RuleCode::ANN003) {
if checker.settings.rules.enabled(&Rule::MissingTypeKwargs) {
checker.diagnostics.push(Diagnostic::new(
violations::MissingTypeKwargs(arg.node.arg.to_string()),
Range::from_located(arg),
@ -273,14 +317,14 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
if let Some(arg) = args.args.first() {
if arg.node.annotation.is_none() {
if visibility::is_classmethod(checker, cast::decorator_list(stmt)) {
if checker.settings.rules.enabled(&RuleCode::ANN102) {
if checker.settings.rules.enabled(&Rule::MissingTypeCls) {
checker.diagnostics.push(Diagnostic::new(
violations::MissingTypeCls(arg.node.arg.to_string()),
Range::from_located(arg),
));
}
} else {
if checker.settings.rules.enabled(&RuleCode::ANN101) {
if checker.settings.rules.enabled(&Rule::MissingTypeSelf) {
checker.diagnostics.push(Diagnostic::new(
violations::MissingTypeSelf(arg.node.arg.to_string()),
Range::from_located(arg),
@ -293,7 +337,11 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
// ANN201, ANN202
if let Some(expr) = &returns {
if checker.settings.rules.enabled(&RuleCode::ANN401) {
if checker
.settings
.rules
.enabled(&Rule::DynamicallyTypedExpression)
{
check_dynamically_typed(checker, expr, || name.to_string());
}
} else {
@ -306,14 +354,22 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
}
if visibility::is_classmethod(checker, cast::decorator_list(stmt)) {
if checker.settings.rules.enabled(&RuleCode::ANN206) {
if checker
.settings
.rules
.enabled(&Rule::MissingReturnTypeClassMethod)
{
checker.diagnostics.push(Diagnostic::new(
violations::MissingReturnTypeClassMethod(name.to_string()),
helpers::identifier_range(stmt, checker.locator),
));
}
} else if visibility::is_staticmethod(checker, cast::decorator_list(stmt)) {
if checker.settings.rules.enabled(&RuleCode::ANN205) {
if checker
.settings
.rules
.enabled(&Rule::MissingReturnTypeStaticMethod)
{
checker.diagnostics.push(Diagnostic::new(
violations::MissingReturnTypeStaticMethod(name.to_string()),
helpers::identifier_range(stmt, checker.locator),
@ -322,7 +378,11 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
} else if visibility::is_init(cast::name(stmt)) {
// Allow omission of return annotation in `__init__` functions, as long as at
// least one argument is typed.
if checker.settings.rules.enabled(&RuleCode::ANN204) {
if checker
.settings
.rules
.enabled(&Rule::MissingReturnTypeSpecialMethod)
{
if !(checker.settings.flake8_annotations.mypy_init_return
&& has_any_typed_arg)
{
@ -342,7 +402,11 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
}
}
} else if visibility::is_magic(cast::name(stmt)) {
if checker.settings.rules.enabled(&RuleCode::ANN204) {
if checker
.settings
.rules
.enabled(&Rule::MissingReturnTypeSpecialMethod)
{
checker.diagnostics.push(Diagnostic::new(
violations::MissingReturnTypeSpecialMethod(name.to_string()),
helpers::identifier_range(stmt, checker.locator),
@ -351,7 +415,11 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
} else {
match visibility {
Visibility::Public => {
if checker.settings.rules.enabled(&RuleCode::ANN201) {
if checker
.settings
.rules
.enabled(&Rule::MissingReturnTypePublicFunction)
{
checker.diagnostics.push(Diagnostic::new(
violations::MissingReturnTypePublicFunction(name.to_string()),
helpers::identifier_range(stmt, checker.locator),
@ -359,7 +427,11 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
}
}
Visibility::Private => {
if checker.settings.rules.enabled(&RuleCode::ANN202) {
if checker
.settings
.rules
.enabled(&Rule::MissingReturnTypePrivateFunction)
{
checker.diagnostics.push(Diagnostic::new(
violations::MissingReturnTypePrivateFunction(name.to_string()),
helpers::identifier_range(stmt, checker.locator),

View File

@ -11,25 +11,25 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings::Settings;
#[test_case(RuleCode::S101, Path::new("S101.py"); "S101")]
#[test_case(RuleCode::S102, Path::new("S102.py"); "S102")]
#[test_case(RuleCode::S103, Path::new("S103.py"); "S103")]
#[test_case(RuleCode::S104, Path::new("S104.py"); "S104")]
#[test_case(RuleCode::S105, Path::new("S105.py"); "S105")]
#[test_case(RuleCode::S106, Path::new("S106.py"); "S106")]
#[test_case(RuleCode::S107, Path::new("S107.py"); "S107")]
#[test_case(RuleCode::S108, Path::new("S108.py"); "S108")]
#[test_case(RuleCode::S113, Path::new("S113.py"); "S113")]
#[test_case(RuleCode::S324, Path::new("S324.py"); "S324")]
#[test_case(RuleCode::S501, Path::new("S501.py"); "S501")]
#[test_case(RuleCode::S506, Path::new("S506.py"); "S506")]
#[test_case(RuleCode::S508, Path::new("S508.py"); "S508")]
#[test_case(RuleCode::S509, Path::new("S509.py"); "S509")]
#[test_case(RuleCode::S701, Path::new("S701.py"); "S701")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::AssertUsed, Path::new("S101.py"); "S101")]
#[test_case(Rule::ExecUsed, Path::new("S102.py"); "S102")]
#[test_case(Rule::BadFilePermissions, Path::new("S103.py"); "S103")]
#[test_case(Rule::HardcodedBindAllInterfaces, Path::new("S104.py"); "S104")]
#[test_case(Rule::HardcodedPasswordString, Path::new("S105.py"); "S105")]
#[test_case(Rule::HardcodedPasswordFuncArg, Path::new("S106.py"); "S106")]
#[test_case(Rule::HardcodedPasswordDefault, Path::new("S107.py"); "S107")]
#[test_case(Rule::HardcodedTempFile, Path::new("S108.py"); "S108")]
#[test_case(Rule::RequestWithoutTimeout, Path::new("S113.py"); "S113")]
#[test_case(Rule::HashlibInsecureHashFunction, Path::new("S324.py"); "S324")]
#[test_case(Rule::RequestWithNoCertValidation, Path::new("S501.py"); "S501")]
#[test_case(Rule::UnsafeYAMLLoad, Path::new("S506.py"); "S506")]
#[test_case(Rule::SnmpInsecureVersion, Path::new("S508.py"); "S508")]
#[test_case(Rule::SnmpWeakCryptography, Path::new("S509.py"); "S509")]
#[test_case(Rule::Jinja2AutoescapeFalse, Path::new("S701.py"); "S701")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_bandit")
@ -54,7 +54,7 @@ mod tests {
"/foo".to_string(),
],
},
..Settings::for_rule(RuleCode::S108)
..Settings::for_rule(Rule::HardcodedTempFile)
},
)?;
insta::assert_yaml_snapshot!("S108_extend", diagnostics);

View File

@ -9,11 +9,11 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::BLE001, Path::new("BLE.py"); "BLE001")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::BlindExcept, Path::new("BLE.py"); "BLE001")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_blind_except")

View File

@ -9,13 +9,13 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::FBT001, Path::new("FBT.py"); "FBT001")]
#[test_case(RuleCode::FBT002, Path::new("FBT.py"); "FBT002")]
#[test_case(RuleCode::FBT003, Path::new("FBT.py"); "FBT003")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::BooleanPositionalArgInFunctionDefinition, Path::new("FBT.py"); "FBT001")]
#[test_case(Rule::BooleanDefaultValueInFunctionDefinition, Path::new("FBT.py"); "FBT002")]
#[test_case(Rule::BooleanPositionalValueInFunctionCall, Path::new("FBT.py"); "FBT003")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_boolean_trap")

View File

@ -10,38 +10,38 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings::Settings;
#[test_case(RuleCode::B002, Path::new("B002.py"); "B002")]
#[test_case(RuleCode::B003, Path::new("B003.py"); "B003")]
#[test_case(RuleCode::B004, Path::new("B004.py"); "B004")]
#[test_case(RuleCode::B005, Path::new("B005.py"); "B005")]
#[test_case(RuleCode::B006, Path::new("B006_B008.py"); "B006")]
#[test_case(RuleCode::B007, Path::new("B007.py"); "B007")]
#[test_case(RuleCode::B008, Path::new("B006_B008.py"); "B008")]
#[test_case(RuleCode::B009, Path::new("B009_B010.py"); "B009")]
#[test_case(RuleCode::B010, Path::new("B009_B010.py"); "B010")]
#[test_case(RuleCode::B011, Path::new("B011.py"); "B011")]
#[test_case(RuleCode::B012, Path::new("B012.py"); "B012")]
#[test_case(RuleCode::B013, Path::new("B013.py"); "B013")]
#[test_case(RuleCode::B014, Path::new("B014.py"); "B014")]
#[test_case(RuleCode::B015, Path::new("B015.py"); "B015")]
#[test_case(RuleCode::B016, Path::new("B016.py"); "B016")]
#[test_case(RuleCode::B017, Path::new("B017.py"); "B017")]
#[test_case(RuleCode::B018, Path::new("B018.py"); "B018")]
#[test_case(RuleCode::B019, Path::new("B019.py"); "B019")]
#[test_case(RuleCode::B020, Path::new("B020.py"); "B020")]
#[test_case(RuleCode::B021, Path::new("B021.py"); "B021")]
#[test_case(RuleCode::B022, Path::new("B022.py"); "B022")]
#[test_case(RuleCode::B023, Path::new("B023.py"); "B023")]
#[test_case(RuleCode::B024, Path::new("B024.py"); "B024")]
#[test_case(RuleCode::B025, Path::new("B025.py"); "B025")]
#[test_case(RuleCode::B026, Path::new("B026.py"); "B026")]
#[test_case(RuleCode::B027, Path::new("B027.py"); "B027")]
#[test_case(RuleCode::B904, Path::new("B904.py"); "B904")]
#[test_case(RuleCode::B905, Path::new("B905.py"); "B905")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::UnaryPrefixIncrement, Path::new("B002.py"); "B002")]
#[test_case(Rule::AssignmentToOsEnviron, Path::new("B003.py"); "B003")]
#[test_case(Rule::UnreliableCallableCheck, Path::new("B004.py"); "B004")]
#[test_case(Rule::StripWithMultiCharacters, Path::new("B005.py"); "B005")]
#[test_case(Rule::MutableArgumentDefault, Path::new("B006_B008.py"); "B006")]
#[test_case(Rule::UnusedLoopControlVariable, Path::new("B007.py"); "B007")]
#[test_case(Rule::FunctionCallArgumentDefault, Path::new("B006_B008.py"); "B008")]
#[test_case(Rule::GetAttrWithConstant, Path::new("B009_B010.py"); "B009")]
#[test_case(Rule::SetAttrWithConstant, Path::new("B009_B010.py"); "B010")]
#[test_case(Rule::DoNotAssertFalse, Path::new("B011.py"); "B011")]
#[test_case(Rule::JumpStatementInFinally, Path::new("B012.py"); "B012")]
#[test_case(Rule::RedundantTupleInExceptionHandler, Path::new("B013.py"); "B013")]
#[test_case(Rule::DuplicateHandlerException, Path::new("B014.py"); "B014")]
#[test_case(Rule::UselessComparison, Path::new("B015.py"); "B015")]
#[test_case(Rule::CannotRaiseLiteral, Path::new("B016.py"); "B016")]
#[test_case(Rule::NoAssertRaisesException, Path::new("B017.py"); "B017")]
#[test_case(Rule::UselessExpression, Path::new("B018.py"); "B018")]
#[test_case(Rule::CachedInstanceMethod, Path::new("B019.py"); "B019")]
#[test_case(Rule::LoopVariableOverridesIterator, Path::new("B020.py"); "B020")]
#[test_case(Rule::FStringDocstring, Path::new("B021.py"); "B021")]
#[test_case(Rule::UselessContextlibSuppress, Path::new("B022.py"); "B022")]
#[test_case(Rule::FunctionUsesLoopVariable, Path::new("B023.py"); "B023")]
#[test_case(Rule::AbstractBaseClassWithoutAbstractMethod, Path::new("B024.py"); "B024")]
#[test_case(Rule::DuplicateTryBlockException, Path::new("B025.py"); "B025")]
#[test_case(Rule::StarArgUnpackingAfterKeywordArg, Path::new("B026.py"); "B026")]
#[test_case(Rule::EmptyMethodWithoutAbstractDecorator, Path::new("B027.py"); "B027")]
#[test_case(Rule::RaiseWithoutFromInsideExcept, Path::new("B904.py"); "B904")]
#[test_case(Rule::ZipWithoutExplicitStrict, Path::new("B905.py"); "B905")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_bugbear")
@ -65,7 +65,7 @@ mod tests {
"fastapi.Query".to_string(),
],
},
..Settings::for_rules(vec![RuleCode::B008])
..Settings::for_rules(vec![Rule::FunctionCallArgumentDefault])
},
)?;
insta::assert_yaml_snapshot!(snapshot, diagnostics);

View File

@ -2,7 +2,7 @@ use rustpython_ast::{Constant, Expr, ExprKind, Keyword, Stmt, StmtKind};
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
use crate::visibility::{is_abstract, is_overload};
@ -78,7 +78,11 @@ pub fn abstract_base_class(
let has_abstract_decorator = is_abstract(checker, decorator_list);
has_abstract_method |= has_abstract_decorator;
if !checker.settings.rules.enabled(&RuleCode::B027) {
if !checker
.settings
.rules
.enabled(&Rule::EmptyMethodWithoutAbstractDecorator)
{
continue;
}
@ -89,7 +93,11 @@ pub fn abstract_base_class(
));
}
}
if checker.settings.rules.enabled(&RuleCode::B024) {
if checker
.settings
.rules
.enabled(&Rule::AbstractBaseClassWithoutAbstractMethod)
{
if !has_abstract_method {
checker.diagnostics.push(Diagnostic::new(
violations::AbstractBaseClassWithoutAbstractMethod(name.to_string()),

View File

@ -6,7 +6,7 @@ use crate::ast::helpers;
use crate::ast::types::{CallPath, Range};
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::source_code::Generator;
use crate::violations;
@ -41,7 +41,11 @@ fn duplicate_handler_exceptions<'a>(
}
}
if checker.settings.rules.enabled(&RuleCode::B014) {
if checker
.settings
.rules
.enabled(&Rule::DuplicateHandlerException)
{
// TODO(charlie): Handle "BaseException" and redundant exception aliases.
if !duplicates.is_empty() {
let mut diagnostic = Diagnostic::new(
@ -105,7 +109,11 @@ pub fn duplicate_exceptions(checker: &mut Checker, handlers: &[Excepthandler]) {
}
}
if checker.settings.rules.enabled(&RuleCode::B025) {
if checker
.settings
.rules
.enabled(&Rule::DuplicateTryBlockException)
{
for (name, exprs) in duplicates {
for expr in exprs {
checker.diagnostics.push(Diagnostic::new(

View File

@ -10,13 +10,13 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::A001, Path::new("A001.py"); "A001")]
#[test_case(RuleCode::A002, Path::new("A002.py"); "A002")]
#[test_case(RuleCode::A003, Path::new("A003.py"); "A003")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::BuiltinVariableShadowing, Path::new("A001.py"); "A001")]
#[test_case(Rule::BuiltinArgumentShadowing, Path::new("A002.py"); "A002")]
#[test_case(Rule::BuiltinAttributeShadowing, Path::new("A003.py"); "A003")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_builtins")

View File

@ -9,7 +9,7 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(Path::new("COM81.py"); "COM81")]
@ -20,9 +20,9 @@ mod tests {
.join(path)
.as_path(),
&settings::Settings::for_rules(vec![
RuleCode::COM812,
RuleCode::COM818,
RuleCode::COM819,
Rule::TrailingCommaMissing,
Rule::TrailingCommaOnBareTupleProhibited,
Rule::TrailingCommaProhibited,
]),
)?;
insta::assert_yaml_snapshot!(snapshot, diagnostics);

View File

@ -4,7 +4,7 @@ use rustpython_parser::token::Tok;
use crate::ast::types::Range;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::settings::{flags, Settings};
use crate::violations;
@ -219,7 +219,7 @@ pub fn trailing_commas(
},
);
if matches!(autofix, flags::Autofix::Enabled)
&& settings.rules.should_fix(&RuleCode::COM819)
&& settings.rules.should_fix(&Rule::TrailingCommaProhibited)
{
diagnostic.amend(Fix::deletion(comma.0, comma.2));
}
@ -265,7 +265,7 @@ pub fn trailing_commas(
},
);
if matches!(autofix, flags::Autofix::Enabled)
&& settings.rules.should_fix(&RuleCode::COM812)
&& settings.rules.should_fix(&Rule::TrailingCommaMissing)
{
diagnostic.amend(Fix::insertion(",".to_owned(), missing_comma.2));
}

View File

@ -10,27 +10,27 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::C400, Path::new("C400.py"); "C400")]
#[test_case(RuleCode::C401, Path::new("C401.py"); "C401")]
#[test_case(RuleCode::C402, Path::new("C402.py"); "C402")]
#[test_case(RuleCode::C403, Path::new("C403.py"); "C403")]
#[test_case(RuleCode::C404, Path::new("C404.py"); "C404")]
#[test_case(RuleCode::C405, Path::new("C405.py"); "C405")]
#[test_case(RuleCode::C406, Path::new("C406.py"); "C406")]
#[test_case(RuleCode::C408, Path::new("C408.py"); "C408")]
#[test_case(RuleCode::C409, Path::new("C409.py"); "C409")]
#[test_case(RuleCode::C410, Path::new("C410.py"); "C410")]
#[test_case(RuleCode::C411, Path::new("C411.py"); "C411")]
#[test_case(RuleCode::C413, Path::new("C413.py"); "C413")]
#[test_case(RuleCode::C414, Path::new("C414.py"); "C414")]
#[test_case(RuleCode::C415, Path::new("C415.py"); "C415")]
#[test_case(RuleCode::C416, Path::new("C416.py"); "C416")]
#[test_case(RuleCode::C417, Path::new("C417.py"); "C417")]
#[test_case(Rule::UnnecessaryGeneratorList, Path::new("C400.py"); "C400")]
#[test_case(Rule::UnnecessaryGeneratorSet, Path::new("C401.py"); "C401")]
#[test_case(Rule::UnnecessaryGeneratorDict, Path::new("C402.py"); "C402")]
#[test_case(Rule::UnnecessaryListComprehensionSet, Path::new("C403.py"); "C403")]
#[test_case(Rule::UnnecessaryListComprehensionDict, Path::new("C404.py"); "C404")]
#[test_case(Rule::UnnecessaryLiteralSet, Path::new("C405.py"); "C405")]
#[test_case(Rule::UnnecessaryLiteralDict, Path::new("C406.py"); "C406")]
#[test_case(Rule::UnnecessaryCollectionCall, Path::new("C408.py"); "C408")]
#[test_case(Rule::UnnecessaryLiteralWithinTupleCall, Path::new("C409.py"); "C409")]
#[test_case(Rule::UnnecessaryLiteralWithinListCall, Path::new("C410.py"); "C410")]
#[test_case(Rule::UnnecessaryListCall, Path::new("C411.py"); "C411")]
#[test_case(Rule::UnnecessaryCallAroundSorted, Path::new("C413.py"); "C413")]
#[test_case(Rule::UnnecessaryDoubleCastOrProcess, Path::new("C414.py"); "C414")]
#[test_case(Rule::UnnecessarySubscriptReversal, Path::new("C415.py"); "C415")]
#[test_case(Rule::UnnecessaryComprehension, Path::new("C416.py"); "C416")]
#[test_case(Rule::UnnecessaryMap, Path::new("C417.py"); "C417")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_comprehensions")

View File

@ -5,7 +5,7 @@ use rustpython_ast::{Comprehension, Constant, Expr, ExprKind, Keyword, Unaryop};
use super::fixes;
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
fn function_name(func: &Expr) -> Option<&str> {
@ -65,7 +65,7 @@ pub fn unnecessary_generator_list(
violations::UnnecessaryGeneratorList,
Range::from_located(expr),
);
if checker.patch(&RuleCode::C400) {
if checker.patch(&Rule::UnnecessaryGeneratorList) {
match fixes::fix_unnecessary_generator_list(checker.locator, expr) {
Ok(fix) => {
diagnostic.amend(fix);
@ -96,7 +96,7 @@ pub fn unnecessary_generator_set(
violations::UnnecessaryGeneratorSet,
Range::from_located(expr),
);
if checker.patch(&RuleCode::C401) {
if checker.patch(&Rule::UnnecessaryGeneratorSet) {
match fixes::fix_unnecessary_generator_set(checker.locator, expr) {
Ok(fix) => {
diagnostic.amend(fix);
@ -126,7 +126,7 @@ pub fn unnecessary_generator_dict(
violations::UnnecessaryGeneratorDict,
Range::from_located(expr),
);
if checker.patch(&RuleCode::C402) {
if checker.patch(&Rule::UnnecessaryGeneratorDict) {
match fixes::fix_unnecessary_generator_dict(checker.locator, expr) {
Ok(fix) => {
diagnostic.amend(fix);
@ -160,7 +160,7 @@ pub fn unnecessary_list_comprehension_set(
violations::UnnecessaryListComprehensionSet,
Range::from_located(expr),
);
if checker.patch(&RuleCode::C403) {
if checker.patch(&Rule::UnnecessaryListComprehensionSet) {
match fixes::fix_unnecessary_list_comprehension_set(checker.locator, expr) {
Ok(fix) => {
diagnostic.amend(fix);
@ -199,7 +199,7 @@ pub fn unnecessary_list_comprehension_dict(
violations::UnnecessaryListComprehensionDict,
Range::from_located(expr),
);
if checker.patch(&RuleCode::C404) {
if checker.patch(&Rule::UnnecessaryListComprehensionDict) {
match fixes::fix_unnecessary_list_comprehension_dict(checker.locator, expr) {
Ok(fix) => {
diagnostic.amend(fix);
@ -233,7 +233,7 @@ pub fn unnecessary_literal_set(
violations::UnnecessaryLiteralSet(kind.to_string()),
Range::from_located(expr),
);
if checker.patch(&RuleCode::C405) {
if checker.patch(&Rule::UnnecessaryLiteralSet) {
match fixes::fix_unnecessary_literal_set(checker.locator, expr) {
Ok(fix) => {
diagnostic.amend(fix);
@ -274,7 +274,7 @@ pub fn unnecessary_literal_dict(
violations::UnnecessaryLiteralDict(kind.to_string()),
Range::from_located(expr),
);
if checker.patch(&RuleCode::C406) {
if checker.patch(&Rule::UnnecessaryLiteralDict) {
match fixes::fix_unnecessary_literal_dict(checker.locator, expr) {
Ok(fix) => {
diagnostic.amend(fix);
@ -315,7 +315,7 @@ pub fn unnecessary_collection_call(
violations::UnnecessaryCollectionCall(id.to_string()),
Range::from_located(expr),
);
if checker.patch(&RuleCode::C408) {
if checker.patch(&Rule::UnnecessaryCollectionCall) {
match fixes::fix_unnecessary_collection_call(checker.locator, expr) {
Ok(fix) => {
diagnostic.amend(fix);
@ -348,7 +348,7 @@ pub fn unnecessary_literal_within_tuple_call(
violations::UnnecessaryLiteralWithinTupleCall(argument_kind.to_string()),
Range::from_located(expr),
);
if checker.patch(&RuleCode::C409) {
if checker.patch(&Rule::UnnecessaryLiteralWithinTupleCall) {
match fixes::fix_unnecessary_literal_within_tuple_call(checker.locator, expr) {
Ok(fix) => {
diagnostic.amend(fix);
@ -381,7 +381,7 @@ pub fn unnecessary_literal_within_list_call(
violations::UnnecessaryLiteralWithinListCall(argument_kind.to_string()),
Range::from_located(expr),
);
if checker.patch(&RuleCode::C410) {
if checker.patch(&Rule::UnnecessaryLiteralWithinListCall) {
match fixes::fix_unnecessary_literal_within_list_call(checker.locator, expr) {
Ok(fix) => {
diagnostic.amend(fix);
@ -405,7 +405,7 @@ pub fn unnecessary_list_call(checker: &mut Checker, expr: &Expr, func: &Expr, ar
}
let mut diagnostic =
Diagnostic::new(violations::UnnecessaryListCall, Range::from_located(expr));
if checker.patch(&RuleCode::C411) {
if checker.patch(&Rule::UnnecessaryListCall) {
match fixes::fix_unnecessary_list_call(checker.locator, expr) {
Ok(fix) => {
diagnostic.amend(fix);
@ -448,7 +448,7 @@ pub fn unnecessary_call_around_sorted(
violations::UnnecessaryCallAroundSorted(outer.to_string()),
Range::from_located(expr),
);
if checker.patch(&RuleCode::C413) {
if checker.patch(&Rule::UnnecessaryCallAroundSorted) {
match fixes::fix_unnecessary_call_around_sorted(checker.locator, expr) {
Ok(fix) => {
diagnostic.amend(fix);
@ -611,7 +611,7 @@ pub fn unnecessary_comprehension(
violations::UnnecessaryComprehension(id.to_string()),
Range::from_located(expr),
);
if checker.patch(&RuleCode::C416) {
if checker.patch(&Rule::UnnecessaryComprehension) {
match fixes::fix_unnecessary_comprehension(checker.locator, expr) {
Ok(fix) => {
diagnostic.amend(fix);

View File

@ -9,19 +9,19 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::DTZ001, Path::new("DTZ001.py"); "DTZ001")]
#[test_case(RuleCode::DTZ002, Path::new("DTZ002.py"); "DTZ002")]
#[test_case(RuleCode::DTZ003, Path::new("DTZ003.py"); "DTZ003")]
#[test_case(RuleCode::DTZ004, Path::new("DTZ004.py"); "DTZ004")]
#[test_case(RuleCode::DTZ005, Path::new("DTZ005.py"); "DTZ005")]
#[test_case(RuleCode::DTZ006, Path::new("DTZ006.py"); "DTZ006")]
#[test_case(RuleCode::DTZ007, Path::new("DTZ007.py"); "DTZ007")]
#[test_case(RuleCode::DTZ011, Path::new("DTZ011.py"); "DTZ011")]
#[test_case(RuleCode::DTZ012, Path::new("DTZ012.py"); "DTZ012")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::CallDatetimeWithoutTzinfo, Path::new("DTZ001.py"); "DTZ001")]
#[test_case(Rule::CallDatetimeToday, Path::new("DTZ002.py"); "DTZ002")]
#[test_case(Rule::CallDatetimeUtcnow, Path::new("DTZ003.py"); "DTZ003")]
#[test_case(Rule::CallDatetimeUtcfromtimestamp, Path::new("DTZ004.py"); "DTZ004")]
#[test_case(Rule::CallDatetimeNowWithoutTzinfo, Path::new("DTZ005.py"); "DTZ005")]
#[test_case(Rule::CallDatetimeFromtimestamp, Path::new("DTZ006.py"); "DTZ006")]
#[test_case(Rule::CallDatetimeStrptimeWithoutZone, Path::new("DTZ007.py"); "DTZ007")]
#[test_case(Rule::CallDateToday, Path::new("DTZ011.py"); "DTZ011")]
#[test_case(Rule::CallDateFromtimestamp, Path::new("DTZ012.py"); "DTZ012")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_datetimez")

View File

@ -10,11 +10,11 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::T100, Path::new("T100.py"); "T100")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::Debugger, Path::new("T100.py"); "T100")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_debugger")

View File

@ -9,14 +9,18 @@ mod tests {
use anyhow::Result;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test]
fn defaults() -> Result<()> {
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_errmsg/EM.py"),
&settings::Settings::for_rules(vec![RuleCode::EM101, RuleCode::EM102, RuleCode::EM103]),
&settings::Settings::for_rules(vec![
Rule::RawStringInException,
Rule::FStringInException,
Rule::DotFormatInException,
]),
)?;
insta::assert_yaml_snapshot!("defaults", diagnostics);
Ok(())
@ -31,9 +35,9 @@ mod tests {
max_string_length: 20,
},
..settings::Settings::for_rules(vec![
RuleCode::EM101,
RuleCode::EM102,
RuleCode::EM103,
Rule::RawStringInException,
Rule::FStringInException,
Rule::DotFormatInException,
])
},
)?;

View File

@ -2,7 +2,7 @@ use rustpython_ast::{Constant, Expr, ExprKind};
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
/// EM101, EM102, EM103
@ -15,7 +15,7 @@ pub fn string_in_exception(checker: &mut Checker, exc: &Expr) {
value: Constant::Str(string),
..
} => {
if checker.settings.rules.enabled(&RuleCode::EM101) {
if checker.settings.rules.enabled(&Rule::RawStringInException) {
if string.len() > checker.settings.flake8_errmsg.max_string_length {
checker.diagnostics.push(Diagnostic::new(
violations::RawStringInException,
@ -26,7 +26,7 @@ pub fn string_in_exception(checker: &mut Checker, exc: &Expr) {
}
// Check for f-strings
ExprKind::JoinedStr { .. } => {
if checker.settings.rules.enabled(&RuleCode::EM102) {
if checker.settings.rules.enabled(&Rule::FStringInException) {
checker.diagnostics.push(Diagnostic::new(
violations::FStringInException,
Range::from_located(first),
@ -35,7 +35,7 @@ pub fn string_in_exception(checker: &mut Checker, exc: &Expr) {
}
// Check for .format() calls
ExprKind::Call { func, .. } => {
if checker.settings.rules.enabled(&RuleCode::EM103) {
if checker.settings.rules.enabled(&Rule::DotFormatInException) {
if let ExprKind::Attribute { value, attr, .. } = &func.node {
if attr == "format" && matches!(value.node, ExprKind::Constant { .. }) {
checker.diagnostics.push(Diagnostic::new(

View File

@ -9,13 +9,13 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::ISC001, Path::new("ISC.py"); "ISC001")]
#[test_case(RuleCode::ISC002, Path::new("ISC.py"); "ISC002")]
#[test_case(RuleCode::ISC003, Path::new("ISC.py"); "ISC003")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::SingleLineImplicitStringConcatenation, Path::new("ISC.py"); "ISC001")]
#[test_case(Rule::MultiLineImplicitStringConcatenation, Path::new("ISC.py"); "ISC002")]
#[test_case(Rule::ExplicitStringConcatenation, Path::new("ISC.py"); "ISC003")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_implicit_str_concat")

View File

@ -10,14 +10,14 @@ mod tests {
use rustc_hash::FxHashMap;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings::Settings;
#[test]
fn defaults() -> Result<()> {
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_import_conventions/defaults.py"),
&Settings::for_rule(RuleCode::ICN001),
&Settings::for_rule(Rule::ImportAliasIsNotConventional),
)?;
insta::assert_yaml_snapshot!("defaults", diagnostics);
Ok(())
@ -36,7 +36,7 @@ mod tests {
])),
}
.into(),
..Settings::for_rule(RuleCode::ICN001)
..Settings::for_rule(Rule::ImportAliasIsNotConventional)
},
)?;
insta::assert_yaml_snapshot!("custom", diagnostics);
@ -58,7 +58,7 @@ mod tests {
extend_aliases: None,
}
.into(),
..Settings::for_rule(RuleCode::ICN001)
..Settings::for_rule(Rule::ImportAliasIsNotConventional)
},
)?;
insta::assert_yaml_snapshot!("remove_default", diagnostics);
@ -78,7 +78,7 @@ mod tests {
)])),
}
.into(),
..Settings::for_rule(RuleCode::ICN001)
..Settings::for_rule(Rule::ImportAliasIsNotConventional)
},
)?;
insta::assert_yaml_snapshot!("override_default", diagnostics);

View File

@ -9,7 +9,7 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings::Settings;
#[test_case(Path::new("test_pass"); "INP001_0")]
@ -24,7 +24,7 @@ mod tests {
.join(path)
.join("example.py")
.as_path(),
&Settings::for_rule(RuleCode::INP001),
&Settings::for_rule(Rule::ImplicitNamespacePackage),
)?;
insta::assert_yaml_snapshot!(snapshot, diagnostics);
Ok(())

View File

@ -9,14 +9,14 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::PIE790, Path::new("PIE790.py"); "PIE790")]
#[test_case(RuleCode::PIE794, Path::new("PIE794.py"); "PIE794")]
#[test_case(RuleCode::PIE796, Path::new("PIE796.py"); "PIE796")]
#[test_case(RuleCode::PIE807, Path::new("PIE807.py"); "PIE807")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::NoUnnecessaryPass, Path::new("PIE790.py"); "PIE790")]
#[test_case(Rule::DupeClassFieldDefinitions, Path::new("PIE794.py"); "PIE794")]
#[test_case(Rule::PreferUniqueEnums, Path::new("PIE796.py"); "PIE796")]
#[test_case(Rule::PreferListBuiltin, Path::new("PIE807.py"); "PIE807")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_pie")

View File

@ -8,7 +8,7 @@ use crate::ast::types::{Range, RefEquality};
use crate::autofix::helpers::delete_stmt;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
/// PIE790
@ -33,7 +33,7 @@ pub fn no_unnecessary_pass(checker: &mut Checker, body: &[Stmt]) {
violations::NoUnnecessaryPass,
Range::from_located(pass_stmt),
);
if checker.patch(&RuleCode::PIE790) {
if checker.patch(&Rule::NoUnnecessaryPass) {
match delete_stmt(pass_stmt, None, &[], checker.locator, checker.indexer) {
Ok(fix) => {
diagnostic.amend(fix);
@ -86,7 +86,7 @@ pub fn dupe_class_field_definitions<'a, 'b>(
violations::DupeClassFieldDefinitions(target.to_string()),
Range::from_located(stmt),
);
if checker.patch(&RuleCode::PIE794) {
if checker.patch(&Rule::DupeClassFieldDefinitions) {
let deleted: Vec<&Stmt> = checker
.deletions
.iter()
@ -162,7 +162,7 @@ pub fn prefer_list_builtin(checker: &mut Checker, expr: &Expr) {
if elts.is_empty() {
let mut diagnostic =
Diagnostic::new(violations::PreferListBuiltin, Range::from_located(expr));
if checker.patch(&RuleCode::PIE807) {
if checker.patch(&Rule::PreferListBuiltin) {
diagnostic.amend(Fix::replacement(
"list".to_string(),
expr.location,

View File

@ -9,12 +9,12 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::T201, Path::new("T201.py"); "T201")]
#[test_case(RuleCode::T203, Path::new("T203.py"); "T203")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::PrintFound, Path::new("T201.py"); "T201")]
#[test_case(Rule::PPrintFound, Path::new("T203.py"); "T203")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_print")

View File

@ -13,12 +13,12 @@ mod tests {
use super::settings::Settings;
use super::types;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::PT001, Path::new("PT001.py"), Settings::default(), "PT001_default"; "PT001_0")]
#[test_case(Rule::IncorrectFixtureParenthesesStyle, Path::new("PT001.py"), Settings::default(), "PT001_default"; "PT001_0")]
#[test_case(
RuleCode::PT001,
Rule::IncorrectFixtureParenthesesStyle,
Path::new("PT001.py"),
Settings {
fixture_parentheses: false,
@ -27,13 +27,13 @@ mod tests {
"PT001_no_parentheses";
"PT001_1"
)]
#[test_case(RuleCode::PT002, Path::new("PT002.py"), Settings::default(), "PT002"; "PT002")]
#[test_case(RuleCode::PT003, Path::new("PT003.py"), Settings::default(), "PT003"; "PT003")]
#[test_case(RuleCode::PT004, Path::new("PT004.py"), Settings::default(), "PT004"; "PT004")]
#[test_case(RuleCode::PT005, Path::new("PT005.py"), Settings::default(), "PT005"; "PT005")]
#[test_case(RuleCode::PT006, Path::new("PT006.py"), Settings::default(), "PT006_default"; "PT006_0")]
#[test_case(Rule::FixturePositionalArgs, Path::new("PT002.py"), Settings::default(), "PT002"; "PT002")]
#[test_case(Rule::ExtraneousScopeFunction, Path::new("PT003.py"), Settings::default(), "PT003"; "PT003")]
#[test_case(Rule::MissingFixtureNameUnderscore, Path::new("PT004.py"), Settings::default(), "PT004"; "PT004")]
#[test_case(Rule::IncorrectFixtureNameUnderscore, Path::new("PT005.py"), Settings::default(), "PT005"; "PT005")]
#[test_case(Rule::ParametrizeNamesWrongType, Path::new("PT006.py"), Settings::default(), "PT006_default"; "PT006_0")]
#[test_case(
RuleCode::PT006,
Rule::ParametrizeNamesWrongType,
Path::new("PT006.py"),
Settings {
parametrize_names_type: types::ParametrizeNameType::Csv,
@ -43,7 +43,7 @@ mod tests {
"PT006_1"
)]
#[test_case(
RuleCode::PT006,
Rule::ParametrizeNamesWrongType,
Path::new("PT006.py"),
Settings {
parametrize_names_type: types::ParametrizeNameType::List,
@ -53,14 +53,14 @@ mod tests {
"PT006_2"
)]
#[test_case(
RuleCode::PT007,
Rule::ParametrizeValuesWrongType,
Path::new("PT007.py"),
Settings::default(),
"PT007_list_of_tuples";
"PT007_0"
)]
#[test_case(
RuleCode::PT007,
Rule::ParametrizeValuesWrongType,
Path::new("PT007.py"),
Settings {
parametrize_values_type: types::ParametrizeValuesType::Tuple,
@ -70,7 +70,7 @@ mod tests {
"PT007_1"
)]
#[test_case(
RuleCode::PT007,
Rule::ParametrizeValuesWrongType,
Path::new("PT007.py"),
Settings {
parametrize_values_type: types::ParametrizeValuesType::Tuple,
@ -81,7 +81,7 @@ mod tests {
"PT007_2"
)]
#[test_case(
RuleCode::PT007,
Rule::ParametrizeValuesWrongType,
Path::new("PT007.py"),
Settings {
parametrize_values_row_type: types::ParametrizeValuesRowType::List,
@ -91,29 +91,29 @@ mod tests {
"PT007_3"
)]
#[test_case(
RuleCode::PT008,
Rule::PatchWithLambda,
Path::new("PT008.py"),
Settings::default(),
"PT008";
"PT008"
)]
#[test_case(
RuleCode::PT009,
Rule::UnittestAssertion,
Path::new("PT009.py"),
Settings::default(),
"PT009";
"PT009"
)]
#[test_case(RuleCode::PT010, Path::new("PT010.py"), Settings::default(), "PT010"; "PT0010")]
#[test_case(Rule::RaisesWithoutException, Path::new("PT010.py"), Settings::default(), "PT010"; "PT0010")]
#[test_case(
RuleCode::PT011,
Rule::RaisesTooBroad,
Path::new("PT011.py"),
Settings::default(),
"PT011_default";
"PT011_0"
)]
#[test_case(
RuleCode::PT011,
Rule::RaisesTooBroad,
Path::new("PT011.py"),
Settings {
raises_extend_require_match_for: vec!["ZeroDivisionError".to_string()],
@ -123,7 +123,7 @@ mod tests {
"PT011_1"
)]
#[test_case(
RuleCode::PT011,
Rule::RaisesTooBroad,
Path::new("PT011.py"),
Settings {
raises_require_match_for: vec!["ZeroDivisionError".to_string()],
@ -133,84 +133,84 @@ mod tests {
"PT011_2"
)]
#[test_case(
RuleCode::PT012,
Rule::RaisesWithMultipleStatements,
Path::new("PT012.py"),
Settings::default(),
"PT012";
"PT012"
)]
#[test_case(
RuleCode::PT013,
Rule::IncorrectPytestImport,
Path::new("PT013.py"),
Settings::default(),
"PT013";
"PT013"
)]
#[test_case(
RuleCode::PT015,
Rule::AssertAlwaysFalse,
Path::new("PT015.py"),
Settings::default(),
"PT015";
"PT015"
)]
#[test_case(
RuleCode::PT016,
Rule::FailWithoutMessage,
Path::new("PT016.py"),
Settings::default(),
"PT016";
"PT016"
)]
#[test_case(
RuleCode::PT017,
Rule::AssertInExcept,
Path::new("PT017.py"),
Settings::default(),
"PT017";
"PT017"
)]
#[test_case(
RuleCode::PT018,
Rule::CompositeAssertion,
Path::new("PT018.py"),
Settings::default(),
"PT018";
"PT018"
)]
#[test_case(
RuleCode::PT019,
Rule::FixtureParamWithoutValue,
Path::new("PT019.py"),
Settings::default(),
"PT019";
"PT019"
)]
#[test_case(
RuleCode::PT020,
Rule::DeprecatedYieldFixture,
Path::new("PT020.py"),
Settings::default(),
"PT020";
"PT020"
)]
#[test_case(
RuleCode::PT021,
Rule::FixtureFinalizerCallback,
Path::new("PT021.py"),
Settings::default(),
"PT021";
"PT021"
)]
#[test_case(
RuleCode::PT022,
Rule::UselessYieldFixture,
Path::new("PT022.py"),
Settings::default(),
"PT022";
"PT022"
)]
#[test_case(
RuleCode::PT023,
Rule::IncorrectMarkParenthesesStyle,
Path::new("PT023.py"),
Settings::default(),
"PT023_default";
"PT023_0"
)]
#[test_case(
RuleCode::PT023,
Rule::IncorrectMarkParenthesesStyle,
Path::new("PT023.py"),
Settings {
mark_parentheses: false,
@ -220,28 +220,28 @@ mod tests {
"PT023_1"
)]
#[test_case(
RuleCode::PT024,
Rule::UnnecessaryAsyncioMarkOnFixture,
Path::new("PT024.py"),
Settings::default(),
"PT024";
"PT024"
)]
#[test_case(
RuleCode::PT025,
Rule::ErroneousUseFixturesOnFixture,
Path::new("PT025.py"),
Settings::default(),
"PT025";
"PT025"
)]
#[test_case(
RuleCode::PT026,
Rule::UseFixturesWithoutParameters,
Path::new("PT026.py"),
Settings::default(),
"PT026";
"PT026"
)]
fn test_pytest_style(
rule_code: RuleCode,
rule_code: Rule,
path: &Path,
plugin_settings: Settings,
name: &str,

View File

@ -10,7 +10,7 @@ use crate::ast::visitor;
use crate::ast::visitor::Visitor;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
#[derive(Default)]
@ -98,7 +98,10 @@ fn check_fixture_decorator(checker: &mut Checker, func_name: &str, decorator: &E
keywords,
..
} => {
if checker.settings.rules.enabled(&RuleCode::PT001)
if checker
.settings
.rules
.enabled(&Rule::IncorrectFixtureParenthesesStyle)
&& !checker.settings.flake8_pytest_style.fixture_parentheses
&& args.is_empty()
&& keywords.is_empty()
@ -111,14 +114,18 @@ fn check_fixture_decorator(checker: &mut Checker, func_name: &str, decorator: &E
pytest_fixture_parentheses(checker, decorator, fix, "", "()");
}
if checker.settings.rules.enabled(&RuleCode::PT002) && !args.is_empty() {
if checker.settings.rules.enabled(&Rule::FixturePositionalArgs) && !args.is_empty() {
checker.diagnostics.push(Diagnostic::new(
violations::FixturePositionalArgs(func_name.to_string()),
Range::from_located(decorator),
));
}
if checker.settings.rules.enabled(&RuleCode::PT003) {
if checker
.settings
.rules
.enabled(&Rule::ExtraneousScopeFunction)
{
let scope_keyword = keywords
.iter()
.find(|kw| kw.node.arg == Some("scope".to_string()));
@ -134,7 +141,10 @@ fn check_fixture_decorator(checker: &mut Checker, func_name: &str, decorator: &E
}
}
_ => {
if checker.settings.rules.enabled(&RuleCode::PT001)
if checker
.settings
.rules
.enabled(&Rule::IncorrectFixtureParenthesesStyle)
&& checker.settings.flake8_pytest_style.fixture_parentheses
{
let fix = Fix::insertion("()".to_string(), decorator.end_location.unwrap());
@ -152,7 +162,10 @@ fn check_fixture_returns(checker: &mut Checker, func: &Stmt, func_name: &str, bo
visitor.visit_stmt(stmt);
}
if checker.settings.rules.enabled(&RuleCode::PT005)
if checker
.settings
.rules
.enabled(&Rule::IncorrectFixtureNameUnderscore)
&& visitor.has_return_with_value
&& func_name.starts_with('_')
{
@ -160,7 +173,10 @@ fn check_fixture_returns(checker: &mut Checker, func: &Stmt, func_name: &str, bo
violations::IncorrectFixtureNameUnderscore(func_name.to_string()),
Range::from_located(func),
));
} else if checker.settings.rules.enabled(&RuleCode::PT004)
} else if checker
.settings
.rules
.enabled(&Rule::MissingFixtureNameUnderscore)
&& !visitor.has_return_with_value
&& !visitor.has_yield_from
&& !func_name.starts_with('_')
@ -171,7 +187,7 @@ fn check_fixture_returns(checker: &mut Checker, func: &Stmt, func_name: &str, bo
));
}
if checker.settings.rules.enabled(&RuleCode::PT022) {
if checker.settings.rules.enabled(&Rule::UselessYieldFixture) {
if let Some(stmt) = body.last() {
if let StmtKind::Expr { value, .. } = &stmt.node {
if let ExprKind::Yield { .. } = value.node {
@ -246,7 +262,11 @@ fn check_fixture_marks(checker: &mut Checker, decorators: &[Expr]) {
for mark in get_mark_decorators(decorators) {
let name = get_mark_name(mark);
if checker.settings.rules.enabled(&RuleCode::PT024) {
if checker
.settings
.rules
.enabled(&Rule::UnnecessaryAsyncioMarkOnFixture)
{
if name == "asyncio" {
let mut diagnostic = Diagnostic::new(
violations::UnnecessaryAsyncioMarkOnFixture,
@ -261,7 +281,11 @@ fn check_fixture_marks(checker: &mut Checker, decorators: &[Expr]) {
}
}
if checker.settings.rules.enabled(&RuleCode::PT025) {
if checker
.settings
.rules
.enabled(&Rule::ErroneousUseFixturesOnFixture)
{
if name == "usefixtures" {
let mut diagnostic = Diagnostic::new(
violations::ErroneousUseFixturesOnFixture,
@ -288,39 +312,69 @@ pub fn fixture(
) {
let decorator = get_fixture_decorator(checker, decorators);
if let Some(decorator) = decorator {
if checker.settings.rules.enabled(&RuleCode::PT001)
|| checker.settings.rules.enabled(&RuleCode::PT002)
|| checker.settings.rules.enabled(&RuleCode::PT003)
if checker
.settings
.rules
.enabled(&Rule::IncorrectFixtureParenthesesStyle)
|| checker.settings.rules.enabled(&Rule::FixturePositionalArgs)
|| checker
.settings
.rules
.enabled(&Rule::ExtraneousScopeFunction)
{
check_fixture_decorator(checker, func_name, decorator);
}
if checker.settings.rules.enabled(&RuleCode::PT020)
if checker
.settings
.rules
.enabled(&Rule::DeprecatedYieldFixture)
&& checker.settings.flake8_pytest_style.fixture_parentheses
{
check_fixture_decorator_name(checker, decorator);
}
if (checker.settings.rules.enabled(&RuleCode::PT004)
|| checker.settings.rules.enabled(&RuleCode::PT005)
|| checker.settings.rules.enabled(&RuleCode::PT022))
if (checker
.settings
.rules
.enabled(&Rule::MissingFixtureNameUnderscore)
|| checker
.settings
.rules
.enabled(&Rule::IncorrectFixtureNameUnderscore)
|| checker.settings.rules.enabled(&Rule::UselessYieldFixture))
&& !has_abstractmethod_decorator(decorators, checker)
{
check_fixture_returns(checker, func, func_name, body);
}
if checker.settings.rules.enabled(&RuleCode::PT021) {
if checker
.settings
.rules
.enabled(&Rule::FixtureFinalizerCallback)
{
check_fixture_addfinalizer(checker, args, body);
}
if checker.settings.rules.enabled(&RuleCode::PT024)
|| checker.settings.rules.enabled(&RuleCode::PT025)
if checker
.settings
.rules
.enabled(&Rule::UnnecessaryAsyncioMarkOnFixture)
|| checker
.settings
.rules
.enabled(&Rule::ErroneousUseFixturesOnFixture)
{
check_fixture_marks(checker, decorators);
}
}
if checker.settings.rules.enabled(&RuleCode::PT019) && func_name.starts_with("test_") {
if checker
.settings
.rules
.enabled(&Rule::FixtureParamWithoutValue)
&& func_name.starts_with("test_")
{
check_test_function_args(checker, args);
}
}

View File

@ -4,7 +4,7 @@ use super::helpers::{get_mark_decorators, get_mark_name};
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
fn pytest_mark_parentheses(
@ -84,8 +84,14 @@ fn check_useless_usefixtures(checker: &mut Checker, decorator: &Expr) {
}
pub fn marks(checker: &mut Checker, decorators: &[Expr]) {
let enforce_parentheses = checker.settings.rules.enabled(&RuleCode::PT023);
let enforce_useless_usefixtures = checker.settings.rules.enabled(&RuleCode::PT026);
let enforce_parentheses = checker
.settings
.rules
.enabled(&Rule::IncorrectMarkParenthesesStyle);
let enforce_useless_usefixtures = checker
.settings
.rules
.enabled(&Rule::UseFixturesWithoutParameters);
for mark in get_mark_decorators(decorators) {
if enforce_parentheses {

View File

@ -6,7 +6,7 @@ use crate::ast::helpers::create_expr;
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::source_code::Generator;
use crate::violations;
@ -328,12 +328,20 @@ pub fn parametrize(checker: &mut Checker, decorators: &[Expr]) {
let decorator = get_parametrize_decorator(checker, decorators);
if let Some(decorator) = decorator {
if let ExprKind::Call { args, .. } = &decorator.node {
if checker.settings.rules.enabled(&RuleCode::PT006) {
if checker
.settings
.rules
.enabled(&Rule::ParametrizeNamesWrongType)
{
if let Some(arg) = args.get(0) {
check_names(checker, arg);
}
}
if checker.settings.rules.enabled(&RuleCode::PT007) {
if checker
.settings
.rules
.enabled(&Rule::ParametrizeValuesWrongType)
{
if let Some(arg) = args.get(1) {
check_values(checker, arg);
}

View File

@ -4,7 +4,7 @@ use super::helpers::is_empty_or_null_string;
use crate::ast::helpers::{format_call_path, to_call_path};
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
fn is_pytest_raises(checker: &Checker, func: &Expr) -> bool {
@ -25,7 +25,11 @@ fn is_non_trivial_with_body(body: &[Stmt]) -> bool {
pub fn raises_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords: &[Keyword]) {
if is_pytest_raises(checker, func) {
if checker.settings.rules.enabled(&RuleCode::PT010) {
if checker
.settings
.rules
.enabled(&Rule::RaisesWithoutException)
{
if args.is_empty() && keywords.is_empty() {
checker.diagnostics.push(Diagnostic::new(
violations::RaisesWithoutException,
@ -34,7 +38,7 @@ pub fn raises_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords:
}
}
if checker.settings.rules.enabled(&RuleCode::PT011) {
if checker.settings.rules.enabled(&Rule::RaisesTooBroad) {
let match_keyword = keywords
.iter()
.find(|kw| kw.node.arg == Some("match".to_string()));

View File

@ -11,7 +11,7 @@ mod tests {
use super::settings::Quote;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings::Settings;
#[test_case(Path::new("doubles.py"))]
@ -33,10 +33,10 @@ mod tests {
avoid_escape: true,
},
..Settings::for_rules(vec![
RuleCode::Q000,
RuleCode::Q001,
RuleCode::Q002,
RuleCode::Q003,
Rule::BadQuotesInlineString,
Rule::BadQuotesMultilineString,
Rule::BadQuotesDocstring,
Rule::AvoidQuoteEscape,
])
},
)?;
@ -63,10 +63,10 @@ mod tests {
avoid_escape: true,
},
..Settings::for_rules(vec![
RuleCode::Q000,
RuleCode::Q001,
RuleCode::Q002,
RuleCode::Q003,
Rule::BadQuotesInlineString,
Rule::BadQuotesMultilineString,
Rule::BadQuotesDocstring,
Rule::AvoidQuoteEscape,
])
},
)?;
@ -98,10 +98,10 @@ mod tests {
avoid_escape: true,
},
..Settings::for_rules(vec![
RuleCode::Q000,
RuleCode::Q001,
RuleCode::Q002,
RuleCode::Q003,
Rule::BadQuotesInlineString,
Rule::BadQuotesMultilineString,
Rule::BadQuotesDocstring,
Rule::AvoidQuoteEscape,
])
},
)?;
@ -133,10 +133,10 @@ mod tests {
avoid_escape: true,
},
..Settings::for_rules(vec![
RuleCode::Q000,
RuleCode::Q001,
RuleCode::Q002,
RuleCode::Q003,
Rule::BadQuotesInlineString,
Rule::BadQuotesMultilineString,
Rule::BadQuotesDocstring,
Rule::AvoidQuoteEscape,
])
},
)?;

View File

@ -3,7 +3,7 @@ use rustpython_ast::Location;
use super::settings::Quote;
use crate::ast::types::Range;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::settings::{flags, Settings};
use crate::source_code::Locator;
use crate::violations;
@ -80,7 +80,8 @@ pub fn quotes(
violations::BadQuotesDocstring(quotes_settings.docstring_quotes.clone()),
Range::new(start, end),
);
if matches!(autofix, flags::Autofix::Enabled) && settings.rules.should_fix(&RuleCode::Q002)
if matches!(autofix, flags::Autofix::Enabled)
&& settings.rules.should_fix(&Rule::BadQuotesDocstring)
{
let quote_count = if is_multiline { 3 } else { 1 };
let string_contents = &raw_text[quote_count..raw_text.len() - quote_count];
@ -110,7 +111,8 @@ pub fn quotes(
Range::new(start, end),
);
if matches!(autofix, flags::Autofix::Enabled) && settings.rules.should_fix(&RuleCode::Q001)
if matches!(autofix, flags::Autofix::Enabled)
&& settings.rules.should_fix(&Rule::BadQuotesMultilineString)
{
let string_contents = &raw_text[3..raw_text.len() - 3];
let quote = good_multiline(&quotes_settings.multiline_quotes);
@ -137,7 +139,7 @@ pub fn quotes(
let mut diagnostic =
Diagnostic::new(violations::AvoidQuoteEscape, Range::new(start, end));
if matches!(autofix, flags::Autofix::Enabled)
&& settings.rules.should_fix(&RuleCode::Q003)
&& settings.rules.should_fix(&Rule::AvoidQuoteEscape)
{
let quote = bad_single(&quotes_settings.inline_quotes);
@ -193,7 +195,7 @@ pub fn quotes(
Range::new(start, end),
);
if matches!(autofix, flags::Autofix::Enabled)
&& settings.rules.should_fix(&RuleCode::Q000)
&& settings.rules.should_fix(&Rule::BadQuotesInlineString)
{
let quote = good_single(&quotes_settings.inline_quotes);
let mut fixed_contents =

View File

@ -11,18 +11,18 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings::Settings;
#[test_case(RuleCode::RET501, Path::new("RET501.py"); "RET501")]
#[test_case(RuleCode::RET502, Path::new("RET502.py"); "RET502")]
#[test_case(RuleCode::RET503, Path::new("RET503.py"); "RET503")]
#[test_case(RuleCode::RET504, Path::new("RET504.py"); "RET504")]
#[test_case(RuleCode::RET505, Path::new("RET505.py"); "RET505")]
#[test_case(RuleCode::RET506, Path::new("RET506.py"); "RET506")]
#[test_case(RuleCode::RET507, Path::new("RET507.py"); "RET507")]
#[test_case(RuleCode::RET508, Path::new("RET508.py"); "RET508")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::UnnecessaryReturnNone, Path::new("RET501.py"); "RET501")]
#[test_case(Rule::ImplicitReturnValue, Path::new("RET502.py"); "RET502")]
#[test_case(Rule::ImplicitReturn, Path::new("RET503.py"); "RET503")]
#[test_case(Rule::UnnecessaryAssign, Path::new("RET504.py"); "RET504")]
#[test_case(Rule::SuperfluousElseReturn, Path::new("RET505.py"); "RET505")]
#[test_case(Rule::SuperfluousElseRaise, Path::new("RET506.py"); "RET506")]
#[test_case(Rule::SuperfluousElseContinue, Path::new("RET507.py"); "RET507")]
#[test_case(Rule::SuperfluousElseBreak, Path::new("RET508.py"); "RET508")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_return")

View File

@ -9,7 +9,7 @@ use crate::ast::visitor::Visitor;
use crate::ast::whitespace::indentation;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
use crate::violations::Branch;
@ -30,7 +30,7 @@ fn unnecessary_return_none(checker: &mut Checker, stack: &Stack) {
}
let mut diagnostic =
Diagnostic::new(violations::UnnecessaryReturnNone, Range::from_located(stmt));
if checker.patch(&RuleCode::RET501) {
if checker.patch(&Rule::UnnecessaryReturnNone) {
diagnostic.amend(Fix::replacement(
"return".to_string(),
stmt.location,
@ -49,7 +49,7 @@ fn implicit_return_value(checker: &mut Checker, stack: &Stack) {
}
let mut diagnostic =
Diagnostic::new(violations::ImplicitReturnValue, Range::from_located(stmt));
if checker.patch(&RuleCode::RET502) {
if checker.patch(&Rule::ImplicitReturnValue) {
diagnostic.amend(Fix::replacement(
"return None".to_string(),
stmt.location,
@ -106,7 +106,7 @@ fn implicit_return(checker: &mut Checker, last_stmt: &Stmt) {
_ => {
let mut diagnostic =
Diagnostic::new(violations::ImplicitReturn, Range::from_located(last_stmt));
if checker.patch(&RuleCode::RET503) {
if checker.patch(&Rule::ImplicitReturn) {
if let Some(indent) = indentation(checker.locator, last_stmt) {
let mut content = String::new();
content.push_str(&indent);
@ -228,7 +228,7 @@ fn superfluous_else_node(checker: &mut Checker, stmt: &Stmt, branch: Branch) ->
};
for child in body {
if matches!(child.node, StmtKind::Return { .. }) {
if checker.settings.rules.enabled(&RuleCode::RET505) {
if checker.settings.rules.enabled(&Rule::SuperfluousElseReturn) {
checker.diagnostics.push(Diagnostic::new(
violations::SuperfluousElseReturn(branch),
elif_else_range(stmt, checker.locator)
@ -238,7 +238,7 @@ fn superfluous_else_node(checker: &mut Checker, stmt: &Stmt, branch: Branch) ->
return true;
}
if matches!(child.node, StmtKind::Break) {
if checker.settings.rules.enabled(&RuleCode::RET508) {
if checker.settings.rules.enabled(&Rule::SuperfluousElseBreak) {
checker.diagnostics.push(Diagnostic::new(
violations::SuperfluousElseBreak(branch),
elif_else_range(stmt, checker.locator)
@ -248,7 +248,7 @@ fn superfluous_else_node(checker: &mut Checker, stmt: &Stmt, branch: Branch) ->
return true;
}
if matches!(child.node, StmtKind::Raise { .. }) {
if checker.settings.rules.enabled(&RuleCode::RET506) {
if checker.settings.rules.enabled(&Rule::SuperfluousElseRaise) {
checker.diagnostics.push(Diagnostic::new(
violations::SuperfluousElseRaise(branch),
elif_else_range(stmt, checker.locator)
@ -258,7 +258,11 @@ fn superfluous_else_node(checker: &mut Checker, stmt: &Stmt, branch: Branch) ->
return true;
}
if matches!(child.node, StmtKind::Continue) {
if checker.settings.rules.enabled(&RuleCode::RET507) {
if checker
.settings
.rules
.enabled(&Rule::SuperfluousElseContinue)
{
checker.diagnostics.push(Diagnostic::new(
violations::SuperfluousElseContinue(branch),
elif_else_range(stmt, checker.locator)
@ -321,10 +325,13 @@ pub fn function(checker: &mut Checker, body: &[Stmt]) {
visitor.stack
};
if checker.settings.rules.enabled(&RuleCode::RET505)
|| checker.settings.rules.enabled(&RuleCode::RET506)
|| checker.settings.rules.enabled(&RuleCode::RET507)
|| checker.settings.rules.enabled(&RuleCode::RET508)
if checker.settings.rules.enabled(&Rule::SuperfluousElseReturn)
|| checker.settings.rules.enabled(&Rule::SuperfluousElseRaise)
|| checker
.settings
.rules
.enabled(&Rule::SuperfluousElseContinue)
|| checker.settings.rules.enabled(&Rule::SuperfluousElseBreak)
{
if superfluous_elif(checker, &stack) {
return;
@ -340,20 +347,20 @@ pub fn function(checker: &mut Checker, body: &[Stmt]) {
}
if !result_exists(&stack.returns) {
if checker.settings.rules.enabled(&RuleCode::RET501) {
if checker.settings.rules.enabled(&Rule::UnnecessaryReturnNone) {
unnecessary_return_none(checker, &stack);
}
return;
}
if checker.settings.rules.enabled(&RuleCode::RET502) {
if checker.settings.rules.enabled(&Rule::ImplicitReturnValue) {
implicit_return_value(checker, &stack);
}
if checker.settings.rules.enabled(&RuleCode::RET503) {
if checker.settings.rules.enabled(&Rule::ImplicitReturn) {
implicit_return(checker, last_stmt);
}
if checker.settings.rules.enabled(&RuleCode::RET504) {
if checker.settings.rules.enabled(&Rule::UnnecessaryAssign) {
for (_, expr) in &stack.returns {
if let Some(expr) = expr {
unnecessary_assign(checker, &stack, expr);

View File

@ -9,35 +9,35 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::SIM101, Path::new("SIM101.py"); "SIM101")]
#[test_case(RuleCode::SIM102, Path::new("SIM102.py"); "SIM102")]
#[test_case(RuleCode::SIM103, Path::new("SIM103.py"); "SIM103")]
#[test_case(RuleCode::SIM105, Path::new("SIM105.py"); "SIM105")]
#[test_case(RuleCode::SIM107, Path::new("SIM107.py"); "SIM107")]
#[test_case(RuleCode::SIM108, Path::new("SIM108.py"); "SIM108")]
#[test_case(RuleCode::SIM109, Path::new("SIM109.py"); "SIM109")]
#[test_case(RuleCode::SIM110, Path::new("SIM110.py"); "SIM110")]
#[test_case(RuleCode::SIM111, Path::new("SIM111.py"); "SIM111")]
#[test_case(RuleCode::SIM112, Path::new("SIM112.py"); "SIM112")]
#[test_case(RuleCode::SIM115, Path::new("SIM115.py"); "SIM115")]
#[test_case(RuleCode::SIM117, Path::new("SIM117.py"); "SIM117")]
#[test_case(RuleCode::SIM118, Path::new("SIM118.py"); "SIM118")]
#[test_case(RuleCode::SIM201, Path::new("SIM201.py"); "SIM201")]
#[test_case(RuleCode::SIM202, Path::new("SIM202.py"); "SIM202")]
#[test_case(RuleCode::SIM208, Path::new("SIM208.py"); "SIM208")]
#[test_case(RuleCode::SIM210, Path::new("SIM210.py"); "SIM210")]
#[test_case(RuleCode::SIM211, Path::new("SIM211.py"); "SIM211")]
#[test_case(RuleCode::SIM212, Path::new("SIM212.py"); "SIM212")]
#[test_case(RuleCode::SIM220, Path::new("SIM220.py"); "SIM220")]
#[test_case(RuleCode::SIM221, Path::new("SIM221.py"); "SIM221")]
#[test_case(RuleCode::SIM222, Path::new("SIM222.py"); "SIM222")]
#[test_case(RuleCode::SIM223, Path::new("SIM223.py"); "SIM223")]
#[test_case(RuleCode::SIM300, Path::new("SIM300.py"); "SIM300")]
#[test_case(RuleCode::SIM401, Path::new("SIM401.py"); "SIM401")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::DuplicateIsinstanceCall, Path::new("SIM101.py"); "SIM101")]
#[test_case(Rule::NestedIfStatements, Path::new("SIM102.py"); "SIM102")]
#[test_case(Rule::ReturnBoolConditionDirectly, Path::new("SIM103.py"); "SIM103")]
#[test_case(Rule::UseContextlibSuppress, Path::new("SIM105.py"); "SIM105")]
#[test_case(Rule::ReturnInTryExceptFinally, Path::new("SIM107.py"); "SIM107")]
#[test_case(Rule::UseTernaryOperator, Path::new("SIM108.py"); "SIM108")]
#[test_case(Rule::CompareWithTuple, Path::new("SIM109.py"); "SIM109")]
#[test_case(Rule::ConvertLoopToAny, Path::new("SIM110.py"); "SIM110")]
#[test_case(Rule::ConvertLoopToAll, Path::new("SIM111.py"); "SIM111")]
#[test_case(Rule::UseCapitalEnvironmentVariables, Path::new("SIM112.py"); "SIM112")]
#[test_case(Rule::OpenFileWithContextHandler, Path::new("SIM115.py"); "SIM115")]
#[test_case(Rule::MultipleWithStatements, Path::new("SIM117.py"); "SIM117")]
#[test_case(Rule::KeyInDict, Path::new("SIM118.py"); "SIM118")]
#[test_case(Rule::NegateEqualOp, Path::new("SIM201.py"); "SIM201")]
#[test_case(Rule::NegateNotEqualOp, Path::new("SIM202.py"); "SIM202")]
#[test_case(Rule::DoubleNegation, Path::new("SIM208.py"); "SIM208")]
#[test_case(Rule::IfExprWithTrueFalse, Path::new("SIM210.py"); "SIM210")]
#[test_case(Rule::IfExprWithFalseTrue, Path::new("SIM211.py"); "SIM211")]
#[test_case(Rule::IfExprWithTwistedArms, Path::new("SIM212.py"); "SIM212")]
#[test_case(Rule::AAndNotA, Path::new("SIM220.py"); "SIM220")]
#[test_case(Rule::AOrNotA, Path::new("SIM221.py"); "SIM221")]
#[test_case(Rule::OrTrue, Path::new("SIM222.py"); "SIM222")]
#[test_case(Rule::AndFalse, Path::new("SIM223.py"); "SIM223")]
#[test_case(Rule::YodaConditions, Path::new("SIM300.py"); "SIM300")]
#[test_case(Rule::DictGetWithDefault, Path::new("SIM401.py"); "SIM401")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_simplify")

View File

@ -9,7 +9,7 @@ use crate::ast::helpers::{contains_effect, create_expr, unparse_expr};
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
/// Return `true` if two `Expr` instances are equivalent names.
@ -66,7 +66,7 @@ pub fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
violations::DuplicateIsinstanceCall(arg_name.to_string()),
Range::from_located(expr),
);
if checker.patch(&RuleCode::SIM101) {
if checker.patch(&Rule::DuplicateIsinstanceCall) {
// Grab the types used in each duplicate `isinstance` call.
let types: Vec<&Expr> = indices
.iter()
@ -179,7 +179,7 @@ pub fn compare_with_tuple(checker: &mut Checker, expr: &Expr) {
),
Range::from_located(expr),
);
if checker.patch(&RuleCode::SIM109) {
if checker.patch(&Rule::CompareWithTuple) {
// Create a `x in (a, b)` compare expr.
let in_expr = create_expr(ExprKind::Compare {
left: Box::new(create_expr(ExprKind::Name {
@ -241,7 +241,7 @@ pub fn a_and_not_a(checker: &mut Checker, expr: &Expr) {
violations::AAndNotA(id.to_string()),
Range::from_located(expr),
);
if checker.patch(&RuleCode::SIM220) {
if checker.patch(&Rule::AAndNotA) {
diagnostic.amend(Fix::replacement(
"False".to_string(),
expr.location,
@ -293,7 +293,7 @@ pub fn a_or_not_a(checker: &mut Checker, expr: &Expr) {
violations::AOrNotA(id.to_string()),
Range::from_located(expr),
);
if checker.patch(&RuleCode::SIM220) {
if checker.patch(&Rule::AAndNotA) {
diagnostic.amend(Fix::replacement(
"True".to_string(),
expr.location,
@ -321,7 +321,7 @@ pub fn or_true(checker: &mut Checker, expr: &Expr) {
} = &value.node
{
let mut diagnostic = Diagnostic::new(violations::OrTrue, Range::from_located(value));
if checker.patch(&RuleCode::SIM223) {
if checker.patch(&Rule::AndFalse) {
diagnostic.amend(Fix::replacement(
"True".to_string(),
expr.location,
@ -348,7 +348,7 @@ pub fn and_false(checker: &mut Checker, expr: &Expr) {
} = &value.node
{
let mut diagnostic = Diagnostic::new(violations::AndFalse, Range::from_located(value));
if checker.patch(&RuleCode::SIM223) {
if checker.patch(&Rule::AndFalse) {
diagnostic.amend(Fix::replacement(
"False".to_string(),
expr.location,

View File

@ -4,7 +4,7 @@ use crate::ast::helpers::{create_expr, unparse_expr};
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
/// SIM112
@ -40,7 +40,7 @@ pub fn use_capital_environment_variables(checker: &mut Checker, expr: &Expr) {
violations::UseCapitalEnvironmentVariables(capital_env_var.clone(), env_var.clone()),
Range::from_located(arg),
);
if checker.patch(&RuleCode::SIM112) {
if checker.patch(&Rule::UseCapitalEnvironmentVariables) {
let new_env_var = create_expr(ExprKind::Constant {
value: capital_env_var.into(),
kind: kind.clone(),
@ -79,7 +79,7 @@ fn check_os_environ_subscript(checker: &mut Checker, expr: &Expr) {
violations::UseCapitalEnvironmentVariables(capital_env_var.clone(), env_var.clone()),
Range::from_located(slice),
);
if checker.patch(&RuleCode::SIM112) {
if checker.patch(&Rule::UseCapitalEnvironmentVariables) {
let new_env_var = create_expr(ExprKind::Constant {
value: capital_env_var.into(),
kind: kind.clone(),

View File

@ -6,7 +6,7 @@ use crate::ast::helpers::{create_expr, create_stmt};
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::source_code::{Generator, Stylist};
use crate::violations;
@ -178,7 +178,7 @@ pub fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt, sibling:
Some(sibling) => return_values_for_siblings(stmt, sibling),
} {
if loop_info.return_value && !loop_info.next_return_value {
if checker.settings.rules.enabled(&RuleCode::SIM110) {
if checker.settings.rules.enabled(&Rule::ConvertLoopToAny) {
let contents = return_stmt(
"any",
loop_info.test,
@ -196,7 +196,7 @@ pub fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt, sibling:
violations::ConvertLoopToAny(contents.clone()),
Range::from_located(stmt),
);
if checker.patch(&RuleCode::SIM110) {
if checker.patch(&Rule::ConvertLoopToAny) {
diagnostic.amend(Fix::replacement(
contents,
stmt.location,
@ -211,7 +211,7 @@ pub fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt, sibling:
}
if !loop_info.return_value && loop_info.next_return_value {
if checker.settings.rules.enabled(&RuleCode::SIM111) {
if checker.settings.rules.enabled(&Rule::ConvertLoopToAll) {
// Invert the condition.
let test = {
if let ExprKind::UnaryOp {
@ -244,7 +244,7 @@ pub fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt, sibling:
violations::ConvertLoopToAll(contents.clone()),
Range::from_located(stmt),
);
if checker.patch(&RuleCode::SIM111) {
if checker.patch(&Rule::ConvertLoopToAll) {
diagnostic.amend(Fix::replacement(
contents,
stmt.location,

View File

@ -9,7 +9,7 @@ use crate::ast::helpers::{
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::rules::flake8_simplify::rules::fix_if;
use crate::violations;
@ -67,7 +67,7 @@ pub fn nested_if_statements(checker: &mut Checker, stmt: &Stmt) {
}
let mut diagnostic = Diagnostic::new(violations::NestedIfStatements, Range::from_located(stmt));
if checker.patch(&RuleCode::SIM102) {
if checker.patch(&Rule::NestedIfStatements) {
// The fixer preserves comments in the nested body, but removes comments between
// the outer and inner if statements.
let nested_if = &body[0];
@ -118,7 +118,7 @@ pub fn return_bool_condition_directly(checker: &mut Checker, stmt: &Stmt) {
violations::ReturnBoolConditionDirectly(condition),
Range::from_located(stmt),
);
if checker.patch(&RuleCode::SIM103)
if checker.patch(&Rule::ReturnBoolConditionDirectly)
&& !(has_comments_in(Range::from_located(stmt), checker.locator)
|| has_comments_in(Range::from_located(&orelse[0]), checker.locator))
{
@ -232,7 +232,7 @@ pub fn use_ternary_operator(checker: &mut Checker, stmt: &Stmt, parent: Option<&
violations::UseTernaryOperator(contents.clone()),
Range::from_located(stmt),
);
if checker.patch(&RuleCode::SIM108) {
if checker.patch(&Rule::UseTernaryOperator) {
diagnostic.amend(Fix::replacement(
contents,
stmt.location,
@ -335,7 +335,7 @@ pub fn use_dict_get_with_default(
violations::DictGetWithDefault(contents.clone()),
Range::from_located(stmt),
);
if checker.patch(&RuleCode::SIM401) {
if checker.patch(&Rule::DictGetWithDefault) {
diagnostic.amend(Fix::replacement(
contents,
stmt.location,

View File

@ -5,7 +5,7 @@ use super::fix_with;
use crate::ast::helpers::{first_colon_range, has_comments_in};
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
fn find_last_with(body: &[Stmt]) -> Option<(&Vec<Withitem>, &Vec<Stmt>)> {
@ -49,7 +49,7 @@ pub fn multiple_with_statements(
|colon| Range::new(with_stmt.location, colon.end_location),
),
);
if checker.patch(&RuleCode::SIM117) {
if checker.patch(&Rule::MultipleWithStatements) {
let nested_with = &with_body[0];
if !has_comments_in(
Range::new(with_stmt.location, nested_with.location),

View File

@ -113,7 +113,7 @@ mod tests {
use super::ApiBan;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings::Settings;
#[test]
@ -139,7 +139,7 @@ mod tests {
.into(),
..Default::default()
},
..Settings::for_rules(vec![RuleCode::TID251])
..Settings::for_rules(vec![Rule::BannedApi])
},
)?;
insta::assert_yaml_snapshot!(diagnostics);

View File

@ -64,7 +64,7 @@ mod tests {
use super::Strictness;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings::Settings;
#[test]
@ -76,7 +76,7 @@ mod tests {
ban_relative_imports: Strictness::Parents,
..Default::default()
},
..Settings::for_rules(vec![RuleCode::TID252])
..Settings::for_rules(vec![Rule::RelativeImports])
},
)?;
insta::assert_yaml_snapshot!(diagnostics);
@ -92,7 +92,7 @@ mod tests {
ban_relative_imports: Strictness::All,
..Default::default()
},
..Settings::for_rules(vec![RuleCode::TID252])
..Settings::for_rules(vec![Rule::RelativeImports])
},
)?;
insta::assert_yaml_snapshot!(diagnostics);

View File

@ -12,15 +12,15 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::ARG001, Path::new("ARG.py"); "ARG001")]
#[test_case(RuleCode::ARG002, Path::new("ARG.py"); "ARG002")]
#[test_case(RuleCode::ARG003, Path::new("ARG.py"); "ARG003")]
#[test_case(RuleCode::ARG004, Path::new("ARG.py"); "ARG004")]
#[test_case(RuleCode::ARG005, Path::new("ARG.py"); "ARG005")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::UnusedFunctionArgument, Path::new("ARG.py"); "ARG001")]
#[test_case(Rule::UnusedMethodArgument, Path::new("ARG.py"); "ARG002")]
#[test_case(Rule::UnusedClassMethodArgument, Path::new("ARG.py"); "ARG003")]
#[test_case(Rule::UnusedStaticMethodArgument, Path::new("ARG.py"); "ARG004")]
#[test_case(Rule::UnusedLambdaArgument, Path::new("ARG.py"); "ARG005")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/flake8_unused_arguments")
@ -41,11 +41,11 @@ mod tests {
ignore_variadic_names: true,
},
..settings::Settings::for_rules(vec![
RuleCode::ARG001,
RuleCode::ARG002,
RuleCode::ARG003,
RuleCode::ARG004,
RuleCode::ARG005,
Rule::UnusedFunctionArgument,
Rule::UnusedMethodArgument,
Rule::UnusedClassMethodArgument,
Rule::UnusedStaticMethodArgument,
Rule::UnusedLambdaArgument,
])
},
)?;
@ -62,11 +62,11 @@ mod tests {
ignore_variadic_names: false,
},
..settings::Settings::for_rules(vec![
RuleCode::ARG001,
RuleCode::ARG002,
RuleCode::ARG003,
RuleCode::ARG004,
RuleCode::ARG005,
Rule::UnusedFunctionArgument,
Rule::UnusedMethodArgument,
Rule::UnusedClassMethodArgument,
Rule::UnusedStaticMethodArgument,
Rule::UnusedLambdaArgument,
])
},
)?;

View File

@ -1,4 +1,4 @@
use crate::registry::{DiagnosticKind, RuleCode};
use crate::registry::{DiagnosticKind, Rule};
use crate::violations;
/// An AST node that can contain arguments.
@ -21,13 +21,13 @@ impl Argumentable {
}
}
pub fn rule_code(&self) -> &RuleCode {
pub fn rule_code(&self) -> &Rule {
match self {
Argumentable::Function => &RuleCode::ARG001,
Argumentable::Method => &RuleCode::ARG002,
Argumentable::ClassMethod => &RuleCode::ARG003,
Argumentable::StaticMethod => &RuleCode::ARG004,
Argumentable::Lambda => &RuleCode::ARG005,
Argumentable::Function => &Rule::UnusedFunctionArgument,
Argumentable::Method => &Rule::UnusedMethodArgument,
Argumentable::ClassMethod => &Rule::UnusedClassMethodArgument,
Argumentable::StaticMethod => &Rule::UnusedStaticMethodArgument,
Argumentable::Lambda => &Rule::UnusedLambdaArgument,
}
}
}

View File

@ -684,7 +684,7 @@ mod tests {
use super::categorize::ImportType;
use super::settings::RelatveImportsOrder;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings::Settings;
#[test_case(Path::new("add_newline_before_comments.py"))]
@ -737,7 +737,7 @@ mod tests {
.as_path(),
&Settings {
src: vec![Path::new("resources/test/fixtures/isort").to_path_buf()],
..Settings::for_rule(RuleCode::I001)
..Settings::for_rule(Rule::UnsortedImports)
},
)?;
insta::assert_yaml_snapshot!(snapshot, diagnostics);
@ -757,7 +757,7 @@ mod tests {
..super::settings::Settings::default()
},
src: vec![Path::new("resources/test/fixtures/isort").to_path_buf()],
..Settings::for_rule(RuleCode::I001)
..Settings::for_rule(Rule::UnsortedImports)
},
)?;
insta::assert_yaml_snapshot!(snapshot, diagnostics);
@ -778,7 +778,7 @@ mod tests {
..super::settings::Settings::default()
},
src: vec![Path::new("resources/test/fixtures/isort").to_path_buf()],
..Settings::for_rule(RuleCode::I001)
..Settings::for_rule(Rule::UnsortedImports)
},
)?;
insta::assert_yaml_snapshot!(snapshot, diagnostics);
@ -798,7 +798,7 @@ mod tests {
..super::settings::Settings::default()
},
src: vec![Path::new("resources/test/fixtures/isort").to_path_buf()],
..Settings::for_rule(RuleCode::I001)
..Settings::for_rule(Rule::UnsortedImports)
},
)?;
insta::assert_yaml_snapshot!(snapshot, diagnostics);
@ -821,7 +821,7 @@ mod tests {
..super::settings::Settings::default()
},
src: vec![Path::new("resources/test/fixtures/isort").to_path_buf()],
..Settings::for_rule(RuleCode::I001)
..Settings::for_rule(Rule::UnsortedImports)
},
)?;
insta::assert_yaml_snapshot!(snapshot, diagnostics);
@ -841,7 +841,7 @@ mod tests {
..super::settings::Settings::default()
},
src: vec![Path::new("resources/test/fixtures/isort").to_path_buf()],
..Settings::for_rule(RuleCode::I001)
..Settings::for_rule(Rule::UnsortedImports)
},
)?;
diagnostics.sort_by_key(|diagnostic| diagnostic.location);
@ -871,7 +871,7 @@ mod tests {
..super::settings::Settings::default()
},
src: vec![Path::new("resources/test/fixtures/isort").to_path_buf()],
..Settings::for_rule(RuleCode::I001)
..Settings::for_rule(Rule::UnsortedImports)
},
)?;
diagnostics.sort_by_key(|diagnostic| diagnostic.location);
@ -903,7 +903,7 @@ mod tests {
..super::settings::Settings::default()
},
src: vec![Path::new("resources/test/fixtures/isort").to_path_buf()],
..Settings::for_rule(RuleCode::I001)
..Settings::for_rule(Rule::UnsortedImports)
},
)?;
diagnostics.sort_by_key(|diagnostic| diagnostic.location);
@ -933,7 +933,7 @@ mod tests {
..super::settings::Settings::default()
},
src: vec![Path::new("resources/test/fixtures/isort").to_path_buf()],
..Settings::for_rule(RuleCode::I001)
..Settings::for_rule(Rule::UnsortedImports)
},
)?;
diagnostics.sort_by_key(|diagnostic| diagnostic.location);
@ -954,7 +954,7 @@ mod tests {
..super::settings::Settings::default()
},
src: vec![Path::new("resources/test/fixtures/isort").to_path_buf()],
..Settings::for_rule(RuleCode::I001)
..Settings::for_rule(Rule::UnsortedImports)
},
)?;
diagnostics.sort_by_key(|diagnostic| diagnostic.location);
@ -979,7 +979,7 @@ mod tests {
]),
..super::settings::Settings::default()
},
..Settings::for_rule(RuleCode::I002)
..Settings::for_rule(Rule::MissingRequiredImport)
},
)?;
insta::assert_yaml_snapshot!(snapshot, diagnostics);
@ -1004,7 +1004,7 @@ mod tests {
]),
..super::settings::Settings::default()
},
..Settings::for_rule(RuleCode::I002)
..Settings::for_rule(Rule::MissingRequiredImport)
},
)?;
insta::assert_yaml_snapshot!(snapshot, diagnostics);
@ -1028,7 +1028,7 @@ mod tests {
.to_string()]),
..super::settings::Settings::default()
},
..Settings::for_rule(RuleCode::I002)
..Settings::for_rule(Rule::MissingRequiredImport)
},
)?;
insta::assert_yaml_snapshot!(snapshot, diagnostics);
@ -1050,7 +1050,7 @@ mod tests {
required_imports: BTreeSet::from(["import os".to_string()]),
..super::settings::Settings::default()
},
..Settings::for_rule(RuleCode::I002)
..Settings::for_rule(Rule::MissingRequiredImport)
},
)?;
insta::assert_yaml_snapshot!(snapshot, diagnostics);
@ -1070,7 +1070,7 @@ mod tests {
..super::settings::Settings::default()
},
src: vec![Path::new("resources/test/fixtures/isort").to_path_buf()],
..Settings::for_rule(RuleCode::I001)
..Settings::for_rule(Rule::UnsortedImports)
},
)?;
insta::assert_yaml_snapshot!(snapshot, diagnostics);
@ -1096,7 +1096,7 @@ mod tests {
..super::settings::Settings::default()
},
src: vec![Path::new("resources/test/fixtures/isort").to_path_buf()],
..Settings::for_rule(RuleCode::I001)
..Settings::for_rule(Rule::UnsortedImports)
},
)?;
diagnostics.sort_by_key(|diagnostic| diagnostic.location);

View File

@ -8,7 +8,7 @@ use super::super::track::Block;
use crate::ast::helpers::is_docstring_stmt;
use crate::ast::types::Range;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::settings::{flags, Settings};
use crate::source_code::Locator;
use crate::violations;
@ -125,7 +125,9 @@ fn add_required_import(
violations::MissingRequiredImport(required_import.clone()),
Range::new(Location::default(), Location::default()),
);
if matches!(autofix, flags::Autofix::Enabled) && settings.rules.should_fix(&RuleCode::I002) {
if matches!(autofix, flags::Autofix::Enabled)
&& settings.rules.should_fix(&Rule::MissingRequiredImport)
{
// Determine the location at which the import should be inserted.
let splice = helpers::find_splice_location(python_ast, locator);

View File

@ -10,7 +10,7 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings::Settings;
#[test_case(0)]
@ -22,7 +22,7 @@ mod tests {
Path::new("./resources/test/fixtures/mccabe/C901.py"),
&Settings {
mccabe: super::settings::Settings { max_complexity },
..Settings::for_rules(vec![RuleCode::C901])
..Settings::for_rules(vec![Rule::FunctionIsTooComplex])
},
)?;
insta::assert_yaml_snapshot!(snapshot, diagnostics);

View File

@ -12,12 +12,12 @@ mod tests {
use textwrap::dedent;
use crate::linter::check_path;
use crate::registry::{RuleCode, RuleCodePrefix};
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: &[RuleCode]) -> Result<()> {
fn rule_code(contents: &str, expected: &[Rule]) -> Result<()> {
let contents = dedent(contents);
let settings = settings::Settings::for_rules(RuleCodePrefix::PD.codes());
let tokens: Vec<LexResult> = rustpython_helpers::tokenize(&contents);
@ -56,7 +56,7 @@ mod tests {
import pandas as pd
x = pd.DataFrame()
x.drop(['a'], axis=1, inplace=True)
"#, &[RuleCode::PD002]; "PD002_fail")]
"#, &[Rule::UseOfInplaceArgument]; "PD002_fail")]
#[test_case(r#"
import pandas as pd
nas = pd.isna(val)
@ -64,7 +64,7 @@ mod tests {
#[test_case(r#"
import pandas as pd
nulls = pd.isnull(val)
"#, &[RuleCode::PD003]; "PD003_fail")]
"#, &[Rule::UseOfDotIsNull]; "PD003_fail")]
#[test_case(r#"
import pandas as pd
print('bah humbug')
@ -76,7 +76,7 @@ mod tests {
#[test_case(r#"
import pandas as pd
not_nulls = pd.notnull(val)
"#, &[RuleCode::PD004]; "PD004_fail")]
"#, &[Rule::UseOfDotNotNull]; "PD004_fail")]
#[test_case(r#"
import pandas as pd
x = pd.DataFrame()
@ -91,7 +91,7 @@ mod tests {
import pandas as pd
x = pd.DataFrame()
y = x.ix[[0, 2], 'A']
"#, &[RuleCode::PD007]; "PD007_fail")]
"#, &[Rule::UseOfDotIx]; "PD007_fail")]
#[test_case(r#"
import pandas as pd
x = pd.DataFrame()
@ -101,7 +101,7 @@ mod tests {
import pandas as pd
x = pd.DataFrame()
index = x.at[:, ['B', 'A']]
"#, &[RuleCode::PD008]; "PD008_fail")]
"#, &[Rule::UseOfDotAt]; "PD008_fail")]
#[test_case(r#"
import pandas as pd
x = pd.DataFrame()
@ -111,7 +111,7 @@ mod tests {
import pandas as pd
x = pd.DataFrame()
index = x.iat[:, 1:3]
"#, &[RuleCode::PD009]; "PD009_fail")]
"#, &[Rule::UseOfDotIat]; "PD009_fail")]
#[test_case(r#"
import pandas as pd
x = pd.DataFrame()
@ -133,7 +133,7 @@ mod tests {
columns='bar',
values='baz'
)
"#, &[RuleCode::PD010]; "PD010_fail_pivot")]
"#, &[Rule::UseOfDotPivotOrUnstack]; "PD010_fail_pivot")]
#[test_case(r#"
import pandas as pd
x = pd.DataFrame()
@ -148,7 +148,7 @@ mod tests {
import pandas as pd
x = pd.DataFrame()
result = x.values
"#, &[RuleCode::PD011]; "PD011_fail_values")]
"#, &[Rule::UseOfDotValues]; "PD011_fail_values")]
#[test_case(r#"
import pandas as pd
x = pd.DataFrame()
@ -177,7 +177,7 @@ mod tests {
#[test_case(r#"
import pandas as pd
employees = pd.read_table(input_file)
"#, &[RuleCode::PD012]; "PD012_fail_read_table")]
"#, &[Rule::UseOfDotReadTable]; "PD012_fail_read_table")]
#[test_case(r#"
import pandas as pd
employees = read_table
@ -204,7 +204,7 @@ mod tests {
import pandas as pd
x = pd.DataFrame()
y = x.stack(level=-1, dropna=True)
"#, &[RuleCode::PD013]; "PD013_fail_stack")]
"#, &[Rule::UseOfDotStack]; "PD013_fail_stack")]
#[test_case(r#"
import pandas as pd
pd.stack(
@ -220,7 +220,7 @@ mod tests {
x = pd.DataFrame()
y = pd.DataFrame()
pd.merge(x, y)
"#, &[RuleCode::PD015]; "PD015_fail_merge_on_pandas_object")]
"#, &[Rule::UseOfPdMerge]; "PD015_fail_merge_on_pandas_object")]
#[test_case(
"pd.to_datetime(timestamp * 10 ** 9).strftime('%Y-%m-%d %H:%M:%S.%f')",
&[];
@ -241,8 +241,8 @@ mod tests {
#[test_case(r#"
import pandas as pd
df = pd.DataFrame()
"#, &[RuleCode::PD901]; "PD901_fail_df_var")]
fn test_pandas_vet(code: &str, expected: &[RuleCode]) -> Result<()> {
"#, &[Rule::DfIsABadVariableName]; "PD901_fail_df_var")]
fn test_pandas_vet(code: &str, expected: &[Rule]) -> Result<()> {
rule_code(code, expected)?;
Ok(())
}

View File

@ -11,25 +11,25 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::N801, Path::new("N801.py"); "N801")]
#[test_case(RuleCode::N802, Path::new("N802.py"); "N802")]
#[test_case(RuleCode::N803, Path::new("N803.py"); "N803")]
#[test_case(RuleCode::N804, Path::new("N804.py"); "N804")]
#[test_case(RuleCode::N805, Path::new("N805.py"); "N805")]
#[test_case(RuleCode::N806, Path::new("N806.py"); "N806")]
#[test_case(RuleCode::N807, Path::new("N807.py"); "N807")]
#[test_case(RuleCode::N811, Path::new("N811.py"); "N811")]
#[test_case(RuleCode::N812, Path::new("N812.py"); "N812")]
#[test_case(RuleCode::N813, Path::new("N813.py"); "N813")]
#[test_case(RuleCode::N814, Path::new("N814.py"); "N814")]
#[test_case(RuleCode::N815, Path::new("N815.py"); "N815")]
#[test_case(RuleCode::N816, Path::new("N816.py"); "N816")]
#[test_case(RuleCode::N817, Path::new("N817.py"); "N817")]
#[test_case(RuleCode::N818, Path::new("N818.py"); "N818")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::InvalidClassName, Path::new("N801.py"); "N801")]
#[test_case(Rule::InvalidFunctionName, Path::new("N802.py"); "N802")]
#[test_case(Rule::InvalidArgumentName, Path::new("N803.py"); "N803")]
#[test_case(Rule::InvalidFirstArgumentNameForClassMethod, Path::new("N804.py"); "N804")]
#[test_case(Rule::InvalidFirstArgumentNameForMethod, Path::new("N805.py"); "N805")]
#[test_case(Rule::NonLowercaseVariableInFunction, Path::new("N806.py"); "N806")]
#[test_case(Rule::DunderFunctionName, Path::new("N807.py"); "N807")]
#[test_case(Rule::ConstantImportedAsNonConstant, Path::new("N811.py"); "N811")]
#[test_case(Rule::LowercaseImportedAsNonLowercase, Path::new("N812.py"); "N812")]
#[test_case(Rule::CamelcaseImportedAsLowercase, Path::new("N813.py"); "N813")]
#[test_case(Rule::CamelcaseImportedAsConstant, Path::new("N814.py"); "N814")]
#[test_case(Rule::MixedCaseVariableInClassScope, Path::new("N815.py"); "N815")]
#[test_case(Rule::MixedCaseVariableInGlobalScope, Path::new("N816.py"); "N816")]
#[test_case(Rule::CamelcaseImportedAsAcronym, Path::new("N817.py"); "N817")]
#[test_case(Rule::ErrorSuffixOnExceptionName, Path::new("N818.py"); "N818")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/pep8_naming")

View File

@ -11,32 +11,32 @@ mod tests {
use super::settings::Settings;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::E401, Path::new("E40.py"))]
#[test_case(RuleCode::E402, Path::new("E40.py"))]
#[test_case(RuleCode::E402, Path::new("E402.py"))]
#[test_case(RuleCode::E501, Path::new("E501.py"))]
#[test_case(RuleCode::E711, Path::new("E711.py"))]
#[test_case(RuleCode::E712, Path::new("E712.py"))]
#[test_case(RuleCode::E713, Path::new("E713.py"))]
#[test_case(RuleCode::E714, Path::new("E714.py"))]
#[test_case(RuleCode::E721, Path::new("E721.py"))]
#[test_case(RuleCode::E722, Path::new("E722.py"))]
#[test_case(RuleCode::E731, Path::new("E731.py"))]
#[test_case(RuleCode::E741, Path::new("E741.py"))]
#[test_case(RuleCode::E742, Path::new("E742.py"))]
#[test_case(RuleCode::E743, Path::new("E743.py"))]
#[test_case(RuleCode::E999, Path::new("E999.py"))]
#[test_case(RuleCode::W292, Path::new("W292_0.py"))]
#[test_case(RuleCode::W292, Path::new("W292_1.py"))]
#[test_case(RuleCode::W292, Path::new("W292_2.py"))]
#[test_case(RuleCode::W292, Path::new("W292_3.py"))]
#[test_case(RuleCode::W292, Path::new("W292_4.py"))]
#[test_case(RuleCode::W605, Path::new("W605_0.py"))]
#[test_case(RuleCode::W605, Path::new("W605_1.py"))]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::MultipleImportsOnOneLine, Path::new("E40.py"))]
#[test_case(Rule::ModuleImportNotAtTopOfFile, Path::new("E40.py"))]
#[test_case(Rule::ModuleImportNotAtTopOfFile, Path::new("E402.py"))]
#[test_case(Rule::LineTooLong, Path::new("E501.py"))]
#[test_case(Rule::NoneComparison, Path::new("E711.py"))]
#[test_case(Rule::TrueFalseComparison, Path::new("E712.py"))]
#[test_case(Rule::NotInTest, Path::new("E713.py"))]
#[test_case(Rule::NotIsTest, Path::new("E714.py"))]
#[test_case(Rule::TypeComparison, Path::new("E721.py"))]
#[test_case(Rule::DoNotUseBareExcept, Path::new("E722.py"))]
#[test_case(Rule::DoNotAssignLambda, Path::new("E731.py"))]
#[test_case(Rule::AmbiguousVariableName, Path::new("E741.py"))]
#[test_case(Rule::AmbiguousClassName, Path::new("E742.py"))]
#[test_case(Rule::AmbiguousFunctionName, Path::new("E743.py"))]
#[test_case(Rule::SyntaxError, Path::new("E999.py"))]
#[test_case(Rule::NoNewLineAtEndOfFile, Path::new("W292_0.py"))]
#[test_case(Rule::NoNewLineAtEndOfFile, Path::new("W292_1.py"))]
#[test_case(Rule::NoNewLineAtEndOfFile, Path::new("W292_2.py"))]
#[test_case(Rule::NoNewLineAtEndOfFile, Path::new("W292_3.py"))]
#[test_case(Rule::NoNewLineAtEndOfFile, Path::new("W292_4.py"))]
#[test_case(Rule::InvalidEscapeSequence, Path::new("W605_0.py"))]
#[test_case(Rule::InvalidEscapeSequence, Path::new("W605_1.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/pycodestyle")
@ -52,7 +52,11 @@ mod tests {
fn constant_literals() -> Result<()> {
let diagnostics = test_path(
Path::new("./resources/test/fixtures/pycodestyle/constant_literals.py"),
&settings::Settings::for_rules(vec![RuleCode::E711, RuleCode::E712, RuleCode::F632]),
&settings::Settings::for_rules(vec![
Rule::NoneComparison,
Rule::TrueFalseComparison,
Rule::IsLiteral,
]),
)?;
insta::assert_yaml_snapshot!(diagnostics);
Ok(())
@ -69,7 +73,7 @@ mod tests {
ignore_overlong_task_comments,
..Settings::default()
},
..settings::Settings::for_rule(RuleCode::E501)
..settings::Settings::for_rule(Rule::LineTooLong)
},
)?;
insta::assert_yaml_snapshot!(snapshot, diagnostics);
@ -85,7 +89,7 @@ mod tests {
max_doc_length: Some(50),
..Settings::default()
},
..settings::Settings::for_rule(RuleCode::W505)
..settings::Settings::for_rule(Rule::DocLineTooLong)
},
)?;
insta::assert_yaml_snapshot!(diagnostics);

View File

@ -12,59 +12,59 @@ mod tests {
use super::settings::{Convention, Settings};
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::D100, Path::new("D.py"); "D100")]
#[test_case(RuleCode::D101, Path::new("D.py"); "D101")]
#[test_case(RuleCode::D102, Path::new("D.py"); "D102_0")]
#[test_case(RuleCode::D102, Path::new("setter.py"); "D102_1")]
#[test_case(RuleCode::D103, Path::new("D.py"); "D103")]
#[test_case(RuleCode::D104, Path::new("D.py"); "D104")]
#[test_case(RuleCode::D105, Path::new("D.py"); "D105")]
#[test_case(RuleCode::D106, Path::new("D.py"); "D106")]
#[test_case(RuleCode::D107, Path::new("D.py"); "D107")]
#[test_case(RuleCode::D201, Path::new("D.py"); "D201")]
#[test_case(RuleCode::D202, Path::new("D.py"); "D202")]
#[test_case(RuleCode::D203, Path::new("D.py"); "D203")]
#[test_case(RuleCode::D204, Path::new("D.py"); "D204")]
#[test_case(RuleCode::D205, Path::new("D.py"); "D205")]
#[test_case(RuleCode::D206, Path::new("D.py"); "D206")]
#[test_case(RuleCode::D207, Path::new("D.py"); "D207")]
#[test_case(RuleCode::D208, Path::new("D.py"); "D208")]
#[test_case(RuleCode::D209, Path::new("D.py"); "D209")]
#[test_case(RuleCode::D210, Path::new("D.py"); "D210")]
#[test_case(RuleCode::D211, Path::new("D.py"); "D211")]
#[test_case(RuleCode::D212, Path::new("D.py"); "D212")]
#[test_case(RuleCode::D213, Path::new("D.py"); "D213")]
#[test_case(RuleCode::D214, Path::new("sections.py"); "D214")]
#[test_case(RuleCode::D215, Path::new("sections.py"); "D215")]
#[test_case(RuleCode::D300, Path::new("D.py"); "D300")]
#[test_case(RuleCode::D301, Path::new("D.py"); "D301")]
#[test_case(RuleCode::D400, Path::new("D.py"); "D400_0")]
#[test_case(RuleCode::D400, Path::new("D400.py"); "D400_1")]
#[test_case(RuleCode::D402, Path::new("D.py"); "D402")]
#[test_case(RuleCode::D403, Path::new("D.py"); "D403")]
#[test_case(RuleCode::D404, Path::new("D.py"); "D404")]
#[test_case(RuleCode::D405, Path::new("sections.py"); "D405")]
#[test_case(RuleCode::D406, Path::new("sections.py"); "D406")]
#[test_case(RuleCode::D407, Path::new("sections.py"); "D407")]
#[test_case(RuleCode::D408, Path::new("sections.py"); "D408")]
#[test_case(RuleCode::D409, Path::new("sections.py"); "D409")]
#[test_case(RuleCode::D410, Path::new("sections.py"); "D410")]
#[test_case(RuleCode::D411, Path::new("sections.py"); "D411")]
#[test_case(RuleCode::D412, Path::new("sections.py"); "D412")]
#[test_case(RuleCode::D413, Path::new("sections.py"); "D413")]
#[test_case(RuleCode::D414, Path::new("sections.py"); "D414")]
#[test_case(RuleCode::D415, Path::new("D.py"); "D415")]
#[test_case(RuleCode::D416, Path::new("D.py"); "D416")]
#[test_case(RuleCode::D417, Path::new("canonical_google_examples.py"); "D417_2")]
#[test_case(RuleCode::D417, Path::new("canonical_numpy_examples.py"); "D417_1")]
#[test_case(RuleCode::D417, Path::new("sections.py"); "D417_0")]
#[test_case(RuleCode::D418, Path::new("D.py"); "D418")]
#[test_case(RuleCode::D419, Path::new("D.py"); "D419")]
#[test_case(RuleCode::D104, Path::new("D104/__init__.py"); "D104_1")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::PublicModule, Path::new("D.py"); "D100")]
#[test_case(Rule::PublicClass, Path::new("D.py"); "D101")]
#[test_case(Rule::PublicMethod, Path::new("D.py"); "D102_0")]
#[test_case(Rule::PublicMethod, Path::new("setter.py"); "D102_1")]
#[test_case(Rule::PublicFunction, Path::new("D.py"); "D103")]
#[test_case(Rule::PublicPackage, Path::new("D.py"); "D104")]
#[test_case(Rule::MagicMethod, Path::new("D.py"); "D105")]
#[test_case(Rule::PublicNestedClass, Path::new("D.py"); "D106")]
#[test_case(Rule::PublicInit, Path::new("D.py"); "D107")]
#[test_case(Rule::NoBlankLineBeforeFunction, Path::new("D.py"); "D201")]
#[test_case(Rule::NoBlankLineAfterFunction, Path::new("D.py"); "D202")]
#[test_case(Rule::OneBlankLineBeforeClass, Path::new("D.py"); "D203")]
#[test_case(Rule::OneBlankLineAfterClass, Path::new("D.py"); "D204")]
#[test_case(Rule::BlankLineAfterSummary, Path::new("D.py"); "D205")]
#[test_case(Rule::IndentWithSpaces, Path::new("D.py"); "D206")]
#[test_case(Rule::NoUnderIndentation, Path::new("D.py"); "D207")]
#[test_case(Rule::NoOverIndentation, Path::new("D.py"); "D208")]
#[test_case(Rule::NewLineAfterLastParagraph, Path::new("D.py"); "D209")]
#[test_case(Rule::NoSurroundingWhitespace, Path::new("D.py"); "D210")]
#[test_case(Rule::NoBlankLineBeforeClass, Path::new("D.py"); "D211")]
#[test_case(Rule::MultiLineSummaryFirstLine, Path::new("D.py"); "D212")]
#[test_case(Rule::MultiLineSummarySecondLine, Path::new("D.py"); "D213")]
#[test_case(Rule::SectionNotOverIndented, Path::new("sections.py"); "D214")]
#[test_case(Rule::SectionUnderlineNotOverIndented, Path::new("sections.py"); "D215")]
#[test_case(Rule::UsesTripleQuotes, Path::new("D.py"); "D300")]
#[test_case(Rule::UsesRPrefixForBackslashedContent, Path::new("D.py"); "D301")]
#[test_case(Rule::EndsInPeriod, Path::new("D.py"); "D400_0")]
#[test_case(Rule::EndsInPeriod, Path::new("D400.py"); "D400_1")]
#[test_case(Rule::NoSignature, Path::new("D.py"); "D402")]
#[test_case(Rule::FirstLineCapitalized, Path::new("D.py"); "D403")]
#[test_case(Rule::NoThisPrefix, Path::new("D.py"); "D404")]
#[test_case(Rule::CapitalizeSectionName, Path::new("sections.py"); "D405")]
#[test_case(Rule::NewLineAfterSectionName, Path::new("sections.py"); "D406")]
#[test_case(Rule::DashedUnderlineAfterSection, Path::new("sections.py"); "D407")]
#[test_case(Rule::SectionUnderlineAfterName, Path::new("sections.py"); "D408")]
#[test_case(Rule::SectionUnderlineMatchesSectionLength, Path::new("sections.py"); "D409")]
#[test_case(Rule::BlankLineAfterSection, Path::new("sections.py"); "D410")]
#[test_case(Rule::BlankLineBeforeSection, Path::new("sections.py"); "D411")]
#[test_case(Rule::NoBlankLinesBetweenHeaderAndContent, Path::new("sections.py"); "D412")]
#[test_case(Rule::BlankLineAfterLastSection, Path::new("sections.py"); "D413")]
#[test_case(Rule::NonEmptySection, Path::new("sections.py"); "D414")]
#[test_case(Rule::EndsInPunctuation, Path::new("D.py"); "D415")]
#[test_case(Rule::SectionNameEndsInColon, Path::new("D.py"); "D416")]
#[test_case(Rule::DocumentAllArguments, Path::new("canonical_google_examples.py"); "D417_2")]
#[test_case(Rule::DocumentAllArguments, Path::new("canonical_numpy_examples.py"); "D417_1")]
#[test_case(Rule::DocumentAllArguments, Path::new("sections.py"); "D417_0")]
#[test_case(Rule::SkipDocstring, Path::new("D.py"); "D418")]
#[test_case(Rule::NonEmpty, Path::new("D.py"); "D419")]
#[test_case(Rule::PublicPackage, Path::new("D104/__init__.py"); "D104_1")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/pydocstyle")
@ -84,7 +84,7 @@ mod tests {
// When inferring the convention, we'll see a few false negatives.
// See: https://github.com/PyCQA/pydocstyle/issues/459.
pydocstyle: Settings { convention: None },
..settings::Settings::for_rule(RuleCode::D417)
..settings::Settings::for_rule(Rule::DocumentAllArguments)
},
)?;
insta::assert_yaml_snapshot!(diagnostics);
@ -100,7 +100,7 @@ mod tests {
pydocstyle: Settings {
convention: Some(Convention::Google),
},
..settings::Settings::for_rule(RuleCode::D417)
..settings::Settings::for_rule(Rule::DocumentAllArguments)
},
)?;
insta::assert_yaml_snapshot!(diagnostics);
@ -116,7 +116,7 @@ mod tests {
pydocstyle: Settings {
convention: Some(Convention::Numpy),
},
..settings::Settings::for_rule(RuleCode::D417)
..settings::Settings::for_rule(Rule::DocumentAllArguments)
},
)?;
insta::assert_yaml_snapshot!(diagnostics);

View File

@ -16,7 +16,7 @@ use crate::docstrings::definition::{Definition, DefinitionKind, Docstring};
use crate::docstrings::sections::{section_contexts, SectionContext};
use crate::docstrings::styles::SectionStyle;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
use crate::visibility::{
is_call, is_init, is_magic, is_new, is_overload, is_override, is_staticmethod, Visibility,
@ -34,7 +34,7 @@ pub fn not_missing(
match definition.kind {
DefinitionKind::Module => {
if checker.settings.rules.enabled(&RuleCode::D100) {
if checker.settings.rules.enabled(&Rule::PublicModule) {
checker.diagnostics.push(Diagnostic::new(
violations::PublicModule,
Range::new(Location::new(1, 0), Location::new(1, 0)),
@ -43,7 +43,7 @@ pub fn not_missing(
false
}
DefinitionKind::Package => {
if checker.settings.rules.enabled(&RuleCode::D104) {
if checker.settings.rules.enabled(&Rule::PublicPackage) {
checker.diagnostics.push(Diagnostic::new(
violations::PublicPackage,
Range::new(Location::new(1, 0), Location::new(1, 0)),
@ -52,7 +52,7 @@ pub fn not_missing(
false
}
DefinitionKind::Class(stmt) => {
if checker.settings.rules.enabled(&RuleCode::D101) {
if checker.settings.rules.enabled(&Rule::PublicClass) {
checker.diagnostics.push(Diagnostic::new(
violations::PublicClass,
identifier_range(stmt, checker.locator),
@ -61,7 +61,7 @@ pub fn not_missing(
false
}
DefinitionKind::NestedClass(stmt) => {
if checker.settings.rules.enabled(&RuleCode::D106) {
if checker.settings.rules.enabled(&Rule::PublicNestedClass) {
checker.diagnostics.push(Diagnostic::new(
violations::PublicNestedClass,
identifier_range(stmt, checker.locator),
@ -73,7 +73,7 @@ pub fn not_missing(
if is_overload(checker, cast::decorator_list(stmt)) {
true
} else {
if checker.settings.rules.enabled(&RuleCode::D103) {
if checker.settings.rules.enabled(&Rule::PublicFunction) {
checker.diagnostics.push(Diagnostic::new(
violations::PublicFunction,
identifier_range(stmt, checker.locator),
@ -88,7 +88,7 @@ pub fn not_missing(
{
true
} else if is_init(cast::name(stmt)) {
if checker.settings.rules.enabled(&RuleCode::D107) {
if checker.settings.rules.enabled(&Rule::PublicInit) {
checker.diagnostics.push(Diagnostic::new(
violations::PublicInit,
identifier_range(stmt, checker.locator),
@ -96,7 +96,7 @@ pub fn not_missing(
}
true
} else if is_new(cast::name(stmt)) || is_call(cast::name(stmt)) {
if checker.settings.rules.enabled(&RuleCode::D102) {
if checker.settings.rules.enabled(&Rule::PublicMethod) {
checker.diagnostics.push(Diagnostic::new(
violations::PublicMethod,
identifier_range(stmt, checker.locator),
@ -104,7 +104,7 @@ pub fn not_missing(
}
true
} else if is_magic(cast::name(stmt)) {
if checker.settings.rules.enabled(&RuleCode::D105) {
if checker.settings.rules.enabled(&Rule::MagicMethod) {
checker.diagnostics.push(Diagnostic::new(
violations::MagicMethod,
identifier_range(stmt, checker.locator),
@ -112,7 +112,7 @@ pub fn not_missing(
}
true
} else {
if checker.settings.rules.enabled(&RuleCode::D102) {
if checker.settings.rules.enabled(&Rule::PublicMethod) {
checker.diagnostics.push(Diagnostic::new(
violations::PublicMethod,
identifier_range(stmt, checker.locator),
@ -163,7 +163,11 @@ pub fn blank_before_after_function(checker: &mut Checker, docstring: &Docstring)
return;
};
if checker.settings.rules.enabled(&RuleCode::D201) {
if checker
.settings
.rules
.enabled(&Rule::NoBlankLineBeforeFunction)
{
let (before, ..) = checker.locator.partition_source_code_at(
&Range::from_located(parent),
&Range::from_located(docstring.expr),
@ -191,7 +195,11 @@ pub fn blank_before_after_function(checker: &mut Checker, docstring: &Docstring)
}
}
if checker.settings.rules.enabled(&RuleCode::D202) {
if checker
.settings
.rules
.enabled(&Rule::NoBlankLineAfterFunction)
{
let (_, _, after) = checker.locator.partition_source_code_at(
&Range::from_located(parent),
&Range::from_located(docstring.expr),
@ -242,8 +250,14 @@ pub fn blank_before_after_class(checker: &mut Checker, docstring: &Docstring) {
return;
};
if checker.settings.rules.enabled(&RuleCode::D203)
|| checker.settings.rules.enabled(&RuleCode::D211)
if checker
.settings
.rules
.enabled(&Rule::OneBlankLineBeforeClass)
|| checker
.settings
.rules
.enabled(&Rule::NoBlankLineBeforeClass)
{
let (before, ..) = checker.locator.partition_source_code_at(
&Range::from_located(parent),
@ -256,7 +270,11 @@ pub fn blank_before_after_class(checker: &mut Checker, docstring: &Docstring) {
.skip(1)
.take_while(|line| line.trim().is_empty())
.count();
if checker.settings.rules.enabled(&RuleCode::D211) {
if checker
.settings
.rules
.enabled(&Rule::NoBlankLineBeforeClass)
{
if blank_lines_before != 0 {
let mut diagnostic = Diagnostic::new(
violations::NoBlankLineBeforeClass(blank_lines_before),
@ -272,7 +290,11 @@ pub fn blank_before_after_class(checker: &mut Checker, docstring: &Docstring) {
checker.diagnostics.push(diagnostic);
}
}
if checker.settings.rules.enabled(&RuleCode::D203) {
if checker
.settings
.rules
.enabled(&Rule::OneBlankLineBeforeClass)
{
if blank_lines_before != 1 {
let mut diagnostic = Diagnostic::new(
violations::OneBlankLineBeforeClass(blank_lines_before),
@ -291,7 +313,11 @@ pub fn blank_before_after_class(checker: &mut Checker, docstring: &Docstring) {
}
}
if checker.settings.rules.enabled(&RuleCode::D204) {
if checker
.settings
.rules
.enabled(&Rule::OneBlankLineAfterClass)
{
let (_, _, after) = checker.locator.partition_source_code_at(
&Range::from_located(parent),
&Range::from_located(docstring.expr),
@ -409,7 +435,7 @@ pub fn indent(checker: &mut Checker, docstring: &Docstring) {
// yet.
has_seen_tab = has_seen_tab || line_indent.contains('\t');
if checker.settings.rules.enabled(&RuleCode::D207) {
if checker.settings.rules.enabled(&Rule::NoUnderIndentation) {
// We report under-indentation on every line. This isn't great, but enables
// autofix.
if (i == lines.len() - 1 || !is_blank)
@ -448,7 +474,7 @@ pub fn indent(checker: &mut Checker, docstring: &Docstring) {
}
}
if checker.settings.rules.enabled(&RuleCode::D206) {
if checker.settings.rules.enabled(&Rule::IndentWithSpaces) {
if has_seen_tab {
checker.diagnostics.push(Diagnostic::new(
violations::IndentWithSpaces,
@ -457,7 +483,7 @@ pub fn indent(checker: &mut Checker, docstring: &Docstring) {
}
}
if checker.settings.rules.enabled(&RuleCode::D208) {
if checker.settings.rules.enabled(&Rule::NoOverIndentation) {
// If every line (except the last) is over-indented...
if is_over_indented {
for i in over_indented_lines {
@ -618,14 +644,22 @@ pub fn multi_line_summary_start(checker: &mut Checker, docstring: &Docstring) {
return;
};
if constants::TRIPLE_QUOTE_PREFIXES.contains(&first_line) {
if checker.settings.rules.enabled(&RuleCode::D212) {
if checker
.settings
.rules
.enabled(&Rule::MultiLineSummaryFirstLine)
{
checker.diagnostics.push(Diagnostic::new(
violations::MultiLineSummaryFirstLine,
Range::from_located(docstring.expr),
));
}
} else {
if checker.settings.rules.enabled(&RuleCode::D213) {
if checker
.settings
.rules
.enabled(&Rule::MultiLineSummarySecondLine)
{
checker.diagnostics.push(Diagnostic::new(
violations::MultiLineSummarySecondLine,
Range::from_located(docstring.expr),
@ -724,7 +758,9 @@ pub fn ends_with_period(checker: &mut Checker, docstring: &Docstring) {
Range::from_located(docstring.expr),
);
// Best-effort autofix: avoid adding a period after other punctuation marks.
if checker.patch(&RuleCode::D400) && !trimmed.ends_with(':') && !trimmed.ends_with(';')
if checker.patch(&Rule::EndsInPeriod)
&& !trimmed.ends_with(':')
&& !trimmed.ends_with(';')
{
if let Some((row, column)) = if index == 0 {
leading_quote(contents).map(|pattern| {
@ -871,7 +907,9 @@ pub fn ends_with_punctuation(checker: &mut Checker, docstring: &Docstring) {
Range::from_located(docstring.expr),
);
// Best-effort autofix: avoid adding a period after other punctuation marks.
if checker.patch(&RuleCode::D415) && !trimmed.ends_with(':') && !trimmed.ends_with(';')
if checker.patch(&Rule::EndsInPunctuation)
&& !trimmed.ends_with(':')
&& !trimmed.ends_with(';')
{
if let Some((row, column)) = if index == 0 {
leading_quote(contents).map(|pattern| {
@ -920,7 +958,7 @@ pub fn not_empty(checker: &mut Checker, docstring: &Docstring) -> bool {
return true;
}
if checker.settings.rules.enabled(&RuleCode::D419) {
if checker.settings.rules.enabled(&Rule::NonEmpty) {
checker.diagnostics.push(Diagnostic::new(
violations::NonEmpty,
Range::from_located(docstring.expr),
@ -983,7 +1021,11 @@ fn blanks_and_section_underline(
// Nothing but blank lines after the section header.
if blank_lines_after_header == context.following_lines.len() {
if checker.settings.rules.enabled(&RuleCode::D407) {
if checker
.settings
.rules
.enabled(&Rule::DashedUnderlineAfterSection)
{
let mut diagnostic = Diagnostic::new(
violations::DashedUnderlineAfterSection(context.section_name.to_string()),
Range::from_located(docstring.expr),
@ -1005,7 +1047,7 @@ fn blanks_and_section_underline(
}
checker.diagnostics.push(diagnostic);
}
if checker.settings.rules.enabled(&RuleCode::D414) {
if checker.settings.rules.enabled(&Rule::NonEmptySection) {
checker.diagnostics.push(Diagnostic::new(
violations::NonEmptySection(context.section_name.to_string()),
Range::from_located(docstring.expr),
@ -1021,7 +1063,11 @@ fn blanks_and_section_underline(
if dash_line_found {
if blank_lines_after_header > 0 {
if checker.settings.rules.enabled(&RuleCode::D408) {
if checker
.settings
.rules
.enabled(&Rule::SectionUnderlineAfterName)
{
let mut diagnostic = Diagnostic::new(
violations::SectionUnderlineAfterName(context.section_name.to_string()),
Range::from_located(docstring.expr),
@ -1053,7 +1099,11 @@ fn blanks_and_section_underline(
.count()
!= context.section_name.len()
{
if checker.settings.rules.enabled(&RuleCode::D409) {
if checker
.settings
.rules
.enabled(&Rule::SectionUnderlineMatchesSectionLength)
{
let mut diagnostic = Diagnostic::new(
violations::SectionUnderlineMatchesSectionLength(
context.section_name.to_string(),
@ -1090,7 +1140,11 @@ fn blanks_and_section_underline(
}
}
if checker.settings.rules.enabled(&RuleCode::D215) {
if checker
.settings
.rules
.enabled(&Rule::SectionUnderlineNotOverIndented)
{
let leading_space = whitespace::leading_space(non_empty_line);
if leading_space.len() > docstring.indentation.len() {
let mut diagnostic = Diagnostic::new(
@ -1132,14 +1186,18 @@ fn blanks_and_section_underline(
.take_while(|line| line.trim().is_empty())
.count();
if blank_lines_after_dashes == rest_of_lines.len() {
if checker.settings.rules.enabled(&RuleCode::D414) {
if checker.settings.rules.enabled(&Rule::NonEmptySection) {
checker.diagnostics.push(Diagnostic::new(
violations::NonEmptySection(context.section_name.to_string()),
Range::from_located(docstring.expr),
));
}
} else {
if checker.settings.rules.enabled(&RuleCode::D412) {
if checker
.settings
.rules
.enabled(&Rule::NoBlankLinesBetweenHeaderAndContent)
{
let mut diagnostic = Diagnostic::new(
violations::NoBlankLinesBetweenHeaderAndContent(
context.section_name.to_string(),
@ -1171,7 +1229,7 @@ fn blanks_and_section_underline(
}
}
} else {
if checker.settings.rules.enabled(&RuleCode::D414) {
if checker.settings.rules.enabled(&Rule::NonEmptySection) {
checker.diagnostics.push(Diagnostic::new(
violations::NonEmptySection(context.section_name.to_string()),
Range::from_located(docstring.expr),
@ -1179,7 +1237,11 @@ fn blanks_and_section_underline(
}
}
} else {
if checker.settings.rules.enabled(&RuleCode::D407) {
if checker
.settings
.rules
.enabled(&Rule::DashedUnderlineAfterSection)
{
let mut diagnostic = Diagnostic::new(
violations::DashedUnderlineAfterSection(context.section_name.to_string()),
Range::from_located(docstring.expr),
@ -1202,7 +1264,11 @@ fn blanks_and_section_underline(
checker.diagnostics.push(diagnostic);
}
if blank_lines_after_header > 0 {
if checker.settings.rules.enabled(&RuleCode::D412) {
if checker
.settings
.rules
.enabled(&Rule::NoBlankLinesBetweenHeaderAndContent)
{
let mut diagnostic = Diagnostic::new(
violations::NoBlankLinesBetweenHeaderAndContent(
context.section_name.to_string(),
@ -1237,7 +1303,7 @@ fn common_section(
context: &SectionContext,
style: &SectionStyle,
) {
if checker.settings.rules.enabled(&RuleCode::D405) {
if checker.settings.rules.enabled(&Rule::CapitalizeSectionName) {
if !style.section_names().contains(&context.section_name) {
let capitalized_section_name = titlecase::titlecase(context.section_name);
if style
@ -1273,7 +1339,11 @@ fn common_section(
}
}
if checker.settings.rules.enabled(&RuleCode::D214) {
if checker
.settings
.rules
.enabled(&Rule::SectionNotOverIndented)
{
let leading_space = whitespace::leading_space(context.line);
if leading_space.len() > docstring.indentation.len() {
let mut diagnostic = Diagnostic::new(
@ -1301,7 +1371,11 @@ fn common_section(
.map_or(true, |line| !line.trim().is_empty())
{
if context.is_last_section {
if checker.settings.rules.enabled(&RuleCode::D413) {
if checker
.settings
.rules
.enabled(&Rule::BlankLineAfterLastSection)
{
let mut diagnostic = Diagnostic::new(
violations::BlankLineAfterLastSection(context.section_name.to_string()),
Range::from_located(docstring.expr),
@ -1322,7 +1396,7 @@ fn common_section(
checker.diagnostics.push(diagnostic);
}
} else {
if checker.settings.rules.enabled(&RuleCode::D410) {
if checker.settings.rules.enabled(&Rule::BlankLineAfterSection) {
let mut diagnostic = Diagnostic::new(
violations::BlankLineAfterSection(context.section_name.to_string()),
Range::from_located(docstring.expr),
@ -1345,7 +1419,11 @@ fn common_section(
}
}
if checker.settings.rules.enabled(&RuleCode::D411) {
if checker
.settings
.rules
.enabled(&Rule::BlankLineBeforeSection)
{
if !context.previous_line.is_empty() {
let mut diagnostic = Diagnostic::new(
violations::BlankLineBeforeSection(context.section_name.to_string()),
@ -1529,7 +1607,11 @@ fn parameters_section(checker: &mut Checker, docstring: &Docstring, context: &Se
fn numpy_section(checker: &mut Checker, docstring: &Docstring, context: &SectionContext) {
common_section(checker, docstring, context, &SectionStyle::Numpy);
if checker.settings.rules.enabled(&RuleCode::D406) {
if checker
.settings
.rules
.enabled(&Rule::NewLineAfterSectionName)
{
let suffix = context
.line
.trim()
@ -1564,7 +1646,7 @@ fn numpy_section(checker: &mut Checker, docstring: &Docstring, context: &Section
}
}
if checker.settings.rules.enabled(&RuleCode::D417) {
if checker.settings.rules.enabled(&Rule::DocumentAllArguments) {
let capitalized_section_name = titlecase::titlecase(context.section_name);
if capitalized_section_name == "Parameters" {
parameters_section(checker, docstring, context);
@ -1575,7 +1657,11 @@ fn numpy_section(checker: &mut Checker, docstring: &Docstring, context: &Section
fn google_section(checker: &mut Checker, docstring: &Docstring, context: &SectionContext) {
common_section(checker, docstring, context, &SectionStyle::Google);
if checker.settings.rules.enabled(&RuleCode::D416) {
if checker
.settings
.rules
.enabled(&Rule::SectionNameEndsInColon)
{
let suffix = context
.line
.trim()
@ -1611,7 +1697,7 @@ fn google_section(checker: &mut Checker, docstring: &Docstring, context: &Sectio
}
}
if checker.settings.rules.enabled(&RuleCode::D417) {
if checker.settings.rules.enabled(&Rule::DocumentAllArguments) {
let capitalized_section_name = titlecase::titlecase(context.section_name);
if capitalized_section_name == "Args" || capitalized_section_name == "Arguments" {
args_section(checker, docstring, context);

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@ use rustpython_ast::{Expr, ExprKind};
use crate::ast::helpers::find_useless_f_strings;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
/// F541
@ -14,7 +14,7 @@ pub fn f_string_missing_placeholders(expr: &Expr, values: &[Expr], checker: &mut
{
for (prefix_range, tok_range) in find_useless_f_strings(expr, checker.locator) {
let mut diagnostic = Diagnostic::new(violations::FStringMissingPlaceholders, tok_range);
if checker.patch(&RuleCode::F541) {
if checker.patch(&Rule::FStringMissingPlaceholders) {
diagnostic.amend(Fix::deletion(
prefix_range.location,
prefix_range.end_location,

View File

@ -8,7 +8,7 @@ use crate::ast::helpers::unparse_expr;
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
#[derive(Debug, Eq, PartialEq, Hash)]
@ -37,7 +37,11 @@ pub fn repeated_keys(checker: &mut Checker, keys: &[Expr], values: &[Expr]) {
if let Some(seen_values) = seen.get_mut(&key) {
match key {
DictionaryKey::Constant(..) => {
if checker.settings.rules.enabled(&RuleCode::F601) {
if checker
.settings
.rules
.enabled(&Rule::MultiValueRepeatedKeyLiteral)
{
let comparable_value: ComparableExpr = (&values[i]).into();
let is_duplicate_value = seen_values.contains(&comparable_value);
let mut diagnostic = Diagnostic::new(
@ -48,7 +52,7 @@ pub fn repeated_keys(checker: &mut Checker, keys: &[Expr], values: &[Expr]) {
Range::from_located(&keys[i]),
);
if is_duplicate_value {
if checker.patch(&RuleCode::F601) {
if checker.patch(&Rule::MultiValueRepeatedKeyLiteral) {
diagnostic.amend(Fix::deletion(
values[i - 1].end_location.unwrap(),
values[i].end_location.unwrap(),
@ -61,7 +65,11 @@ pub fn repeated_keys(checker: &mut Checker, keys: &[Expr], values: &[Expr]) {
}
}
DictionaryKey::Variable(key) => {
if checker.settings.rules.enabled(&RuleCode::F602) {
if checker
.settings
.rules
.enabled(&Rule::MultiValueRepeatedKeyVariable)
{
let comparable_value: ComparableExpr = (&values[i]).into();
let is_duplicate_value = seen_values.contains(&comparable_value);
let mut diagnostic = Diagnostic::new(
@ -72,7 +80,7 @@ pub fn repeated_keys(checker: &mut Checker, keys: &[Expr], values: &[Expr]) {
Range::from_located(&keys[i]),
);
if is_duplicate_value {
if checker.patch(&RuleCode::F602) {
if checker.patch(&Rule::MultiValueRepeatedKeyVariable) {
diagnostic.amend(Fix::deletion(
values[i - 1].end_location.unwrap(),
values[i].end_location.unwrap(),

View File

@ -9,7 +9,7 @@ use crate::ast::types::{BindingKind, Range, RefEquality, ScopeKind};
use crate::autofix::helpers::delete_stmt;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::source_code::Locator;
use crate::violations;
@ -167,7 +167,7 @@ pub fn unused_variable(checker: &mut Checker, scope: usize) {
violations::UnusedVariable((*name).to_string()),
binding.range,
);
if checker.patch(&RuleCode::F841) {
if checker.patch(&Rule::UnusedVariable) {
if let Some(stmt) = binding.source.as_ref().map(std::convert::Into::into) {
if let Some((kind, fix)) = remove_unused_variable(stmt, &binding.range, checker)
{

View File

@ -9,16 +9,16 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::PGH001, Path::new("PGH001_0.py"); "PGH001_0")]
#[test_case(RuleCode::PGH001, Path::new("PGH001_1.py"); "PGH001_1")]
#[test_case(RuleCode::PGH002, Path::new("PGH002_0.py"); "PGH002_0")]
#[test_case(RuleCode::PGH002, Path::new("PGH002_1.py"); "PGH002_1")]
#[test_case(RuleCode::PGH003, Path::new("PGH003_0.py"); "PGH003_0")]
#[test_case(RuleCode::PGH004, Path::new("PGH004_0.py"); "PGH004_0")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::NoEval, Path::new("PGH001_0.py"); "PGH001_0")]
#[test_case(Rule::NoEval, Path::new("PGH001_1.py"); "PGH001_1")]
#[test_case(Rule::DeprecatedLogWarn, Path::new("PGH002_0.py"); "PGH002_0")]
#[test_case(Rule::DeprecatedLogWarn, Path::new("PGH002_1.py"); "PGH002_1")]
#[test_case(Rule::BlanketTypeIgnore, Path::new("PGH003_0.py"); "PGH003_0")]
#[test_case(Rule::BlanketNOQA, Path::new("PGH004_0.py"); "PGH004_0")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/pygrep-hooks")

View File

@ -10,30 +10,30 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::rules::pylint;
use crate::settings::Settings;
#[test_case(RuleCode::PLC0414, Path::new("import_aliasing.py"); "PLC0414")]
#[test_case(RuleCode::PLC3002, Path::new("unnecessary_direct_lambda_call.py"); "PLC3002")]
#[test_case(RuleCode::PLE0117, Path::new("nonlocal_without_binding.py"); "PLE0117")]
#[test_case(RuleCode::PLE0118, Path::new("used_prior_global_declaration.py"); "PLE0118")]
#[test_case(RuleCode::PLE1142, Path::new("await_outside_async.py"); "PLE1142")]
#[test_case(RuleCode::PLR0133, Path::new("constant_comparison.py"); "PLR0133")]
#[test_case(RuleCode::PLR0206, Path::new("property_with_parameters.py"); "PLR0206")]
#[test_case(RuleCode::PLR0402, Path::new("import_aliasing.py"); "PLR0402")]
#[test_case(RuleCode::PLR1701, Path::new("consider_merging_isinstance.py"); "PLR1701")]
#[test_case(RuleCode::PLR1722, Path::new("consider_using_sys_exit_0.py"); "PLR1722_0")]
#[test_case(RuleCode::PLR1722, Path::new("consider_using_sys_exit_1.py"); "PLR1722_1")]
#[test_case(RuleCode::PLR1722, Path::new("consider_using_sys_exit_2.py"); "PLR1722_2")]
#[test_case(RuleCode::PLR1722, Path::new("consider_using_sys_exit_3.py"); "PLR1722_3")]
#[test_case(RuleCode::PLR1722, Path::new("consider_using_sys_exit_4.py"); "PLR1722_4")]
#[test_case(RuleCode::PLR1722, Path::new("consider_using_sys_exit_5.py"); "PLR1722_5")]
#[test_case(RuleCode::PLR1722, Path::new("consider_using_sys_exit_6.py"); "PLR1722_6")]
#[test_case(RuleCode::PLR2004, Path::new("magic_value_comparison.py"); "PLR2004")]
#[test_case(RuleCode::PLW0120, Path::new("useless_else_on_loop.py"); "PLW0120")]
#[test_case(RuleCode::PLW0602, Path::new("global_variable_not_assigned.py"); "PLW0602")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::UselessImportAlias, Path::new("import_aliasing.py"); "PLC0414")]
#[test_case(Rule::UnnecessaryDirectLambdaCall, Path::new("unnecessary_direct_lambda_call.py"); "PLC3002")]
#[test_case(Rule::NonlocalWithoutBinding, Path::new("nonlocal_without_binding.py"); "PLE0117")]
#[test_case(Rule::UsedPriorGlobalDeclaration, Path::new("used_prior_global_declaration.py"); "PLE0118")]
#[test_case(Rule::AwaitOutsideAsync, Path::new("await_outside_async.py"); "PLE1142")]
#[test_case(Rule::ConstantComparison, Path::new("constant_comparison.py"); "PLR0133")]
#[test_case(Rule::PropertyWithParameters, Path::new("property_with_parameters.py"); "PLR0206")]
#[test_case(Rule::ConsiderUsingFromImport, Path::new("import_aliasing.py"); "PLR0402")]
#[test_case(Rule::ConsiderMergingIsinstance, Path::new("consider_merging_isinstance.py"); "PLR1701")]
#[test_case(Rule::UseSysExit, Path::new("consider_using_sys_exit_0.py"); "PLR1722_0")]
#[test_case(Rule::UseSysExit, Path::new("consider_using_sys_exit_1.py"); "PLR1722_1")]
#[test_case(Rule::UseSysExit, Path::new("consider_using_sys_exit_2.py"); "PLR1722_2")]
#[test_case(Rule::UseSysExit, Path::new("consider_using_sys_exit_3.py"); "PLR1722_3")]
#[test_case(Rule::UseSysExit, Path::new("consider_using_sys_exit_4.py"); "PLR1722_4")]
#[test_case(Rule::UseSysExit, Path::new("consider_using_sys_exit_5.py"); "PLR1722_5")]
#[test_case(Rule::UseSysExit, Path::new("consider_using_sys_exit_6.py"); "PLR1722_6")]
#[test_case(Rule::MagicValueComparison, Path::new("magic_value_comparison.py"); "PLR2004")]
#[test_case(Rule::UselessElseOnLoop, Path::new("useless_else_on_loop.py"); "PLW0120")]
#[test_case(Rule::GlobalVariableNotAssigned, Path::new("global_variable_not_assigned.py"); "PLW0602")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/pylint")
@ -53,7 +53,7 @@ mod tests {
pylint: pylint::settings::Settings {
allow_magic_value_types: vec![pylint::settings::ConstantType::Int],
},
..Settings::for_rules(vec![RuleCode::PLR2004])
..Settings::for_rules(vec![Rule::MagicValueComparison])
},
)?;
insta::assert_yaml_snapshot!(diagnostics);

View File

@ -12,49 +12,49 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
use crate::settings::types::PythonVersion;
#[test_case(RuleCode::UP001, Path::new("UP001.py"); "UP001")]
#[test_case(RuleCode::UP003, Path::new("UP003.py"); "UP003")]
#[test_case(RuleCode::UP004, Path::new("UP004.py"); "UP004")]
#[test_case(RuleCode::UP005, Path::new("UP005.py"); "UP005")]
#[test_case(RuleCode::UP006, Path::new("UP006.py"); "UP006")]
#[test_case(RuleCode::UP007, Path::new("UP007.py"); "UP007")]
#[test_case(RuleCode::UP008, Path::new("UP008.py"); "UP008")]
#[test_case(RuleCode::UP009, Path::new("UP009_0.py"); "UP009_0")]
#[test_case(RuleCode::UP009, Path::new("UP009_1.py"); "UP009_1")]
#[test_case(RuleCode::UP009, Path::new("UP009_2.py"); "UP009_2")]
#[test_case(RuleCode::UP009, Path::new("UP009_3.py"); "UP009_3")]
#[test_case(RuleCode::UP009, Path::new("UP009_4.py"); "UP009_4")]
#[test_case(RuleCode::UP010, Path::new("UP010.py"); "UP010")]
#[test_case(RuleCode::UP011, Path::new("UP011.py"); "UP011")]
#[test_case(RuleCode::UP012, Path::new("UP012.py"); "UP012")]
#[test_case(RuleCode::UP013, Path::new("UP013.py"); "UP013")]
#[test_case(RuleCode::UP014, Path::new("UP014.py"); "UP014")]
#[test_case(RuleCode::UP015, Path::new("UP015.py"); "UP015")]
#[test_case(RuleCode::UP016, Path::new("UP016.py"); "UP016")]
#[test_case(RuleCode::UP018, Path::new("UP018.py"); "UP018")]
#[test_case(RuleCode::UP019, Path::new("UP019.py"); "UP019")]
#[test_case(RuleCode::UP021, Path::new("UP021.py"); "UP021")]
#[test_case(RuleCode::UP022, Path::new("UP022.py"); "UP022")]
#[test_case(RuleCode::UP023, Path::new("UP023.py"); "UP023")]
#[test_case(RuleCode::UP024, Path::new("UP024_0.py"); "UP024_0")]
#[test_case(RuleCode::UP024, Path::new("UP024_1.py"); "UP024_1")]
#[test_case(RuleCode::UP024, Path::new("UP024_2.py"); "UP024_2")]
#[test_case(RuleCode::UP024, Path::new("UP024_3.py"); "UP024_3")]
#[test_case(RuleCode::UP025, Path::new("UP025.py"); "UP025")]
#[test_case(RuleCode::UP026, Path::new("UP026.py"); "UP026")]
#[test_case(RuleCode::UP027, Path::new("UP027.py"); "UP027")]
#[test_case(RuleCode::UP028, Path::new("UP028_0.py"); "UP028_0")]
#[test_case(RuleCode::UP028, Path::new("UP028_1.py"); "UP028_1")]
#[test_case(RuleCode::UP029, Path::new("UP029.py"); "UP029")]
#[test_case(RuleCode::UP030, Path::new("UP030_0.py"); "UP030_0")]
#[test_case(RuleCode::UP030, Path::new("UP030_1.py"); "UP030_1")]
#[test_case(RuleCode::UP032, Path::new("UP032.py"); "UP032")]
#[test_case(RuleCode::UP033, Path::new("UP033.py"); "UP033")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::UselessMetaclassType, Path::new("UP001.py"); "UP001")]
#[test_case(Rule::TypeOfPrimitive, Path::new("UP003.py"); "UP003")]
#[test_case(Rule::UselessObjectInheritance, Path::new("UP004.py"); "UP004")]
#[test_case(Rule::DeprecatedUnittestAlias, Path::new("UP005.py"); "UP005")]
#[test_case(Rule::UsePEP585Annotation, Path::new("UP006.py"); "UP006")]
#[test_case(Rule::UsePEP604Annotation, Path::new("UP007.py"); "UP007")]
#[test_case(Rule::SuperCallWithParameters, Path::new("UP008.py"); "UP008")]
#[test_case(Rule::PEP3120UnnecessaryCodingComment, Path::new("UP009_0.py"); "UP009_0")]
#[test_case(Rule::PEP3120UnnecessaryCodingComment, Path::new("UP009_1.py"); "UP009_1")]
#[test_case(Rule::PEP3120UnnecessaryCodingComment, Path::new("UP009_2.py"); "UP009_2")]
#[test_case(Rule::PEP3120UnnecessaryCodingComment, Path::new("UP009_3.py"); "UP009_3")]
#[test_case(Rule::PEP3120UnnecessaryCodingComment, Path::new("UP009_4.py"); "UP009_4")]
#[test_case(Rule::UnnecessaryFutureImport, Path::new("UP010.py"); "UP010")]
#[test_case(Rule::LRUCacheWithoutParameters, Path::new("UP011.py"); "UP011")]
#[test_case(Rule::UnnecessaryEncodeUTF8, Path::new("UP012.py"); "UP012")]
#[test_case(Rule::ConvertTypedDictFunctionalToClass, Path::new("UP013.py"); "UP013")]
#[test_case(Rule::ConvertNamedTupleFunctionalToClass, Path::new("UP014.py"); "UP014")]
#[test_case(Rule::RedundantOpenModes, Path::new("UP015.py"); "UP015")]
#[test_case(Rule::RemoveSixCompat, Path::new("UP016.py"); "UP016")]
#[test_case(Rule::NativeLiterals, Path::new("UP018.py"); "UP018")]
#[test_case(Rule::TypingTextStrAlias, Path::new("UP019.py"); "UP019")]
#[test_case(Rule::ReplaceUniversalNewlines, Path::new("UP021.py"); "UP021")]
#[test_case(Rule::ReplaceStdoutStderr, Path::new("UP022.py"); "UP022")]
#[test_case(Rule::RewriteCElementTree, Path::new("UP023.py"); "UP023")]
#[test_case(Rule::OSErrorAlias, Path::new("UP024_0.py"); "UP024_0")]
#[test_case(Rule::OSErrorAlias, Path::new("UP024_1.py"); "UP024_1")]
#[test_case(Rule::OSErrorAlias, Path::new("UP024_2.py"); "UP024_2")]
#[test_case(Rule::OSErrorAlias, Path::new("UP024_3.py"); "UP024_3")]
#[test_case(Rule::RewriteUnicodeLiteral, Path::new("UP025.py"); "UP025")]
#[test_case(Rule::RewriteMockImport, Path::new("UP026.py"); "UP026")]
#[test_case(Rule::RewriteListComprehension, Path::new("UP027.py"); "UP027")]
#[test_case(Rule::RewriteYieldFrom, Path::new("UP028_0.py"); "UP028_0")]
#[test_case(Rule::RewriteYieldFrom, Path::new("UP028_1.py"); "UP028_1")]
#[test_case(Rule::UnnecessaryBuiltinImport, Path::new("UP029.py"); "UP029")]
#[test_case(Rule::FormatLiterals, Path::new("UP030_0.py"); "UP030_0")]
#[test_case(Rule::FormatLiterals, Path::new("UP030_1.py"); "UP030_1")]
#[test_case(Rule::FString, Path::new("UP032.py"); "UP032")]
#[test_case(Rule::FunctoolsCache, Path::new("UP033.py"); "UP033")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/pyupgrade")
@ -72,7 +72,7 @@ mod tests {
Path::new("./resources/test/fixtures/pyupgrade/future_annotations.py"),
&settings::Settings {
target_version: PythonVersion::Py37,
..settings::Settings::for_rule(RuleCode::UP006)
..settings::Settings::for_rule(Rule::UsePEP585Annotation)
},
)?;
insta::assert_yaml_snapshot!(diagnostics);
@ -85,7 +85,7 @@ mod tests {
Path::new("./resources/test/fixtures/pyupgrade/future_annotations.py"),
&settings::Settings {
target_version: PythonVersion::Py310,
..settings::Settings::for_rule(RuleCode::UP006)
..settings::Settings::for_rule(Rule::UsePEP585Annotation)
},
)?;
insta::assert_yaml_snapshot!(diagnostics);
@ -98,7 +98,7 @@ mod tests {
Path::new("./resources/test/fixtures/pyupgrade/future_annotations.py"),
&settings::Settings {
target_version: PythonVersion::Py37,
..settings::Settings::for_rule(RuleCode::UP007)
..settings::Settings::for_rule(Rule::UsePEP604Annotation)
},
)?;
insta::assert_yaml_snapshot!(diagnostics);
@ -111,7 +111,7 @@ mod tests {
Path::new("./resources/test/fixtures/pyupgrade/future_annotations.py"),
&settings::Settings {
target_version: PythonVersion::Py310,
..settings::Settings::for_rule(RuleCode::UP007)
..settings::Settings::for_rule(Rule::UsePEP604Annotation)
},
)?;
insta::assert_yaml_snapshot!(diagnostics);
@ -124,7 +124,7 @@ mod tests {
Path::new("./resources/test/fixtures/pyupgrade/UP017.py"),
&settings::Settings {
target_version: PythonVersion::Py311,
..settings::Settings::for_rule(RuleCode::UP017)
..settings::Settings::for_rule(Rule::DatetimeTimezoneUTC)
},
)?;
insta::assert_yaml_snapshot!(diagnostics);

View File

@ -4,7 +4,7 @@ use crate::ast::helpers::collect_call_path;
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
/// UP017
@ -17,7 +17,7 @@ pub fn datetime_utc_alias(checker: &mut Checker, expr: &Expr) {
violations::DatetimeTimezoneUTC { straight_import },
Range::from_located(expr),
);
if checker.patch(&RuleCode::UP017) {
if checker.patch(&Rule::DatetimeTimezoneUTC) {
if straight_import {
diagnostic.amend(Fix::replacement(
"datetime.UTC".to_string(),

View File

@ -9,7 +9,7 @@ use rustpython_parser::lexer::Tok;
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::rules::pydocstyle::helpers::{leading_quote, trailing_quote};
use crate::rules::pyflakes::format::FormatSummary;
use crate::violations;
@ -263,7 +263,7 @@ pub(crate) fn f_strings(checker: &mut Checker, summary: &FormatSummary, expr: &E
}
let mut diagnostic = Diagnostic::new(violations::FString, Range::from_located(expr));
if checker.patch(&RuleCode::UP032) {
if checker.patch(&Rule::FString) {
diagnostic.amend(Fix::replacement(
contents,
expr.location,

View File

@ -5,7 +5,7 @@ use crate::ast::helpers::{create_expr, unparse_expr};
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
/// UP033
@ -40,7 +40,7 @@ pub fn functools_cache(checker: &mut Checker, decorator_list: &[Expr]) {
violations::FunctoolsCache,
Range::new(func.end_location.unwrap(), expr.end_location.unwrap()),
);
if checker.patch(&RuleCode::UP033) {
if checker.patch(&Rule::FunctoolsCache) {
if let ExprKind::Attribute { value, ctx, .. } = &func.node {
diagnostic.amend(Fix::replacement(
unparse_expr(

View File

@ -5,7 +5,7 @@ use crate::ast::helpers::unparse_expr;
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
/// UP011
@ -30,7 +30,7 @@ pub fn lru_cache_without_parameters(checker: &mut Checker, decorator_list: &[Exp
violations::LRUCacheWithoutParameters,
Range::new(func.end_location.unwrap(), expr.end_location.unwrap()),
);
if checker.patch(&RuleCode::UP011) {
if checker.patch(&Rule::LRUCacheWithoutParameters) {
diagnostic.amend(Fix::replacement(
unparse_expr(func, checker.stylist),
expr.location,

View File

@ -5,7 +5,7 @@ use rustpython_parser::lexer::Tok;
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
use crate::violations::LiteralType;
@ -30,7 +30,7 @@ pub fn native_literals(
} else {
LiteralType::Bytes
}), Range::from_located(expr));
if checker.patch(&RuleCode::UP018) {
if checker.patch(&Rule::NativeLiterals) {
diagnostic.amend(Fix::replacement(
if id == "bytes" {
let mut content = String::with_capacity(3);
@ -101,7 +101,7 @@ pub fn native_literals(
}),
Range::from_located(expr),
);
if checker.patch(&RuleCode::UP018) {
if checker.patch(&Rule::NativeLiterals) {
diagnostic.amend(Fix::replacement(
arg_code.to_string(),
expr.location,

View File

@ -3,7 +3,7 @@ use rustpython_ast::Expr;
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
/// UP020
@ -13,7 +13,7 @@ pub fn open_alias(checker: &mut Checker, expr: &Expr, func: &Expr) {
.map_or(false, |call_path| call_path.as_slice() == ["io", "open"])
{
let mut diagnostic = Diagnostic::new(violations::OpenAlias, Range::from_located(expr));
if checker.patch(&RuleCode::UP020) {
if checker.patch(&Rule::OpenAlias) {
diagnostic.amend(Fix::replacement(
"open".to_string(),
func.location,

View File

@ -10,7 +10,7 @@ use crate::ast::helpers::find_keyword;
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::source_code::Locator;
use crate::violations;
@ -164,7 +164,7 @@ pub fn redundant_open_modes(checker: &mut Checker, expr: &Expr) {
&keyword.node.value,
mode.replacement_value(),
checker.locator,
checker.patch(&RuleCode::UP015),
checker.patch(&Rule::RedundantOpenModes),
));
}
}
@ -181,7 +181,7 @@ pub fn redundant_open_modes(checker: &mut Checker, expr: &Expr) {
mode_param,
mode.replacement_value(),
checker.locator,
checker.patch(&RuleCode::UP015),
checker.patch(&Rule::RedundantOpenModes),
));
}
}

View File

@ -4,7 +4,7 @@ use crate::ast::helpers::{create_expr, create_stmt};
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::source_code::{Generator, Locator, Stylist};
use crate::violations;
@ -405,7 +405,7 @@ fn handle_next_on_six_dict(expr: &Expr, patch: bool, checker: &Checker) -> Optio
/// UP016
pub fn remove_six_compat(checker: &mut Checker, expr: &Expr) {
if let Some(diagnostic) =
handle_next_on_six_dict(expr, checker.patch(&RuleCode::UP016), checker)
handle_next_on_six_dict(expr, checker.patch(&Rule::RemoveSixCompat), checker)
{
checker.diagnostics.push(diagnostic);
return;
@ -415,7 +415,7 @@ pub fn remove_six_compat(checker: &mut Checker, expr: &Expr) {
.resolve_call_path(expr)
.map_or(false, |call_path| is_module_member(&call_path, "six"))
{
let patch = checker.patch(&RuleCode::UP016);
let patch = checker.patch(&Rule::RemoveSixCompat);
let diagnostic = match &expr.node {
ExprKind::Call {
func,

View File

@ -12,7 +12,7 @@ use crate::ast::whitespace::indentation;
use crate::checkers::ast::Checker;
use crate::cst::matchers::{match_import, match_import_from, match_module};
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::source_code::{Locator, Stylist};
use crate::violations;
use crate::violations::MockReference;
@ -204,7 +204,7 @@ pub fn rewrite_mock_attribute(checker: &mut Checker, expr: &Expr) {
violations::RewriteMockImport(MockReference::Attribute),
Range::from_located(value),
);
if checker.patch(&RuleCode::UP026) {
if checker.patch(&Rule::RewriteMockImport) {
diagnostic.amend(Fix::replacement(
"mock".to_string(),
value.location,
@ -226,7 +226,7 @@ pub fn rewrite_mock_import(checker: &mut Checker, stmt: &Stmt) {
.any(|name| name.node.name == "mock" || name.node.name == "mock.mock")
{
// Generate the fix, if needed, which is shared between all `mock` imports.
let content = if checker.patch(&RuleCode::UP026) {
let content = if checker.patch(&Rule::RewriteMockImport) {
if let Some(indent) = indentation(checker.locator, stmt) {
match format_import(stmt, &indent, checker.locator, checker.stylist) {
Ok(content) => Some(content),
@ -275,7 +275,7 @@ pub fn rewrite_mock_import(checker: &mut Checker, stmt: &Stmt) {
violations::RewriteMockImport(MockReference::Import),
Range::from_located(stmt),
);
if checker.patch(&RuleCode::UP026) {
if checker.patch(&Rule::RewriteMockImport) {
if let Some(indent) = indentation(checker.locator, stmt) {
match format_import_from(stmt, &indent, checker.locator, checker.stylist) {
Ok(content) => {

View File

@ -3,7 +3,7 @@ use rustpython_ast::{Constant, Expr, ExprKind, Keyword};
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::source_code::Locator;
use crate::violations;
@ -130,7 +130,7 @@ pub fn unnecessary_encode_utf8(
expr,
variable,
checker.locator,
checker.patch(&RuleCode::UP012),
checker.patch(&Rule::UnnecessaryEncodeUTF8),
));
} else {
// "unicode text©".encode("utf-8")
@ -138,7 +138,7 @@ pub fn unnecessary_encode_utf8(
expr,
args,
kwargs,
checker.patch(&RuleCode::UP012),
checker.patch(&Rule::UnnecessaryEncodeUTF8),
) {
checker.diagnostics.push(diagnostic);
}
@ -152,7 +152,7 @@ pub fn unnecessary_encode_utf8(
expr,
args,
kwargs,
checker.patch(&RuleCode::UP012),
checker.patch(&Rule::UnnecessaryEncodeUTF8),
) {
checker.diagnostics.push(diagnostic);
}

View File

@ -3,7 +3,7 @@ use rustpython_ast::{Expr, ExprKind};
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::fix::Fix;
use crate::registry::{Diagnostic, RuleCode};
use crate::registry::{Diagnostic, Rule};
use crate::violations;
/// Returns `true` if `expr` contains an `ExprKind::Await`.
@ -79,7 +79,7 @@ pub fn unpack_list_comprehension(checker: &mut Checker, targets: &[Expr], value:
violations::RewriteListComprehension,
Range::from_located(value),
);
if checker.patch(&RuleCode::UP027) {
if checker.patch(&Rule::RewriteListComprehension) {
let existing = checker
.locator
.slice_source_code_range(&Range::from_located(value));

View File

@ -11,10 +11,10 @@ mod tests {
use test_case::test_case;
use crate::linter::test_path;
use crate::registry::RuleCode;
use crate::registry::Rule;
use crate::settings;
#[test_case(RuleCode::RUF004, Path::new("RUF004.py"); "RUF004")]
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
#[test_case(Rule::KeywordArgumentBeforeStarArgument, Path::new("RUF004.py"); "RUF004")]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("./resources/test/fixtures/ruff")
@ -33,9 +33,9 @@ mod tests {
&settings::Settings {
allowed_confusables: FxHashSet::from_iter(['', 'ρ', '']).into(),
..settings::Settings::for_rules(vec![
RuleCode::RUF001,
RuleCode::RUF002,
RuleCode::RUF003,
Rule::AmbiguousUnicodeCharacterString,
Rule::AmbiguousUnicodeCharacterDocstring,
Rule::AmbiguousUnicodeCharacterComment,
])
},
)?;
@ -48,10 +48,10 @@ mod tests {
let diagnostics = test_path(
Path::new("./resources/test/fixtures/ruff/RUF100_0.py"),
&settings::Settings::for_rules(vec![
RuleCode::RUF100,
RuleCode::E501,
RuleCode::F401,
RuleCode::F841,
Rule::UnusedNOQA,
Rule::LineTooLong,
Rule::UnusedImport,
Rule::UnusedVariable,
]),
)?;
insta::assert_yaml_snapshot!(diagnostics);
@ -62,7 +62,7 @@ mod tests {
fn ruf100_1() -> Result<()> {
let diagnostics = test_path(
Path::new("./resources/test/fixtures/ruff/RUF100_1.py"),
&settings::Settings::for_rules(vec![RuleCode::RUF100, RuleCode::F401]),
&settings::Settings::for_rules(vec![Rule::UnusedNOQA, Rule::UnusedImport]),
)?;
insta::assert_yaml_snapshot!(diagnostics);
Ok(())
@ -72,7 +72,7 @@ mod tests {
fn flake8_noqa() -> Result<()> {
let diagnostics = test_path(
Path::new("./resources/test/fixtures/ruff/flake8_noqa.py"),
&settings::Settings::for_rules(vec![RuleCode::F401, RuleCode::F841]),
&settings::Settings::for_rules(vec![Rule::UnusedImport, Rule::UnusedVariable]),
)?;
insta::assert_yaml_snapshot!(diagnostics);
Ok(())
@ -82,7 +82,7 @@ mod tests {
fn ruff_noqa() -> Result<()> {
let diagnostics = test_path(
Path::new("./resources/test/fixtures/ruff/ruff_noqa.py"),
&settings::Settings::for_rules(vec![RuleCode::F401, RuleCode::F841]),
&settings::Settings::for_rules(vec![Rule::UnusedImport, Rule::UnusedVariable]),
)?;
insta::assert_yaml_snapshot!(diagnostics);
Ok(())
@ -92,7 +92,7 @@ mod tests {
fn redirects() -> Result<()> {
let diagnostics = test_path(
Path::new("./resources/test/fixtures/ruff/redirects.py"),
&settings::Settings::for_rules(vec![RuleCode::UP007]),
&settings::Settings::for_rules(vec![Rule::UsePEP604Annotation]),
)?;
insta::assert_yaml_snapshot!(diagnostics);
Ok(())

View File

@ -14,7 +14,7 @@ use rustc_hash::FxHashSet;
use self::hashable::{HashableGlobMatcher, HashableGlobSet, HashableHashSet, HashableRegex};
use self::rule_table::RuleTable;
use crate::cache::cache_dir;
use crate::registry::{RuleCode, RuleCodePrefix, SuffixLength, CATEGORIES, INCOMPATIBLE_CODES};
use crate::registry::{Rule, RuleCodePrefix, SuffixLength, CATEGORIES, INCOMPATIBLE_CODES};
use crate::rules::{
flake8_annotations, flake8_bandit, flake8_bugbear, flake8_errmsg, flake8_import_conventions,
flake8_pytest_style, flake8_quotes, flake8_tidy_imports, flake8_unused_arguments, isort,
@ -78,7 +78,7 @@ pub struct Settings {
pub per_file_ignores: Vec<(
HashableGlobMatcher,
HashableGlobMatcher,
HashableHashSet<RuleCode>,
HashableHashSet<Rule>,
)>,
pub show_source: bool,
@ -207,7 +207,7 @@ impl Settings {
}
#[cfg(test)]
pub fn for_rule(rule_code: RuleCode) -> Self {
pub fn for_rule(rule_code: Rule) -> Self {
Self {
rules: [rule_code].into(),
..Settings::default()
@ -215,7 +215,7 @@ impl Settings {
}
#[cfg(test)]
pub fn for_rules(rule_codes: Vec<RuleCode>) -> Self {
pub fn for_rules(rule_codes: Vec<Rule>) -> Self {
Self {
rules: rule_codes.into(),
..Settings::default()
@ -293,7 +293,7 @@ pub fn resolve_per_file_ignores(
Vec<(
HashableGlobMatcher,
HashableGlobMatcher,
HashableHashSet<RuleCode>,
HashableHashSet<Rule>,
)>,
> {
per_file_ignores
@ -319,8 +319,8 @@ struct RuleCodeSpec<'a> {
/// Given a set of selected and ignored prefixes, resolve the set of enabled
/// rule codes.
fn resolve_codes<'a>(specs: impl IntoIterator<Item = RuleCodeSpec<'a>>) -> FxHashSet<RuleCode> {
let mut codes: FxHashSet<RuleCode> = FxHashSet::default();
fn resolve_codes<'a>(specs: impl IntoIterator<Item = RuleCodeSpec<'a>>) -> FxHashSet<Rule> {
let mut codes: FxHashSet<Rule> = FxHashSet::default();
for spec in specs {
for specificity in [
SuffixLength::None,
@ -348,7 +348,7 @@ fn resolve_codes<'a>(specs: impl IntoIterator<Item = RuleCodeSpec<'a>>) -> FxHas
}
/// Warn if the set of enabled codes contains any incompatibilities.
fn validate_enabled(enabled: FxHashSet<RuleCode>) -> FxHashSet<RuleCode> {
fn validate_enabled(enabled: FxHashSet<Rule>) -> FxHashSet<Rule> {
for (a, b, message) in INCOMPATIBLE_CODES {
if enabled.contains(a) && enabled.contains(b) {
warn_user_once!("{}", message);
@ -361,7 +361,7 @@ fn validate_enabled(enabled: FxHashSet<RuleCode>) -> FxHashSet<RuleCode> {
mod tests {
use rustc_hash::FxHashSet;
use crate::registry::{RuleCode, RuleCodePrefix};
use crate::registry::{Rule, RuleCodePrefix};
use crate::settings::{resolve_codes, RuleCodeSpec};
#[test]
@ -370,21 +370,25 @@ mod tests {
select: &[RuleCodePrefix::W],
ignore: &[],
}]);
let expected = FxHashSet::from_iter([RuleCode::W292, RuleCode::W505, RuleCode::W605]);
let expected = FxHashSet::from_iter([
Rule::NoNewLineAtEndOfFile,
Rule::DocLineTooLong,
Rule::InvalidEscapeSequence,
]);
assert_eq!(actual, expected);
let actual = resolve_codes([RuleCodeSpec {
select: &[RuleCodePrefix::W6],
ignore: &[],
}]);
let expected = FxHashSet::from_iter([RuleCode::W605]);
let expected = FxHashSet::from_iter([Rule::InvalidEscapeSequence]);
assert_eq!(actual, expected);
let actual = resolve_codes([RuleCodeSpec {
select: &[RuleCodePrefix::W],
ignore: &[RuleCodePrefix::W292],
}]);
let expected = FxHashSet::from_iter([RuleCode::W505, RuleCode::W605]);
let expected = FxHashSet::from_iter([Rule::DocLineTooLong, Rule::InvalidEscapeSequence]);
assert_eq!(actual, expected);
let actual = resolve_codes([RuleCodeSpec {
@ -404,7 +408,11 @@ mod tests {
ignore: &[],
},
]);
let expected = FxHashSet::from_iter([RuleCode::W292, RuleCode::W505, RuleCode::W605]);
let expected = FxHashSet::from_iter([
Rule::NoNewLineAtEndOfFile,
Rule::DocLineTooLong,
Rule::InvalidEscapeSequence,
]);
assert_eq!(actual, expected);
let actual = resolve_codes([
@ -417,7 +425,7 @@ mod tests {
ignore: &[RuleCodePrefix::W],
},
]);
let expected = FxHashSet::from_iter([RuleCode::W292]);
let expected = FxHashSet::from_iter([Rule::NoNewLineAtEndOfFile]);
assert_eq!(actual, expected);
}
}

View File

@ -3,14 +3,14 @@ use std::collections::hash_map;
use rustc_hash::FxHashMap;
use super::hashable::HashableHashMap;
use crate::registry::RuleCode;
use crate::registry::Rule;
/// A table to keep track of which rules are enabled
/// and whether or not they should be autofixed.
#[derive(Debug, Hash)]
pub struct RuleTable {
/// Maps rule codes to a boolean indicating if the rule should be autofixed.
enabled: HashableHashMap<RuleCode, bool>,
enabled: HashableHashMap<Rule, bool>,
}
impl RuleTable {
@ -22,27 +22,27 @@ impl RuleTable {
}
/// Returns whether the given rule should be checked.
pub fn enabled(&self, code: &RuleCode) -> bool {
pub fn enabled(&self, code: &Rule) -> bool {
self.enabled.contains_key(code)
}
/// Returns whether violations of the given rule should be autofixed.
pub fn should_fix(&self, code: &RuleCode) -> bool {
pub fn should_fix(&self, code: &Rule) -> bool {
*self.enabled.get(code).unwrap_or(&false)
}
/// Returns an iterator over all enabled rules.
pub fn iter_enabled(&self) -> hash_map::Keys<RuleCode, bool> {
pub fn iter_enabled(&self) -> hash_map::Keys<Rule, bool> {
self.enabled.keys()
}
/// Enables the given rule.
pub fn enable(&mut self, code: RuleCode, should_fix: bool) {
pub fn enable(&mut self, code: Rule, should_fix: bool) {
self.enabled.insert(code, should_fix);
}
}
impl<I: IntoIterator<Item = RuleCode>> From<I> for RuleTable {
impl<I: IntoIterator<Item = Rule>> From<I> for RuleTable {
fn from(codes: I) -> Self {
let mut enabled = FxHashMap::default();
for code in codes {

View File

@ -12,7 +12,7 @@ use serde::{de, Deserialize, Deserializer, Serialize};
use super::hashable::HashableHashSet;
use crate::fs;
use crate::registry::{RuleCode, RuleCodePrefix};
use crate::registry::{Rule, RuleCodePrefix};
#[derive(
Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize, Hash, JsonSchema,
@ -89,7 +89,7 @@ impl FromStr for FilePattern {
pub struct PerFileIgnore {
pub basename: String,
pub absolute: PathBuf,
pub codes: HashableHashSet<RuleCode>,
pub codes: HashableHashSet<Rule>,
}
impl PerFileIgnore {