mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 18:28:24 +00:00
Move flake8-simplify violations to rule modules (#2495)
This commit is contained in:
parent
335395adec
commit
77716108af
15 changed files with 560 additions and 529 deletions
|
@ -198,31 +198,31 @@ ruff_macros::define_rule_mapping!(
|
|||
YTT302 => violations::SysVersionCmpStr10,
|
||||
YTT303 => violations::SysVersionSlice1Referenced,
|
||||
// flake8-simplify
|
||||
SIM115 => violations::OpenFileWithContextHandler,
|
||||
SIM101 => violations::DuplicateIsinstanceCall,
|
||||
SIM102 => violations::NestedIfStatements,
|
||||
SIM103 => violations::ReturnBoolConditionDirectly,
|
||||
SIM105 => violations::UseContextlibSuppress,
|
||||
SIM107 => violations::ReturnInTryExceptFinally,
|
||||
SIM108 => violations::UseTernaryOperator,
|
||||
SIM109 => violations::CompareWithTuple,
|
||||
SIM110 => violations::ConvertLoopToAny,
|
||||
SIM111 => violations::ConvertLoopToAll,
|
||||
SIM112 => violations::UseCapitalEnvironmentVariables,
|
||||
SIM117 => violations::MultipleWithStatements,
|
||||
SIM118 => violations::KeyInDict,
|
||||
SIM201 => violations::NegateEqualOp,
|
||||
SIM202 => violations::NegateNotEqualOp,
|
||||
SIM208 => violations::DoubleNegation,
|
||||
SIM210 => violations::IfExprWithTrueFalse,
|
||||
SIM211 => violations::IfExprWithFalseTrue,
|
||||
SIM212 => violations::IfExprWithTwistedArms,
|
||||
SIM220 => violations::AAndNotA,
|
||||
SIM221 => violations::AOrNotA,
|
||||
SIM222 => violations::OrTrue,
|
||||
SIM223 => violations::AndFalse,
|
||||
SIM300 => violations::YodaConditions,
|
||||
SIM401 => violations::DictGetWithDefault,
|
||||
SIM115 => rules::flake8_simplify::rules::OpenFileWithContextHandler,
|
||||
SIM101 => rules::flake8_simplify::rules::DuplicateIsinstanceCall,
|
||||
SIM102 => rules::flake8_simplify::rules::NestedIfStatements,
|
||||
SIM103 => rules::flake8_simplify::rules::ReturnBoolConditionDirectly,
|
||||
SIM105 => rules::flake8_simplify::rules::UseContextlibSuppress,
|
||||
SIM107 => rules::flake8_simplify::rules::ReturnInTryExceptFinally,
|
||||
SIM108 => rules::flake8_simplify::rules::UseTernaryOperator,
|
||||
SIM109 => rules::flake8_simplify::rules::CompareWithTuple,
|
||||
SIM110 => rules::flake8_simplify::rules::ConvertLoopToAny,
|
||||
SIM111 => rules::flake8_simplify::rules::ConvertLoopToAll,
|
||||
SIM112 => rules::flake8_simplify::rules::UseCapitalEnvironmentVariables,
|
||||
SIM117 => rules::flake8_simplify::rules::MultipleWithStatements,
|
||||
SIM118 => rules::flake8_simplify::rules::KeyInDict,
|
||||
SIM201 => rules::flake8_simplify::rules::NegateEqualOp,
|
||||
SIM202 => rules::flake8_simplify::rules::NegateNotEqualOp,
|
||||
SIM208 => rules::flake8_simplify::rules::DoubleNegation,
|
||||
SIM210 => rules::flake8_simplify::rules::IfExprWithTrueFalse,
|
||||
SIM211 => rules::flake8_simplify::rules::IfExprWithFalseTrue,
|
||||
SIM212 => rules::flake8_simplify::rules::IfExprWithTwistedArms,
|
||||
SIM220 => rules::flake8_simplify::rules::AAndNotA,
|
||||
SIM221 => rules::flake8_simplify::rules::AOrNotA,
|
||||
SIM222 => rules::flake8_simplify::rules::OrTrue,
|
||||
SIM223 => rules::flake8_simplify::rules::AndFalse,
|
||||
SIM300 => rules::flake8_simplify::rules::YodaConditions,
|
||||
SIM401 => rules::flake8_simplify::rules::DictGetWithDefault,
|
||||
// pyupgrade
|
||||
UP001 => rules::pyupgrade::rules::UselessMetaclassType,
|
||||
UP003 => rules::pyupgrade::rules::TypeOfPrimitive,
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::iter;
|
||||
|
||||
|
@ -9,7 +13,104 @@ use crate::ast::types::Range;
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct DuplicateIsinstanceCall {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for DuplicateIsinstanceCall {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let DuplicateIsinstanceCall { name } = self;
|
||||
format!("Multiple `isinstance` calls for `{name}`, merge into a single call")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let DuplicateIsinstanceCall { name } = self;
|
||||
format!("Merge `isinstance` calls for `{name}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct CompareWithTuple {
|
||||
pub replacement: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for CompareWithTuple {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let CompareWithTuple { replacement } = self;
|
||||
format!("Use `{replacement}` instead of multiple equality comparisons")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let CompareWithTuple { replacement, .. } = self;
|
||||
format!("Replace with `{replacement}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct AAndNotA {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for AAndNotA {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let AAndNotA { name } = self;
|
||||
format!("Use `False` instead of `{name} and not {name}`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Replace with `False`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct AOrNotA {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for AOrNotA {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let AOrNotA { name } = self;
|
||||
format!("Use `True` instead of `{name} or not {name}`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Replace with `True`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct OrTrue;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for OrTrue {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Use `True` instead of `... or True`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Replace with `True`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct AndFalse;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for AndFalse {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Use `False` instead of `... and False`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Replace with `False`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// Return `true` if two `Expr` instances are equivalent names.
|
||||
fn is_same_expr<'a>(a: &'a Expr, b: &'a Expr) -> Option<&'a str> {
|
||||
|
@ -65,7 +166,7 @@ pub fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
|
|||
for (arg_name, indices) in duplicates {
|
||||
if indices.len() > 1 {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::DuplicateIsinstanceCall {
|
||||
DuplicateIsinstanceCall {
|
||||
name: arg_name.to_string(),
|
||||
},
|
||||
Range::from_located(expr),
|
||||
|
@ -211,7 +312,7 @@ pub fn compare_with_tuple(checker: &mut Checker, expr: &Expr) {
|
|||
})],
|
||||
});
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::CompareWithTuple {
|
||||
CompareWithTuple {
|
||||
replacement: unparse_expr(&in_expr, checker.stylist),
|
||||
},
|
||||
Range::from_located(expr),
|
||||
|
@ -278,7 +379,7 @@ pub fn a_and_not_a(checker: &mut Checker, expr: &Expr) {
|
|||
for non_negate_expr in &non_negated_expr {
|
||||
if let Some(id) = is_same_expr(negate_expr, non_negate_expr) {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::AAndNotA {
|
||||
AAndNotA {
|
||||
name: id.to_string(),
|
||||
},
|
||||
Range::from_located(expr),
|
||||
|
@ -332,7 +433,7 @@ pub fn a_or_not_a(checker: &mut Checker, expr: &Expr) {
|
|||
for non_negate_expr in &non_negated_expr {
|
||||
if let Some(id) = is_same_expr(negate_expr, non_negate_expr) {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::AOrNotA {
|
||||
AOrNotA {
|
||||
name: id.to_string(),
|
||||
},
|
||||
Range::from_located(expr),
|
||||
|
@ -364,7 +465,7 @@ pub fn or_true(checker: &mut Checker, expr: &Expr) {
|
|||
..
|
||||
} = &value.node
|
||||
{
|
||||
let mut diagnostic = Diagnostic::new(violations::OrTrue, Range::from_located(value));
|
||||
let mut diagnostic = Diagnostic::new(OrTrue, Range::from_located(value));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.amend(Fix::replacement(
|
||||
"True".to_string(),
|
||||
|
@ -391,7 +492,7 @@ pub fn and_false(checker: &mut Checker, expr: &Expr) {
|
|||
..
|
||||
} = &value.node
|
||||
{
|
||||
let mut diagnostic = Diagnostic::new(violations::AndFalse, Range::from_located(value));
|
||||
let mut diagnostic = Diagnostic::new(AndFalse, Range::from_located(value));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.amend(Fix::replacement(
|
||||
"False".to_string(),
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Constant, Expr, ExprKind};
|
||||
|
||||
use crate::ast::helpers::{create_expr, unparse_expr};
|
||||
|
@ -5,7 +8,25 @@ use crate::ast::types::Range;
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct UseCapitalEnvironmentVariables {
|
||||
pub expected: String,
|
||||
pub original: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for UseCapitalEnvironmentVariables {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let UseCapitalEnvironmentVariables { expected, original } = self;
|
||||
format!("Use capitalized environment variable `{expected}` instead of `{original}`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let UseCapitalEnvironmentVariables { expected, original } = self;
|
||||
format!("Replace `{original}` with `{expected}`")
|
||||
}
|
||||
}
|
||||
|
||||
/// SIM112
|
||||
pub fn use_capital_environment_variables(checker: &mut Checker, expr: &Expr) {
|
||||
|
@ -37,7 +58,7 @@ pub fn use_capital_environment_variables(checker: &mut Checker, expr: &Expr) {
|
|||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::UseCapitalEnvironmentVariables {
|
||||
UseCapitalEnvironmentVariables {
|
||||
expected: capital_env_var.clone(),
|
||||
original: env_var.clone(),
|
||||
},
|
||||
|
@ -79,7 +100,7 @@ fn check_os_environ_subscript(checker: &mut Checker, expr: &Expr) {
|
|||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::UseCapitalEnvironmentVariables {
|
||||
UseCapitalEnvironmentVariables {
|
||||
expected: capital_env_var.clone(),
|
||||
original: env_var.clone(),
|
||||
},
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{
|
||||
Comprehension, Constant, Expr, ExprContext, ExprKind, Location, Stmt, StmtKind, Unaryop,
|
||||
};
|
||||
|
@ -8,7 +11,42 @@ use crate::checkers::ast::Checker;
|
|||
use crate::fix::Fix;
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use crate::source_code::Stylist;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct ConvertLoopToAny {
|
||||
pub any: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for ConvertLoopToAny {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let ConvertLoopToAny { any } = self;
|
||||
format!("Use `{any}` instead of `for` loop")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let ConvertLoopToAny { any } = self;
|
||||
format!("Replace with `{any}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct ConvertLoopToAll {
|
||||
pub all: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for ConvertLoopToAll {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let ConvertLoopToAll { all } = self;
|
||||
format!("Use `{all}` instead of `for` loop")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let ConvertLoopToAll { all } = self;
|
||||
format!("Replace with `{all}`")
|
||||
}
|
||||
}
|
||||
|
||||
struct Loop<'a> {
|
||||
return_value: bool,
|
||||
|
@ -197,7 +235,7 @@ pub fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt, sibling:
|
|||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::ConvertLoopToAny {
|
||||
ConvertLoopToAny {
|
||||
any: contents.clone(),
|
||||
},
|
||||
Range::from_located(stmt),
|
||||
|
@ -244,7 +282,7 @@ pub fn convert_for_loop_to_any_all(checker: &mut Checker, stmt: &Stmt, sibling:
|
|||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::ConvertLoopToAll {
|
||||
ConvertLoopToAll {
|
||||
all: contents.clone(),
|
||||
},
|
||||
Range::from_located(stmt),
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
use crate::violation::{AlwaysAutofixableViolation, Availability, Violation};
|
||||
use crate::{define_violation, AutofixKind};
|
||||
use log::error;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Cmpop, Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use crate::ast::comparable::ComparableExpr;
|
||||
|
@ -11,7 +14,75 @@ use crate::checkers::ast::Checker;
|
|||
use crate::fix::Fix;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::rules::flake8_simplify::rules::fix_if;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct NestedIfStatements;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for NestedIfStatements {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Use a single `if` statement instead of nested `if` statements")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Combine `if` statements using `and`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct ReturnBoolConditionDirectly {
|
||||
pub cond: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for ReturnBoolConditionDirectly {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let ReturnBoolConditionDirectly { cond } = self;
|
||||
format!("Return the condition `{cond}` directly")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let ReturnBoolConditionDirectly { cond } = self;
|
||||
format!("Replace with `return {cond}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct UseTernaryOperator {
|
||||
pub contents: String,
|
||||
}
|
||||
);
|
||||
impl Violation for UseTernaryOperator {
|
||||
const AUTOFIX: Option<AutofixKind> = Some(AutofixKind::new(Availability::Sometimes));
|
||||
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let UseTernaryOperator { contents } = self;
|
||||
format!("Use ternary operator `{contents}` instead of if-else-block")
|
||||
}
|
||||
|
||||
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
|
||||
Some(|UseTernaryOperator { contents }| format!("Replace if-else-block with `{contents}`"))
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct DictGetWithDefault {
|
||||
pub contents: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for DictGetWithDefault {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let DictGetWithDefault { contents } = self;
|
||||
format!("Use `{contents}` instead of an `if` block")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let DictGetWithDefault { contents } = self;
|
||||
format!("Replace with `{contents}`")
|
||||
}
|
||||
}
|
||||
|
||||
fn is_main_check(expr: &Expr) -> bool {
|
||||
if let ExprKind::Compare {
|
||||
|
@ -97,7 +168,7 @@ pub fn nested_if_statements(
|
|||
checker.locator,
|
||||
);
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::NestedIfStatements,
|
||||
NestedIfStatements,
|
||||
colon.map_or_else(
|
||||
|| Range::from_located(stmt),
|
||||
|colon| Range::new(stmt.location, colon.end_location),
|
||||
|
@ -176,7 +247,7 @@ pub fn return_bool_condition_directly(checker: &mut Checker, stmt: &Stmt) {
|
|||
|
||||
let condition = unparse_expr(test, checker.stylist);
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::ReturnBoolConditionDirectly { cond: condition },
|
||||
ReturnBoolConditionDirectly { cond: condition },
|
||||
Range::from_located(stmt),
|
||||
);
|
||||
if checker.patch(diagnostic.kind.rule())
|
||||
|
@ -308,7 +379,7 @@ pub fn use_ternary_operator(checker: &mut Checker, stmt: &Stmt, parent: Option<&
|
|||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::UseTernaryOperator {
|
||||
UseTernaryOperator {
|
||||
contents: contents.clone(),
|
||||
},
|
||||
Range::from_located(stmt),
|
||||
|
@ -439,7 +510,7 @@ pub fn use_dict_get_with_default(
|
|||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::DictGetWithDefault {
|
||||
DictGetWithDefault {
|
||||
contents: contents.clone(),
|
||||
},
|
||||
Range::from_located(stmt),
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Unaryop};
|
||||
|
||||
use crate::ast::helpers::{create_expr, unparse_expr};
|
||||
|
@ -5,7 +8,70 @@ use crate::ast::types::Range;
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct IfExprWithTrueFalse {
|
||||
pub expr: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for IfExprWithTrueFalse {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let IfExprWithTrueFalse { expr } = self;
|
||||
format!("Use `bool({expr})` instead of `True if {expr} else False`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let IfExprWithTrueFalse { expr } = self;
|
||||
format!("Replace with `not {expr}")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct IfExprWithFalseTrue {
|
||||
pub expr: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for IfExprWithFalseTrue {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let IfExprWithFalseTrue { expr } = self;
|
||||
format!("Use `not {expr}` instead of `False if {expr} else True`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let IfExprWithFalseTrue { expr } = self;
|
||||
format!("Replace with `bool({expr})")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct IfExprWithTwistedArms {
|
||||
pub expr_body: String,
|
||||
pub expr_else: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for IfExprWithTwistedArms {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let IfExprWithTwistedArms {
|
||||
expr_body,
|
||||
expr_else,
|
||||
} = self;
|
||||
format!(
|
||||
"Use `{expr_else} if {expr_else} else {expr_body}` instead of `{expr_body} if not \
|
||||
{expr_else} else {expr_else}`"
|
||||
)
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let IfExprWithTwistedArms {
|
||||
expr_body,
|
||||
expr_else,
|
||||
} = self;
|
||||
format!("Replace with `{expr_else} if {expr_else} else {expr_body}`")
|
||||
}
|
||||
}
|
||||
|
||||
/// SIM210
|
||||
pub fn explicit_true_false_in_ifexpr(
|
||||
|
@ -29,7 +95,7 @@ pub fn explicit_true_false_in_ifexpr(
|
|||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::IfExprWithTrueFalse {
|
||||
IfExprWithTrueFalse {
|
||||
expr: unparse_expr(test, checker.stylist),
|
||||
},
|
||||
Range::from_located(expr),
|
||||
|
@ -84,7 +150,7 @@ pub fn explicit_false_true_in_ifexpr(
|
|||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::IfExprWithFalseTrue {
|
||||
IfExprWithFalseTrue {
|
||||
expr: unparse_expr(test, checker.stylist),
|
||||
},
|
||||
Range::from_located(expr),
|
||||
|
@ -132,7 +198,7 @@ pub fn twisted_arms_in_ifexpr(
|
|||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::IfExprWithTwistedArms {
|
||||
IfExprWithTwistedArms {
|
||||
expr_body: unparse_expr(body, checker.stylist),
|
||||
expr_else: unparse_expr(orelse, checker.stylist),
|
||||
},
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Cmpop, Expr, ExprKind, Stmt, StmtKind, Unaryop};
|
||||
|
||||
use crate::ast::helpers::{create_expr, unparse_expr};
|
||||
|
@ -5,7 +8,60 @@ use crate::ast::types::{Range, ScopeKind};
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct NegateEqualOp {
|
||||
pub left: String,
|
||||
pub right: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for NegateEqualOp {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let NegateEqualOp { left, right } = self;
|
||||
format!("Use `{left} != {right}` instead of `not {left} == {right}`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Replace with `!=` operator".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct NegateNotEqualOp {
|
||||
pub left: String,
|
||||
pub right: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for NegateNotEqualOp {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let NegateNotEqualOp { left, right } = self;
|
||||
format!("Use `{left} == {right}` instead of `not {left} != {right}`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Replace with `==` operator".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct DoubleNegation {
|
||||
pub expr: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for DoubleNegation {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let DoubleNegation { expr } = self;
|
||||
format!("Use `{expr}` instead of `not (not {expr})`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let DoubleNegation { expr } = self;
|
||||
format!("Replace with `{expr}`")
|
||||
}
|
||||
}
|
||||
|
||||
const DUNDER_METHODS: &[&str] = &["__eq__", "__ne__", "__lt__", "__le__", "__gt__", "__ge__"];
|
||||
|
||||
|
@ -45,7 +101,7 @@ pub fn negation_with_equal_op(checker: &mut Checker, expr: &Expr, op: &Unaryop,
|
|||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::NegateEqualOp {
|
||||
NegateEqualOp {
|
||||
left: unparse_expr(left, checker.stylist),
|
||||
right: unparse_expr(&comparators[0], checker.stylist),
|
||||
},
|
||||
|
@ -96,7 +152,7 @@ pub fn negation_with_not_equal_op(
|
|||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::NegateNotEqualOp {
|
||||
NegateNotEqualOp {
|
||||
left: unparse_expr(left, checker.stylist),
|
||||
right: unparse_expr(&comparators[0], checker.stylist),
|
||||
},
|
||||
|
@ -132,7 +188,7 @@ pub fn double_negation(checker: &mut Checker, expr: &Expr, op: &Unaryop, operand
|
|||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::DoubleNegation {
|
||||
DoubleNegation {
|
||||
expr: operand.to_string(),
|
||||
},
|
||||
Range::from_located(expr),
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use log::error;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Located, Stmt, StmtKind, Withitem};
|
||||
|
||||
use super::fix_with;
|
||||
|
@ -6,7 +9,23 @@ use crate::ast::helpers::{first_colon_range, has_comments_in};
|
|||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct MultipleWithStatements;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for MultipleWithStatements {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!(
|
||||
"Use a single `with` statement with multiple contexts instead of nested `with` \
|
||||
statements"
|
||||
)
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Combine `with` statements".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
fn find_last_with(body: &[Stmt]) -> Option<(&Vec<Withitem>, &Vec<Stmt>)> {
|
||||
let [Located { node: StmtKind::With { items, body, .. }, ..}] = body else { return None };
|
||||
|
@ -43,7 +62,7 @@ pub fn multiple_with_statements(
|
|||
checker.locator,
|
||||
);
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::MultipleWithStatements,
|
||||
MultipleWithStatements,
|
||||
colon.map_or_else(
|
||||
|| Range::from_located(with_stmt),
|
||||
|colon| Range::new(with_stmt.location, colon.end_location),
|
||||
|
|
|
@ -1,10 +1,31 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Cmpop, Expr, ExprKind};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct KeyInDict {
|
||||
pub key: String,
|
||||
pub dict: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for KeyInDict {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let KeyInDict { key, dict } = self;
|
||||
format!("Use `{key} in {dict}` instead of `{key} in {dict}.keys()`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let KeyInDict { key, dict } = self;
|
||||
format!("Convert to `{key} in {dict}`")
|
||||
}
|
||||
}
|
||||
|
||||
/// SIM118
|
||||
fn key_in_dict(checker: &mut Checker, left: &Expr, right: &Expr, range: Range) {
|
||||
|
@ -35,7 +56,7 @@ fn key_in_dict(checker: &mut Checker, left: &Expr, right: &Expr, range: Range) {
|
|||
.slice_source_code_range(&Range::from_located(value));
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::KeyInDict {
|
||||
KeyInDict {
|
||||
key: left_content.to_string(),
|
||||
dict: value_content.to_string(),
|
||||
},
|
||||
|
|
|
@ -1,22 +1,30 @@
|
|||
pub use ast_bool_op::{
|
||||
a_and_not_a, a_or_not_a, and_false, compare_with_tuple, duplicate_isinstance_call, or_true,
|
||||
AAndNotA, AOrNotA, AndFalse, CompareWithTuple, DuplicateIsinstanceCall, OrTrue,
|
||||
};
|
||||
pub use ast_expr::use_capital_environment_variables;
|
||||
pub use ast_for::convert_for_loop_to_any_all;
|
||||
pub use ast_expr::{use_capital_environment_variables, UseCapitalEnvironmentVariables};
|
||||
pub use ast_for::{convert_for_loop_to_any_all, ConvertLoopToAll, ConvertLoopToAny};
|
||||
pub use ast_if::{
|
||||
nested_if_statements, return_bool_condition_directly, use_dict_get_with_default,
|
||||
use_ternary_operator,
|
||||
use_ternary_operator, DictGetWithDefault, NestedIfStatements, ReturnBoolConditionDirectly,
|
||||
UseTernaryOperator,
|
||||
};
|
||||
pub use ast_ifexp::{
|
||||
explicit_false_true_in_ifexpr, explicit_true_false_in_ifexpr, twisted_arms_in_ifexpr,
|
||||
IfExprWithFalseTrue, IfExprWithTrueFalse, IfExprWithTwistedArms,
|
||||
};
|
||||
pub use ast_unary_op::{double_negation, negation_with_equal_op, negation_with_not_equal_op};
|
||||
pub use ast_with::multiple_with_statements;
|
||||
pub use key_in_dict::{key_in_dict_compare, key_in_dict_for};
|
||||
pub use open_file_with_context_handler::open_file_with_context_handler;
|
||||
pub use return_in_try_except_finally::return_in_try_except_finally;
|
||||
pub use use_contextlib_suppress::use_contextlib_suppress;
|
||||
pub use yoda_conditions::yoda_conditions;
|
||||
pub use ast_unary_op::{
|
||||
double_negation, negation_with_equal_op, negation_with_not_equal_op, DoubleNegation,
|
||||
NegateEqualOp, NegateNotEqualOp,
|
||||
};
|
||||
pub use ast_with::{multiple_with_statements, MultipleWithStatements};
|
||||
pub use key_in_dict::{key_in_dict_compare, key_in_dict_for, KeyInDict};
|
||||
pub use open_file_with_context_handler::{
|
||||
open_file_with_context_handler, OpenFileWithContextHandler,
|
||||
};
|
||||
pub use return_in_try_except_finally::{return_in_try_except_finally, ReturnInTryExceptFinally};
|
||||
pub use use_contextlib_suppress::{use_contextlib_suppress, UseContextlibSuppress};
|
||||
pub use yoda_conditions::{yoda_conditions, YodaConditions};
|
||||
|
||||
mod ast_bool_op;
|
||||
mod ast_expr;
|
||||
|
|
|
@ -1,10 +1,22 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Expr, ExprKind};
|
||||
use rustpython_parser::ast::StmtKind;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct OpenFileWithContextHandler;
|
||||
);
|
||||
impl Violation for OpenFileWithContextHandler {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Use context handler for opening files")
|
||||
}
|
||||
}
|
||||
|
||||
/// Return `true` if the current expression is nested in an `await
|
||||
/// exit_stack.enter_async_context` call.
|
||||
|
@ -94,7 +106,7 @@ pub fn open_file_with_context_handler(checker: &mut Checker, func: &Expr) {
|
|||
}
|
||||
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::OpenFileWithContextHandler,
|
||||
OpenFileWithContextHandler,
|
||||
Range::from_located(func),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -1,9 +1,21 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Excepthandler, ExcepthandlerKind, Stmt, StmtKind};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct ReturnInTryExceptFinally;
|
||||
);
|
||||
impl Violation for ReturnInTryExceptFinally {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Don't use `return` in `try`/`except` and `finally`")
|
||||
}
|
||||
}
|
||||
|
||||
fn find_return(stmts: &[Stmt]) -> Option<&Stmt> {
|
||||
stmts
|
||||
|
@ -27,7 +39,7 @@ pub fn return_in_try_except_finally(
|
|||
if let Some(finally_return) = find_return(finalbody) {
|
||||
if try_has_return || except_has_return {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::ReturnInTryExceptFinally,
|
||||
ReturnInTryExceptFinally,
|
||||
Range::from_located(finally_return),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -1,11 +1,25 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::Violation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Excepthandler, ExcepthandlerKind, Located, Stmt, StmtKind};
|
||||
|
||||
use crate::ast::helpers;
|
||||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
define_violation!(
|
||||
pub struct UseContextlibSuppress {
|
||||
pub exception: String,
|
||||
}
|
||||
);
|
||||
impl Violation for UseContextlibSuppress {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let UseContextlibSuppress { exception } = self;
|
||||
format!("Use `contextlib.suppress({exception})` instead of try-except-pass")
|
||||
}
|
||||
}
|
||||
/// SIM105
|
||||
pub fn use_contextlib_suppress(
|
||||
checker: &mut Checker,
|
||||
|
@ -49,7 +63,7 @@ pub fn use_contextlib_suppress(
|
|||
handler_names.join(", ")
|
||||
};
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::UseContextlibSuppress { exception },
|
||||
UseContextlibSuppress { exception },
|
||||
Range::from_located(stmt),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -5,11 +5,45 @@ use crate::fix::Fix;
|
|||
use crate::python::string::{self};
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::source_code::{Locator, Stylist};
|
||||
use crate::violations;
|
||||
use crate::violation::{Availability, Violation};
|
||||
use crate::{define_violation, AutofixKind};
|
||||
|
||||
use anyhow::Result;
|
||||
use libcst_native::{Codegen, CodegenState, CompOp};
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Cmpop, Expr, ExprKind};
|
||||
|
||||
define_violation!(
|
||||
pub struct YodaConditions {
|
||||
pub suggestion: Option<String>,
|
||||
}
|
||||
);
|
||||
impl Violation for YodaConditions {
|
||||
const AUTOFIX: Option<AutofixKind> = Some(AutofixKind::new(Availability::Always));
|
||||
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let YodaConditions { suggestion } = self;
|
||||
if let Some(suggestion) = suggestion {
|
||||
format!("Yoda conditions are discouraged, use `{suggestion}` instead")
|
||||
} else {
|
||||
format!("Yoda conditions are discouraged")
|
||||
}
|
||||
}
|
||||
|
||||
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
|
||||
let YodaConditions { suggestion, .. } = self;
|
||||
if suggestion.is_some() {
|
||||
Some(|YodaConditions { suggestion }| {
|
||||
let suggestion = suggestion.as_ref().unwrap();
|
||||
format!("Replace Yoda condition with `{suggestion}`")
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return `true` if an [`Expr`] is a constant or a constant-like name.
|
||||
fn is_constant_like(expr: &Expr) -> bool {
|
||||
match &expr.node {
|
||||
|
@ -119,7 +153,7 @@ pub fn yoda_conditions(
|
|||
|
||||
if let Ok(suggestion) = reverse_comparison(expr, checker.locator, checker.stylist) {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::YodaConditions {
|
||||
YodaConditions {
|
||||
suggestion: Some(suggestion.to_string()),
|
||||
},
|
||||
Range::from_located(expr),
|
||||
|
@ -134,7 +168,7 @@ pub fn yoda_conditions(
|
|||
checker.diagnostics.push(diagnostic);
|
||||
} else {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::YodaConditions { suggestion: None },
|
||||
YodaConditions { suggestion: None },
|
||||
Range::from_located(expr),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -487,461 +487,6 @@ impl Violation for SysVersionSlice1Referenced {
|
|||
}
|
||||
}
|
||||
|
||||
// flake8-simplify
|
||||
|
||||
define_violation!(
|
||||
pub struct OpenFileWithContextHandler;
|
||||
);
|
||||
impl Violation for OpenFileWithContextHandler {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Use context handler for opening files")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct UseCapitalEnvironmentVariables {
|
||||
pub expected: String,
|
||||
pub original: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for UseCapitalEnvironmentVariables {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let UseCapitalEnvironmentVariables { expected, original } = self;
|
||||
format!("Use capitalized environment variable `{expected}` instead of `{original}`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let UseCapitalEnvironmentVariables { expected, original } = self;
|
||||
format!("Replace `{original}` with `{expected}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct DuplicateIsinstanceCall {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for DuplicateIsinstanceCall {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let DuplicateIsinstanceCall { name } = self;
|
||||
format!("Multiple `isinstance` calls for `{name}`, merge into a single call")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let DuplicateIsinstanceCall { name } = self;
|
||||
format!("Merge `isinstance` calls for `{name}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct NestedIfStatements;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for NestedIfStatements {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Use a single `if` statement instead of nested `if` statements")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Combine `if` statements using `and`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct ReturnBoolConditionDirectly {
|
||||
pub cond: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for ReturnBoolConditionDirectly {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let ReturnBoolConditionDirectly { cond } = self;
|
||||
format!("Return the condition `{cond}` directly")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let ReturnBoolConditionDirectly { cond } = self;
|
||||
format!("Replace with `return {cond}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct UseContextlibSuppress {
|
||||
pub exception: String,
|
||||
}
|
||||
);
|
||||
impl Violation for UseContextlibSuppress {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let UseContextlibSuppress { exception } = self;
|
||||
format!("Use `contextlib.suppress({exception})` instead of try-except-pass")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct ReturnInTryExceptFinally;
|
||||
);
|
||||
impl Violation for ReturnInTryExceptFinally {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Don't use `return` in `try`/`except` and `finally`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct UseTernaryOperator {
|
||||
pub contents: String,
|
||||
}
|
||||
);
|
||||
impl Violation for UseTernaryOperator {
|
||||
const AUTOFIX: Option<AutofixKind> = Some(AutofixKind::new(Availability::Sometimes));
|
||||
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let UseTernaryOperator { contents } = self;
|
||||
format!("Use ternary operator `{contents}` instead of if-else-block")
|
||||
}
|
||||
|
||||
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
|
||||
Some(|UseTernaryOperator { contents }| format!("Replace if-else-block with `{contents}`"))
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct CompareWithTuple {
|
||||
pub replacement: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for CompareWithTuple {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let CompareWithTuple { replacement } = self;
|
||||
format!("Use `{replacement}` instead of multiple equality comparisons")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let CompareWithTuple { replacement, .. } = self;
|
||||
format!("Replace with `{replacement}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct ConvertLoopToAny {
|
||||
pub any: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for ConvertLoopToAny {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let ConvertLoopToAny { any } = self;
|
||||
format!("Use `{any}` instead of `for` loop")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let ConvertLoopToAny { any } = self;
|
||||
format!("Replace with `{any}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct ConvertLoopToAll {
|
||||
pub all: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for ConvertLoopToAll {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let ConvertLoopToAll { all } = self;
|
||||
format!("Use `{all}` instead of `for` loop")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let ConvertLoopToAll { all } = self;
|
||||
format!("Replace with `{all}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct MultipleWithStatements;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for MultipleWithStatements {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!(
|
||||
"Use a single `with` statement with multiple contexts instead of nested `with` \
|
||||
statements"
|
||||
)
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Combine `with` statements".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct KeyInDict {
|
||||
pub key: String,
|
||||
pub dict: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for KeyInDict {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let KeyInDict { key, dict } = self;
|
||||
format!("Use `{key} in {dict}` instead of `{key} in {dict}.keys()`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let KeyInDict { key, dict } = self;
|
||||
format!("Convert to `{key} in {dict}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct NegateEqualOp {
|
||||
pub left: String,
|
||||
pub right: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for NegateEqualOp {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let NegateEqualOp { left, right } = self;
|
||||
format!("Use `{left} != {right}` instead of `not {left} == {right}`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Replace with `!=` operator".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct NegateNotEqualOp {
|
||||
pub left: String,
|
||||
pub right: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for NegateNotEqualOp {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let NegateNotEqualOp { left, right } = self;
|
||||
format!("Use `{left} == {right}` instead of `not {left} != {right}`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Replace with `==` operator".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct DoubleNegation {
|
||||
pub expr: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for DoubleNegation {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let DoubleNegation { expr } = self;
|
||||
format!("Use `{expr}` instead of `not (not {expr})`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let DoubleNegation { expr } = self;
|
||||
format!("Replace with `{expr}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct AAndNotA {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for AAndNotA {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let AAndNotA { name } = self;
|
||||
format!("Use `False` instead of `{name} and not {name}`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Replace with `False`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct AOrNotA {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for AOrNotA {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let AOrNotA { name } = self;
|
||||
format!("Use `True` instead of `{name} or not {name}`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Replace with `True`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct OrTrue;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for OrTrue {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Use `True` instead of `... or True`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Replace with `True`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct AndFalse;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for AndFalse {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Use `False` instead of `... and False`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Replace with `False`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct YodaConditions {
|
||||
pub suggestion: Option<String>,
|
||||
}
|
||||
);
|
||||
impl Violation for YodaConditions {
|
||||
const AUTOFIX: Option<AutofixKind> = Some(AutofixKind::new(Availability::Always));
|
||||
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let YodaConditions { suggestion } = self;
|
||||
if let Some(suggestion) = suggestion {
|
||||
format!("Yoda conditions are discouraged, use `{suggestion}` instead")
|
||||
} else {
|
||||
format!("Yoda conditions are discouraged")
|
||||
}
|
||||
}
|
||||
|
||||
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
|
||||
let YodaConditions { suggestion, .. } = self;
|
||||
if suggestion.is_some() {
|
||||
Some(|YodaConditions { suggestion }| {
|
||||
let suggestion = suggestion.as_ref().unwrap();
|
||||
format!("Replace Yoda condition with `{suggestion}`")
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct IfExprWithTrueFalse {
|
||||
pub expr: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for IfExprWithTrueFalse {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let IfExprWithTrueFalse { expr } = self;
|
||||
format!("Use `bool({expr})` instead of `True if {expr} else False`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let IfExprWithTrueFalse { expr } = self;
|
||||
format!("Replace with `not {expr}")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct IfExprWithFalseTrue {
|
||||
pub expr: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for IfExprWithFalseTrue {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let IfExprWithFalseTrue { expr } = self;
|
||||
format!("Use `not {expr}` instead of `False if {expr} else True`")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let IfExprWithFalseTrue { expr } = self;
|
||||
format!("Replace with `bool({expr})")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct IfExprWithTwistedArms {
|
||||
pub expr_body: String,
|
||||
pub expr_else: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for IfExprWithTwistedArms {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let IfExprWithTwistedArms {
|
||||
expr_body,
|
||||
expr_else,
|
||||
} = self;
|
||||
format!(
|
||||
"Use `{expr_else} if {expr_else} else {expr_body}` instead of `{expr_body} if not \
|
||||
{expr_else} else {expr_else}`"
|
||||
)
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let IfExprWithTwistedArms {
|
||||
expr_body,
|
||||
expr_else,
|
||||
} = self;
|
||||
format!("Replace with `{expr_else} if {expr_else} else {expr_body}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct DictGetWithDefault {
|
||||
pub contents: String,
|
||||
}
|
||||
);
|
||||
impl AlwaysAutofixableViolation for DictGetWithDefault {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let DictGetWithDefault { contents } = self;
|
||||
format!("Use `{contents}` instead of an `if` block")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let DictGetWithDefault { contents } = self;
|
||||
format!("Replace with `{contents}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct UnpackInsteadOfConcatenatingToCollectionLiteral {
|
||||
pub expr: String,
|
||||
}
|
||||
);
|
||||
impl Violation for UnpackInsteadOfConcatenatingToCollectionLiteral {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let UnpackInsteadOfConcatenatingToCollectionLiteral { expr } = self;
|
||||
format!("Consider `{expr}` instead of concatenation")
|
||||
}
|
||||
}
|
||||
|
||||
// pydocstyle
|
||||
|
||||
define_violation!(
|
||||
|
@ -2355,6 +1900,19 @@ impl Violation for KeywordArgumentBeforeStarArgument {
|
|||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct UnpackInsteadOfConcatenatingToCollectionLiteral {
|
||||
pub expr: String,
|
||||
}
|
||||
);
|
||||
impl Violation for UnpackInsteadOfConcatenatingToCollectionLiteral {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let UnpackInsteadOfConcatenatingToCollectionLiteral { expr } = self;
|
||||
format!("Consider `{expr}` instead of concatenation")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct UnusedCodes {
|
||||
pub unknown: Vec<String>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue