mirror of https://github.com/astral-sh/ruff
5040 lines
131 KiB
Rust
5040 lines
131 KiB
Rust
#![allow(clippy::useless_format)]
|
|
use std::fmt;
|
|
|
|
use itertools::Itertools;
|
|
use ruff_macros::derive_message_formats;
|
|
use rustpython_ast::Cmpop;
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::define_violation;
|
|
use crate::rules::flake8_debugger::types::DebuggerUsingType;
|
|
use crate::rules::flake8_pytest_style::types::{
|
|
ParametrizeNameType, ParametrizeValuesRowType, ParametrizeValuesType,
|
|
};
|
|
use crate::rules::flake8_quotes::settings::Quote;
|
|
use crate::rules::pyupgrade::types::Primitive;
|
|
use crate::violation::{AlwaysAutofixableViolation, AutofixKind, Availability, Violation};
|
|
|
|
// pycodestyle errors
|
|
|
|
define_violation!(
|
|
pub struct MultipleImportsOnOneLine;
|
|
);
|
|
impl Violation for MultipleImportsOnOneLine {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Multiple imports on one line")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ModuleImportNotAtTopOfFile;
|
|
);
|
|
impl Violation for ModuleImportNotAtTopOfFile {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Module level import not at top of file")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct IOError {
|
|
pub message: String,
|
|
}
|
|
);
|
|
impl Violation for IOError {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let IOError { message } = self;
|
|
format!("{message}")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SyntaxError {
|
|
pub message: String,
|
|
}
|
|
);
|
|
impl Violation for SyntaxError {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let SyntaxError { message } = self;
|
|
format!("SyntaxError: {message}")
|
|
}
|
|
}
|
|
|
|
// pyflakes
|
|
|
|
define_violation!(
|
|
pub struct UnusedImport {
|
|
pub name: String,
|
|
pub ignore_init: bool,
|
|
pub multiple: bool,
|
|
}
|
|
);
|
|
fn fmt_unused_import_autofix_msg(unused_import: &UnusedImport) -> String {
|
|
let UnusedImport { name, multiple, .. } = unused_import;
|
|
if *multiple {
|
|
"Remove unused import".to_string()
|
|
} else {
|
|
format!("Remove unused import: `{name}`")
|
|
}
|
|
}
|
|
impl Violation for UnusedImport {
|
|
const AUTOFIX: Option<AutofixKind> = Some(AutofixKind::new(Availability::Always));
|
|
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnusedImport {
|
|
name, ignore_init, ..
|
|
} = self;
|
|
if *ignore_init {
|
|
format!(
|
|
"`{name}` imported but unused; consider adding to `__all__` or using a redundant \
|
|
alias"
|
|
)
|
|
} else {
|
|
format!("`{name}` imported but unused")
|
|
}
|
|
}
|
|
|
|
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
|
|
let UnusedImport { ignore_init, .. } = self;
|
|
if *ignore_init {
|
|
None
|
|
} else {
|
|
Some(fmt_unused_import_autofix_msg)
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ImportShadowedByLoopVar {
|
|
pub name: String,
|
|
pub line: usize,
|
|
}
|
|
);
|
|
impl Violation for ImportShadowedByLoopVar {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let ImportShadowedByLoopVar { name, line } = self;
|
|
format!("Import `{name}` from line {line} shadowed by loop variable")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ImportStarUsed {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for ImportStarUsed {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let ImportStarUsed { name } = self;
|
|
format!("`from {name} import *` used; unable to detect undefined names")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct LateFutureImport;
|
|
);
|
|
impl Violation for LateFutureImport {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`from __future__` imports must occur at the beginning of the file")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ImportStarUsage {
|
|
pub name: String,
|
|
pub sources: Vec<String>,
|
|
}
|
|
);
|
|
impl Violation for ImportStarUsage {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let ImportStarUsage { name, sources } = self;
|
|
let sources = sources
|
|
.iter()
|
|
.map(|source| format!("`{source}`"))
|
|
.join(", ");
|
|
format!("`{name}` may be undefined, or defined from star imports: {sources}")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ImportStarNotPermitted {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for ImportStarNotPermitted {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let ImportStarNotPermitted { name } = self;
|
|
format!("`from {name} import *` only allowed at module level")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct FutureFeatureNotDefined {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for FutureFeatureNotDefined {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let FutureFeatureNotDefined { name } = self;
|
|
format!("Future feature `{name}` is not defined")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PercentFormatInvalidFormat {
|
|
pub message: String,
|
|
}
|
|
);
|
|
impl Violation for PercentFormatInvalidFormat {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let PercentFormatInvalidFormat { message } = self;
|
|
format!("`%`-format string has invalid format string: {message}")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PercentFormatExpectedMapping;
|
|
);
|
|
impl Violation for PercentFormatExpectedMapping {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`%`-format string expected mapping but got sequence")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PercentFormatExpectedSequence;
|
|
);
|
|
impl Violation for PercentFormatExpectedSequence {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`%`-format string expected sequence but got mapping")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PercentFormatExtraNamedArguments {
|
|
pub missing: Vec<String>,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for PercentFormatExtraNamedArguments {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let PercentFormatExtraNamedArguments { missing } = self;
|
|
let message = missing.join(", ");
|
|
format!("`%`-format string has unused named argument(s): {message}")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let PercentFormatExtraNamedArguments { missing } = self;
|
|
let message = missing.join(", ");
|
|
format!("Remove extra named arguments: {message}")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PercentFormatMissingArgument {
|
|
pub missing: Vec<String>,
|
|
}
|
|
);
|
|
impl Violation for PercentFormatMissingArgument {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let PercentFormatMissingArgument { missing } = self;
|
|
let message = missing.join(", ");
|
|
format!("`%`-format string is missing argument(s) for placeholder(s): {message}")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PercentFormatMixedPositionalAndNamed;
|
|
);
|
|
impl Violation for PercentFormatMixedPositionalAndNamed {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`%`-format string has mixed positional and named placeholders")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PercentFormatPositionalCountMismatch {
|
|
pub wanted: usize,
|
|
pub got: usize,
|
|
}
|
|
);
|
|
impl Violation for PercentFormatPositionalCountMismatch {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let PercentFormatPositionalCountMismatch { wanted, got } = self;
|
|
format!("`%`-format string has {wanted} placeholder(s) but {got} substitution(s)")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PercentFormatStarRequiresSequence;
|
|
);
|
|
impl Violation for PercentFormatStarRequiresSequence {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`%`-format string `*` specifier requires sequence")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PercentFormatUnsupportedFormatCharacter {
|
|
pub char: char,
|
|
}
|
|
);
|
|
impl Violation for PercentFormatUnsupportedFormatCharacter {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let PercentFormatUnsupportedFormatCharacter { char } = self;
|
|
format!("`%`-format string has unsupported format character '{char}'")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct StringDotFormatInvalidFormat {
|
|
pub message: String,
|
|
}
|
|
);
|
|
impl Violation for StringDotFormatInvalidFormat {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let StringDotFormatInvalidFormat { message } = self;
|
|
format!("`.format` call has invalid format string: {message}")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct StringDotFormatExtraNamedArguments {
|
|
pub missing: Vec<String>,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for StringDotFormatExtraNamedArguments {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let StringDotFormatExtraNamedArguments { missing } = self;
|
|
let message = missing.join(", ");
|
|
format!("`.format` call has unused named argument(s): {message}")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let StringDotFormatExtraNamedArguments { missing } = self;
|
|
let message = missing.join(", ");
|
|
format!("Remove extra named arguments: {message}")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct StringDotFormatExtraPositionalArguments {
|
|
pub missing: Vec<String>,
|
|
}
|
|
);
|
|
impl Violation for StringDotFormatExtraPositionalArguments {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let StringDotFormatExtraPositionalArguments { missing } = self;
|
|
let message = missing.join(", ");
|
|
format!("`.format` call has unused arguments at position(s): {message}")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct StringDotFormatMissingArguments {
|
|
pub missing: Vec<String>,
|
|
}
|
|
);
|
|
impl Violation for StringDotFormatMissingArguments {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let StringDotFormatMissingArguments { missing } = self;
|
|
let message = missing.join(", ");
|
|
format!("`.format` call is missing argument(s) for placeholder(s): {message}")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct StringDotFormatMixingAutomatic;
|
|
);
|
|
impl Violation for StringDotFormatMixingAutomatic {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`.format` string mixes automatic and manual numbering")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct FStringMissingPlaceholders;
|
|
);
|
|
impl AlwaysAutofixableViolation for FStringMissingPlaceholders {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("f-string without any placeholders")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove extraneous `f` prefix".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MultiValueRepeatedKeyLiteral {
|
|
pub name: String,
|
|
pub repeated_value: bool,
|
|
}
|
|
);
|
|
impl Violation for MultiValueRepeatedKeyLiteral {
|
|
const AUTOFIX: Option<AutofixKind> = Some(AutofixKind::new(Availability::Always));
|
|
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let MultiValueRepeatedKeyLiteral { name, .. } = self;
|
|
format!("Dictionary key literal `{name}` repeated")
|
|
}
|
|
|
|
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
|
|
let MultiValueRepeatedKeyLiteral { repeated_value, .. } = self;
|
|
if *repeated_value {
|
|
Some(|MultiValueRepeatedKeyLiteral { name, .. }| {
|
|
format!("Remove repeated key literal `{name}`")
|
|
})
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MultiValueRepeatedKeyVariable {
|
|
pub name: String,
|
|
pub repeated_value: bool,
|
|
}
|
|
);
|
|
impl Violation for MultiValueRepeatedKeyVariable {
|
|
const AUTOFIX: Option<AutofixKind> = Some(AutofixKind::new(Availability::Always));
|
|
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let MultiValueRepeatedKeyVariable { name, .. } = self;
|
|
format!("Dictionary key `{name}` repeated")
|
|
}
|
|
|
|
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
|
|
let MultiValueRepeatedKeyVariable { repeated_value, .. } = self;
|
|
if *repeated_value {
|
|
Some(|MultiValueRepeatedKeyVariable { name, .. }| {
|
|
format!("Remove repeated key `{name}`")
|
|
})
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ExpressionsInStarAssignment;
|
|
);
|
|
impl Violation for ExpressionsInStarAssignment {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Too many expressions in star-unpacking assignment")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct TwoStarredExpressions;
|
|
);
|
|
impl Violation for TwoStarredExpressions {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Two starred expressions in assignment")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct AssertTuple;
|
|
);
|
|
impl Violation for AssertTuple {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Assert test is a non-empty tuple, which is always `True`")
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum IsCmpop {
|
|
Is,
|
|
IsNot,
|
|
}
|
|
|
|
impl From<&Cmpop> for IsCmpop {
|
|
fn from(cmpop: &Cmpop) -> Self {
|
|
match cmpop {
|
|
Cmpop::Is => IsCmpop::Is,
|
|
Cmpop::IsNot => IsCmpop::IsNot,
|
|
_ => unreachable!("Expected Cmpop::Is | Cmpop::IsNot"),
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct IsLiteral {
|
|
pub cmpop: IsCmpop,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for IsLiteral {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let IsLiteral { cmpop } = self;
|
|
match cmpop {
|
|
IsCmpop::Is => format!("Use `==` to compare constant literals"),
|
|
IsCmpop::IsNot => format!("Use `!=` to compare constant literals"),
|
|
}
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let IsLiteral { cmpop } = self;
|
|
match cmpop {
|
|
IsCmpop::Is => "Replace `is` with `==`".to_string(),
|
|
IsCmpop::IsNot => "Replace `is not` with `!=`".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct InvalidPrintSyntax;
|
|
);
|
|
impl Violation for InvalidPrintSyntax {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use of `>>` is invalid with `print` function")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct IfTuple;
|
|
);
|
|
impl Violation for IfTuple {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("If test is a tuple, which is always `True`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct BreakOutsideLoop;
|
|
);
|
|
impl Violation for BreakOutsideLoop {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`break` outside loop")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ContinueOutsideLoop;
|
|
);
|
|
impl Violation for ContinueOutsideLoop {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`continue` not properly in loop")
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum DeferralKeyword {
|
|
Yield,
|
|
YieldFrom,
|
|
Await,
|
|
}
|
|
|
|
impl fmt::Display for DeferralKeyword {
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
|
match self {
|
|
DeferralKeyword::Yield => fmt.write_str("yield"),
|
|
DeferralKeyword::YieldFrom => fmt.write_str("yield from"),
|
|
DeferralKeyword::Await => fmt.write_str("await"),
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct YieldOutsideFunction {
|
|
pub keyword: DeferralKeyword,
|
|
}
|
|
);
|
|
impl Violation for YieldOutsideFunction {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let YieldOutsideFunction { keyword } = self;
|
|
format!("`{keyword}` statement outside of a function")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ReturnOutsideFunction;
|
|
);
|
|
impl Violation for ReturnOutsideFunction {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`return` statement outside of a function/method")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct DefaultExceptNotLast;
|
|
);
|
|
impl Violation for DefaultExceptNotLast {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("An `except` block as not the last exception handler")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ForwardAnnotationSyntaxError {
|
|
pub body: String,
|
|
}
|
|
);
|
|
impl Violation for ForwardAnnotationSyntaxError {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let ForwardAnnotationSyntaxError { body } = self;
|
|
format!("Syntax error in forward annotation: `{body}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct RedefinedWhileUnused {
|
|
pub name: String,
|
|
pub line: usize,
|
|
}
|
|
);
|
|
impl Violation for RedefinedWhileUnused {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let RedefinedWhileUnused { name, line } = self;
|
|
format!("Redefinition of unused `{name}` from line {line}")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UndefinedName {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for UndefinedName {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UndefinedName { name } = self;
|
|
format!("Undefined name `{name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UndefinedExport {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for UndefinedExport {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UndefinedExport { name } = self;
|
|
format!("Undefined name `{name}` in `__all__`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UndefinedLocal {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for UndefinedLocal {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UndefinedLocal { name } = self;
|
|
format!("Local variable `{name}` referenced before assignment")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnusedVariable {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for UnusedVariable {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnusedVariable { name } = self;
|
|
format!("Local variable `{name}` is assigned to but never used")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let UnusedVariable { name } = self;
|
|
format!("Remove assignment to unused variable `{name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnusedAnnotation {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for UnusedAnnotation {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnusedAnnotation { name } = self;
|
|
format!("Local variable `{name}` is annotated but never used")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct RaiseNotImplemented;
|
|
);
|
|
impl AlwaysAutofixableViolation for RaiseNotImplemented {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`raise NotImplemented` should be `raise NotImplementedError`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Use `raise NotImplementedError`".to_string()
|
|
}
|
|
}
|
|
|
|
// pylint
|
|
|
|
define_violation!(
|
|
pub struct UselessImportAlias;
|
|
);
|
|
impl AlwaysAutofixableViolation for UselessImportAlias {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Import alias does not rename original package")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove import alias".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryDirectLambdaCall;
|
|
);
|
|
impl Violation for UnnecessaryDirectLambdaCall {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Lambda expression called directly. Execute the expression inline instead.")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NonlocalWithoutBinding {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for NonlocalWithoutBinding {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let NonlocalWithoutBinding { name } = self;
|
|
format!("Nonlocal name `{name}` found without binding")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UsedPriorGlobalDeclaration {
|
|
pub name: String,
|
|
pub line: usize,
|
|
}
|
|
);
|
|
impl Violation for UsedPriorGlobalDeclaration {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UsedPriorGlobalDeclaration { name, line } = self;
|
|
format!("Name `{name}` is used prior to global declaration on line {line}")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct AwaitOutsideAsync;
|
|
);
|
|
impl Violation for AwaitOutsideAsync {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`await` should be used within an async function")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PropertyWithParameters;
|
|
);
|
|
impl Violation for PropertyWithParameters {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Cannot have defined parameters for properties")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ConsiderUsingFromImport {
|
|
pub module: String,
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for ConsiderUsingFromImport {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let ConsiderUsingFromImport { module, name } = self;
|
|
format!("Use `from {module} import {name}` in lieu of alias")
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum ViolationsCmpop {
|
|
Eq,
|
|
NotEq,
|
|
Lt,
|
|
LtE,
|
|
Gt,
|
|
GtE,
|
|
Is,
|
|
IsNot,
|
|
In,
|
|
NotIn,
|
|
}
|
|
|
|
impl From<&Cmpop> for ViolationsCmpop {
|
|
fn from(cmpop: &Cmpop) -> Self {
|
|
match cmpop {
|
|
Cmpop::Eq => Self::Eq,
|
|
Cmpop::NotEq => Self::NotEq,
|
|
Cmpop::Lt => Self::Lt,
|
|
Cmpop::LtE => Self::LtE,
|
|
Cmpop::Gt => Self::Gt,
|
|
Cmpop::GtE => Self::GtE,
|
|
Cmpop::Is => Self::Is,
|
|
Cmpop::IsNot => Self::IsNot,
|
|
Cmpop::In => Self::In,
|
|
Cmpop::NotIn => Self::NotIn,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for ViolationsCmpop {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
let representation = match self {
|
|
Self::Eq => "==",
|
|
Self::NotEq => "!=",
|
|
Self::Lt => "<",
|
|
Self::LtE => "<=",
|
|
Self::Gt => ">",
|
|
Self::GtE => ">=",
|
|
Self::Is => "is",
|
|
Self::IsNot => "is not",
|
|
Self::In => "in",
|
|
Self::NotIn => "not in",
|
|
};
|
|
write!(f, "{representation}")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ConstantComparison {
|
|
pub left_constant: String,
|
|
pub op: ViolationsCmpop,
|
|
pub right_constant: String,
|
|
}
|
|
);
|
|
impl Violation for ConstantComparison {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let ConstantComparison {
|
|
left_constant,
|
|
op,
|
|
right_constant,
|
|
} = self;
|
|
|
|
format!(
|
|
"Two constants compared in a comparison, consider replacing `{left_constant} {op} \
|
|
{right_constant}`"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ConsiderMergingIsinstance {
|
|
pub obj: String,
|
|
pub types: Vec<String>,
|
|
}
|
|
);
|
|
impl Violation for ConsiderMergingIsinstance {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let ConsiderMergingIsinstance { obj, types } = self;
|
|
let types = types.join(", ");
|
|
format!("Merge these isinstance calls: `isinstance({obj}, ({types}))`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UseSysExit {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for UseSysExit {
|
|
const AUTOFIX: Option<AutofixKind> = Some(AutofixKind::new(Availability::Sometimes));
|
|
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UseSysExit { name } = self;
|
|
format!("Use `sys.exit()` instead of `{name}`")
|
|
}
|
|
|
|
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
|
|
Some(|UseSysExit { name }| format!("Replace `{name}` with `sys.exit()`"))
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MagicValueComparison {
|
|
pub value: String,
|
|
}
|
|
);
|
|
impl Violation for MagicValueComparison {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let MagicValueComparison { value } = self;
|
|
format!(
|
|
"Magic value used in comparison, consider replacing {value} with a constant variable"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UselessElseOnLoop;
|
|
);
|
|
impl Violation for UselessElseOnLoop {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"Else clause on loop without a break statement, remove the else and de-indent all the \
|
|
code inside it"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct GlobalVariableNotAssigned {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for GlobalVariableNotAssigned {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let GlobalVariableNotAssigned { name } = self;
|
|
format!("Using global for `{name}` but no assignment is done")
|
|
}
|
|
}
|
|
|
|
// flake8-builtins
|
|
|
|
define_violation!(
|
|
pub struct BuiltinVariableShadowing {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for BuiltinVariableShadowing {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let BuiltinVariableShadowing { name } = self;
|
|
format!("Variable `{name}` is shadowing a python builtin")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct BuiltinArgumentShadowing {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for BuiltinArgumentShadowing {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let BuiltinArgumentShadowing { name } = self;
|
|
format!("Argument `{name}` is shadowing a python builtin")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct BuiltinAttributeShadowing {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for BuiltinAttributeShadowing {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let BuiltinAttributeShadowing { name } = self;
|
|
format!("Class attribute `{name}` is shadowing a python builtin")
|
|
}
|
|
}
|
|
|
|
// flake8-bugbear
|
|
|
|
define_violation!(
|
|
pub struct UnaryPrefixIncrement;
|
|
);
|
|
impl Violation for UnaryPrefixIncrement {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Python does not support the unary prefix increment")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct AssignmentToOsEnviron;
|
|
);
|
|
impl Violation for AssignmentToOsEnviron {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Assigning to `os.environ` doesn't clear the environment")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnreliableCallableCheck;
|
|
);
|
|
impl Violation for UnreliableCallableCheck {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
" Using `hasattr(x, '__call__')` to test if x is callable is unreliable. Use \
|
|
`callable(x)` for consistent results."
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct StripWithMultiCharacters;
|
|
);
|
|
impl Violation for StripWithMultiCharacters {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Using `.strip()` with multi-character strings is misleading the reader")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MutableArgumentDefault;
|
|
);
|
|
impl Violation for MutableArgumentDefault {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Do not use mutable data structures for argument defaults")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnusedLoopControlVariable {
|
|
/// The name of the loop control variable.
|
|
pub name: String,
|
|
/// Whether the variable is safe to rename. A variable is unsafe to
|
|
/// rename if it _might_ be used by magic control flow (e.g.,
|
|
/// `locals()`).
|
|
pub safe: bool,
|
|
}
|
|
);
|
|
impl Violation for UnusedLoopControlVariable {
|
|
const AUTOFIX: Option<AutofixKind> = Some(AutofixKind::new(Availability::Always));
|
|
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnusedLoopControlVariable { name, safe } = self;
|
|
if *safe {
|
|
format!("Loop control variable `{name}` not used within loop body")
|
|
} else {
|
|
format!("Loop control variable `{name}` may not be used within loop body")
|
|
}
|
|
}
|
|
|
|
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
|
|
let UnusedLoopControlVariable { safe, .. } = self;
|
|
if *safe {
|
|
Some(|UnusedLoopControlVariable { name, .. }| {
|
|
format!("Rename unused `{name}` to `_{name}`")
|
|
})
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct FunctionCallArgumentDefault {
|
|
pub name: Option<String>,
|
|
}
|
|
);
|
|
impl Violation for FunctionCallArgumentDefault {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let FunctionCallArgumentDefault { name } = self;
|
|
if let Some(name) = name {
|
|
format!("Do not perform function call `{name}` in argument defaults")
|
|
} else {
|
|
format!("Do not perform function call in argument defaults")
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct GetAttrWithConstant;
|
|
);
|
|
impl AlwaysAutofixableViolation for GetAttrWithConstant {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"Do not call `getattr` with a constant attribute value. It is not any safer than \
|
|
normal property access."
|
|
)
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Replace `getattr` with attribute access".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SetAttrWithConstant;
|
|
);
|
|
impl AlwaysAutofixableViolation for SetAttrWithConstant {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"Do not call `setattr` with a constant attribute value. It is not any safer than \
|
|
normal property access."
|
|
)
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Replace `setattr` with assignment".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct DoNotAssertFalse;
|
|
);
|
|
impl AlwaysAutofixableViolation for DoNotAssertFalse {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Do not `assert False` (`python -O` removes these calls), raise `AssertionError()`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Replace `assert False`".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct JumpStatementInFinally {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for JumpStatementInFinally {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let JumpStatementInFinally { name } = self;
|
|
format!("`{name}` inside `finally` blocks cause exceptions to be silenced")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct RedundantTupleInExceptionHandler {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for RedundantTupleInExceptionHandler {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let RedundantTupleInExceptionHandler { name } = self;
|
|
format!(
|
|
"A length-one tuple literal is redundant. Write `except {name}` instead of `except \
|
|
({name},)`."
|
|
)
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let RedundantTupleInExceptionHandler { name } = self;
|
|
format!("Replace with `except {name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct DuplicateHandlerException {
|
|
pub names: Vec<String>,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for DuplicateHandlerException {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let DuplicateHandlerException { names } = self;
|
|
if names.len() == 1 {
|
|
let name = &names[0];
|
|
format!("Exception handler with duplicate exception: `{name}`")
|
|
} else {
|
|
let names = names.iter().map(|name| format!("`{name}`")).join(", ");
|
|
format!("Exception handler with duplicate exceptions: {names}")
|
|
}
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"De-duplicate exceptions".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UselessComparison;
|
|
);
|
|
impl Violation for UselessComparison {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"Pointless comparison. This comparison does nothing but waste CPU instructions. \
|
|
Either prepend `assert` or remove it."
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct CannotRaiseLiteral;
|
|
);
|
|
impl Violation for CannotRaiseLiteral {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Cannot raise a literal. Did you intend to return it or raise an Exception?")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NoAssertRaisesException;
|
|
);
|
|
impl Violation for NoAssertRaisesException {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`assertRaises(Exception)` should be considered evil")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UselessExpression;
|
|
);
|
|
impl Violation for UselessExpression {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Found useless expression. Either assign it to a variable or remove it.")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct CachedInstanceMethod;
|
|
);
|
|
impl Violation for CachedInstanceMethod {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"Use of `functools.lru_cache` or `functools.cache` on methods can lead to memory leaks"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct LoopVariableOverridesIterator {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for LoopVariableOverridesIterator {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let LoopVariableOverridesIterator { name } = self;
|
|
format!("Loop control variable `{name}` overrides iterable it iterates")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct FStringDocstring;
|
|
);
|
|
impl Violation for FStringDocstring {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"f-string used as docstring. This will be interpreted by python as a joined string \
|
|
rather than a docstring."
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UselessContextlibSuppress;
|
|
);
|
|
impl Violation for UselessContextlibSuppress {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"No arguments passed to `contextlib.suppress`. No exceptions will be suppressed and \
|
|
therefore this context manager is redundant"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct FunctionUsesLoopVariable {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for FunctionUsesLoopVariable {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let FunctionUsesLoopVariable { name } = self;
|
|
format!("Function definition does not bind loop variable `{name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct AbstractBaseClassWithoutAbstractMethod {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for AbstractBaseClassWithoutAbstractMethod {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let AbstractBaseClassWithoutAbstractMethod { name } = self;
|
|
format!("`{name}` is an abstract base class, but it has no abstract methods")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct DuplicateTryBlockException {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for DuplicateTryBlockException {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let DuplicateTryBlockException { name } = self;
|
|
format!("try-except block with duplicate exception `{name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct StarArgUnpackingAfterKeywordArg;
|
|
);
|
|
impl Violation for StarArgUnpackingAfterKeywordArg {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Star-arg unpacking after a keyword argument is strongly discouraged")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct EmptyMethodWithoutAbstractDecorator {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for EmptyMethodWithoutAbstractDecorator {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let EmptyMethodWithoutAbstractDecorator { name } = self;
|
|
format!(
|
|
"`{name}` is an empty method in an abstract base class, but has no abstract decorator"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct RaiseWithoutFromInsideExcept;
|
|
);
|
|
impl Violation for RaiseWithoutFromInsideExcept {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"Within an except clause, raise exceptions with `raise ... from err` or `raise ... \
|
|
from None` to distinguish them from errors in exception handling"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ZipWithoutExplicitStrict;
|
|
);
|
|
impl Violation for ZipWithoutExplicitStrict {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`zip()` without an explicit `strict=` parameter")
|
|
}
|
|
}
|
|
|
|
// flake8-blind-except
|
|
|
|
define_violation!(
|
|
pub struct BlindExcept {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for BlindExcept {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let BlindExcept { name } = self;
|
|
format!("Do not catch blind exception: `{name}`")
|
|
}
|
|
}
|
|
|
|
// flake8-comprehensions
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryGeneratorList;
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryGeneratorList {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Unnecessary generator (rewrite as a `list` comprehension)")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Rewrite as a `list` comprehension".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryGeneratorSet;
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryGeneratorSet {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Unnecessary generator (rewrite as a `set` comprehension)")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Rewrite as a `set` comprehension".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryGeneratorDict;
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryGeneratorDict {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Unnecessary generator (rewrite as a `dict` comprehension)")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Rewrite as a `dict` comprehension".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryListComprehensionSet;
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryListComprehensionSet {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Unnecessary `list` comprehension (rewrite as a `set` comprehension)")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Rewrite as a `set` comprehension".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryListComprehensionDict;
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryListComprehensionDict {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Unnecessary `list` comprehension (rewrite as a `dict` comprehension)")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Rewrite as a `dict` comprehension".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryLiteralSet {
|
|
pub obj_type: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryLiteralSet {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnnecessaryLiteralSet { obj_type } = self;
|
|
format!("Unnecessary `{obj_type}` literal (rewrite as a `set` literal)")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Rewrite as a `set` literal".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryLiteralDict {
|
|
pub obj_type: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryLiteralDict {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnnecessaryLiteralDict { obj_type } = self;
|
|
format!("Unnecessary `{obj_type}` literal (rewrite as a `dict` literal)")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Rewrite as a `dict` literal".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryCollectionCall {
|
|
pub obj_type: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryCollectionCall {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnnecessaryCollectionCall { obj_type } = self;
|
|
format!("Unnecessary `{obj_type}` call (rewrite as a literal)")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Rewrite as a literal".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryLiteralWithinTupleCall {
|
|
pub literal: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryLiteralWithinTupleCall {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnnecessaryLiteralWithinTupleCall { literal } = self;
|
|
if literal == "list" {
|
|
format!(
|
|
"Unnecessary `{literal}` literal passed to `tuple()` (rewrite as a `tuple` \
|
|
literal)"
|
|
)
|
|
} else {
|
|
format!(
|
|
"Unnecessary `{literal}` literal passed to `tuple()` (remove the outer call to \
|
|
`tuple()`)"
|
|
)
|
|
}
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let UnnecessaryLiteralWithinTupleCall { literal } = self;
|
|
{
|
|
if literal == "list" {
|
|
"Rewrite as a `tuple` literal".to_string()
|
|
} else {
|
|
"Remove outer `tuple` call".to_string()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryLiteralWithinListCall {
|
|
pub literal: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryLiteralWithinListCall {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnnecessaryLiteralWithinListCall { literal } = self;
|
|
if literal == "list" {
|
|
format!(
|
|
"Unnecessary `{literal}` literal passed to `list()` (remove the outer call to \
|
|
`list()`)"
|
|
)
|
|
} else {
|
|
format!(
|
|
"Unnecessary `{literal}` literal passed to `list()` (rewrite as a `list` literal)"
|
|
)
|
|
}
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let UnnecessaryLiteralWithinListCall { literal } = self;
|
|
{
|
|
if literal == "list" {
|
|
"Remove outer `list` call".to_string()
|
|
} else {
|
|
"Rewrite as a `list` literal".to_string()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryListCall;
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryListCall {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Unnecessary `list` call (remove the outer call to `list()`)")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove outer `list` call".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryCallAroundSorted {
|
|
pub func: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryCallAroundSorted {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnnecessaryCallAroundSorted { func } = self;
|
|
format!("Unnecessary `{func}` call around `sorted()`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let UnnecessaryCallAroundSorted { func } = self;
|
|
format!("Remove unnecessary `{func}` call")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryDoubleCastOrProcess {
|
|
pub inner: String,
|
|
pub outer: String,
|
|
}
|
|
);
|
|
impl Violation for UnnecessaryDoubleCastOrProcess {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnnecessaryDoubleCastOrProcess { inner, outer } = self;
|
|
format!("Unnecessary `{inner}` call within `{outer}()`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessarySubscriptReversal {
|
|
pub func: String,
|
|
}
|
|
);
|
|
impl Violation for UnnecessarySubscriptReversal {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnnecessarySubscriptReversal { func } = self;
|
|
format!("Unnecessary subscript reversal of iterable within `{func}()`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryComprehension {
|
|
pub obj_type: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryComprehension {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnnecessaryComprehension { obj_type } = self;
|
|
format!("Unnecessary `{obj_type}` comprehension (rewrite using `{obj_type}()`)")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let UnnecessaryComprehension { obj_type } = self;
|
|
format!("Rewrite using `{obj_type}()`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryMap {
|
|
pub obj_type: String,
|
|
}
|
|
);
|
|
impl Violation for UnnecessaryMap {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnnecessaryMap { obj_type } = self;
|
|
if obj_type == "generator" {
|
|
format!("Unnecessary `map` usage (rewrite using a generator expression)")
|
|
} else {
|
|
format!("Unnecessary `map` usage (rewrite using a `{obj_type}` comprehension)")
|
|
}
|
|
}
|
|
}
|
|
|
|
// flake8-debugger
|
|
|
|
define_violation!(
|
|
pub struct Debugger {
|
|
pub using_type: DebuggerUsingType,
|
|
}
|
|
);
|
|
impl Violation for Debugger {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let Debugger { using_type } = self;
|
|
match using_type {
|
|
DebuggerUsingType::Call(name) => format!("Trace found: `{name}` used"),
|
|
DebuggerUsingType::Import(name) => format!("Import for `{name}` found"),
|
|
}
|
|
}
|
|
}
|
|
|
|
// mccabe
|
|
|
|
define_violation!(
|
|
pub struct FunctionIsTooComplex {
|
|
pub name: String,
|
|
pub complexity: usize,
|
|
}
|
|
);
|
|
impl Violation for FunctionIsTooComplex {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let FunctionIsTooComplex { name, complexity } = self;
|
|
format!("`{name}` is too complex ({complexity})")
|
|
}
|
|
}
|
|
|
|
// flake8-return
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryReturnNone;
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryReturnNone {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"Do not explicitly `return None` in function if it is the only possible return value"
|
|
)
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove explicit `return None`".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ImplicitReturnValue;
|
|
);
|
|
impl AlwaysAutofixableViolation for ImplicitReturnValue {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Do not implicitly `return None` in function able to return non-`None` value")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Add explicit `None` return value".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ImplicitReturn;
|
|
);
|
|
impl AlwaysAutofixableViolation for ImplicitReturn {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Missing explicit `return` at the end of function able to return non-`None` value")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Add explicit `return` statement".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryAssign;
|
|
);
|
|
impl Violation for UnnecessaryAssign {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Unnecessary variable assignment before `return` statement")
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum Branch {
|
|
Elif,
|
|
Else,
|
|
}
|
|
|
|
impl fmt::Display for Branch {
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
|
match self {
|
|
Branch::Elif => fmt.write_str("elif"),
|
|
Branch::Else => fmt.write_str("else"),
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SuperfluousElseReturn {
|
|
pub branch: Branch,
|
|
}
|
|
);
|
|
impl Violation for SuperfluousElseReturn {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let SuperfluousElseReturn { branch } = self;
|
|
format!("Unnecessary `{branch}` after `return` statement")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SuperfluousElseRaise {
|
|
pub branch: Branch,
|
|
}
|
|
);
|
|
impl Violation for SuperfluousElseRaise {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let SuperfluousElseRaise { branch } = self;
|
|
format!("Unnecessary `{branch}` after `raise` statement")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SuperfluousElseContinue {
|
|
pub branch: Branch,
|
|
}
|
|
);
|
|
impl Violation for SuperfluousElseContinue {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let SuperfluousElseContinue { branch } = self;
|
|
format!("Unnecessary `{branch}` after `continue` statement")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SuperfluousElseBreak {
|
|
pub branch: Branch,
|
|
}
|
|
);
|
|
impl Violation for SuperfluousElseBreak {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let SuperfluousElseBreak { branch } = self;
|
|
format!("Unnecessary `{branch}` after `break` statement")
|
|
}
|
|
}
|
|
|
|
// flake8-implicit-str-concat
|
|
|
|
define_violation!(
|
|
pub struct SingleLineImplicitStringConcatenation;
|
|
);
|
|
impl Violation for SingleLineImplicitStringConcatenation {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Implicitly concatenated string literals on one line")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MultiLineImplicitStringConcatenation;
|
|
);
|
|
impl Violation for MultiLineImplicitStringConcatenation {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Implicitly concatenated string literals over continuation line")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ExplicitStringConcatenation;
|
|
);
|
|
impl Violation for ExplicitStringConcatenation {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Explicitly concatenated string should be implicitly concatenated")
|
|
}
|
|
}
|
|
|
|
// flake8-print
|
|
|
|
define_violation!(
|
|
pub struct PrintFound;
|
|
);
|
|
impl AlwaysAutofixableViolation for PrintFound {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`print` found")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove `print`".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PPrintFound;
|
|
);
|
|
impl AlwaysAutofixableViolation for PPrintFound {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`pprint` found")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove `pprint`".to_string()
|
|
}
|
|
}
|
|
|
|
// flake8-quotes
|
|
|
|
define_violation!(
|
|
pub struct BadQuotesInlineString {
|
|
pub quote: Quote,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for BadQuotesInlineString {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let BadQuotesInlineString { quote } = self;
|
|
match quote {
|
|
Quote::Single => format!("Double quotes found but single quotes preferred"),
|
|
Quote::Double => format!("Single quotes found but double quotes preferred"),
|
|
}
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let BadQuotesInlineString { quote } = self;
|
|
match quote {
|
|
Quote::Single => "Replace double quotes with single quotes".to_string(),
|
|
Quote::Double => "Replace single quotes with double quotes".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct BadQuotesMultilineString {
|
|
pub quote: Quote,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for BadQuotesMultilineString {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let BadQuotesMultilineString { quote } = self;
|
|
match quote {
|
|
Quote::Single => format!("Double quote multiline found but single quotes preferred"),
|
|
Quote::Double => format!("Single quote multiline found but double quotes preferred"),
|
|
}
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let BadQuotesMultilineString { quote } = self;
|
|
match quote {
|
|
Quote::Single => "Replace double multiline quotes with single quotes".to_string(),
|
|
Quote::Double => "Replace single multiline quotes with double quotes".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct BadQuotesDocstring {
|
|
pub quote: Quote,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for BadQuotesDocstring {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let BadQuotesDocstring { quote } = self;
|
|
match quote {
|
|
Quote::Single => format!("Double quote docstring found but single quotes preferred"),
|
|
Quote::Double => format!("Single quote docstring found but double quotes preferred"),
|
|
}
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let BadQuotesDocstring { quote } = self;
|
|
match quote {
|
|
Quote::Single => "Replace double quotes docstring with single quotes".to_string(),
|
|
Quote::Double => "Replace single quotes docstring with double quotes".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct AvoidQuoteEscape;
|
|
);
|
|
impl AlwaysAutofixableViolation for AvoidQuoteEscape {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Change outer quotes to avoid escaping inner quotes")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Change outer quotes to avoid escaping inner quotes".to_string()
|
|
}
|
|
}
|
|
|
|
// flake8-annotations
|
|
|
|
define_violation!(
|
|
pub struct MissingTypeFunctionArgument {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for MissingTypeFunctionArgument {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let MissingTypeFunctionArgument { name } = self;
|
|
format!("Missing type annotation for function argument `{name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MissingTypeArgs {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for MissingTypeArgs {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let MissingTypeArgs { name } = self;
|
|
format!("Missing type annotation for `*{name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MissingTypeKwargs {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for MissingTypeKwargs {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let MissingTypeKwargs { name } = self;
|
|
format!("Missing type annotation for `**{name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MissingTypeSelf {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for MissingTypeSelf {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let MissingTypeSelf { name } = self;
|
|
format!("Missing type annotation for `{name}` in method")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MissingTypeCls {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for MissingTypeCls {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let MissingTypeCls { name } = self;
|
|
format!("Missing type annotation for `{name}` in classmethod")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MissingReturnTypePublicFunction {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for MissingReturnTypePublicFunction {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let MissingReturnTypePublicFunction { name } = self;
|
|
format!("Missing return type annotation for public function `{name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MissingReturnTypePrivateFunction {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for MissingReturnTypePrivateFunction {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let MissingReturnTypePrivateFunction { name } = self;
|
|
format!("Missing return type annotation for private function `{name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MissingReturnTypeSpecialMethod {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for MissingReturnTypeSpecialMethod {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let MissingReturnTypeSpecialMethod { name } = self;
|
|
format!("Missing return type annotation for special method `{name}`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Add `None` return type".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MissingReturnTypeStaticMethod {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for MissingReturnTypeStaticMethod {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let MissingReturnTypeStaticMethod { name } = self;
|
|
format!("Missing return type annotation for staticmethod `{name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MissingReturnTypeClassMethod {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for MissingReturnTypeClassMethod {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let MissingReturnTypeClassMethod { name } = self;
|
|
format!("Missing return type annotation for classmethod `{name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct DynamicallyTypedExpression {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for DynamicallyTypedExpression {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let DynamicallyTypedExpression { name } = self;
|
|
format!("Dynamically typed expressions (typing.Any) are disallowed in `{name}`")
|
|
}
|
|
}
|
|
|
|
// flake8-2020
|
|
|
|
define_violation!(
|
|
pub struct SysVersionSlice3Referenced;
|
|
);
|
|
impl Violation for SysVersionSlice3Referenced {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`sys.version[:3]` referenced (python3.10), use `sys.version_info`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SysVersion2Referenced;
|
|
);
|
|
impl Violation for SysVersion2Referenced {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`sys.version[2]` referenced (python3.10), use `sys.version_info`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SysVersionCmpStr3;
|
|
);
|
|
impl Violation for SysVersionCmpStr3 {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`sys.version` compared to string (python3.10), use `sys.version_info`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SysVersionInfo0Eq3Referenced;
|
|
);
|
|
impl Violation for SysVersionInfo0Eq3Referenced {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`sys.version_info[0] == 3` referenced (python4), use `>=`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SixPY3Referenced;
|
|
);
|
|
impl Violation for SixPY3Referenced {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`six.PY3` referenced (python4), use `not six.PY2`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SysVersionInfo1CmpInt;
|
|
);
|
|
impl Violation for SysVersionInfo1CmpInt {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"`sys.version_info[1]` compared to integer (python4), compare `sys.version_info` to \
|
|
tuple"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SysVersionInfoMinorCmpInt;
|
|
);
|
|
impl Violation for SysVersionInfoMinorCmpInt {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"`sys.version_info.minor` compared to integer (python4), compare `sys.version_info` \
|
|
to tuple"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SysVersion0Referenced;
|
|
);
|
|
impl Violation for SysVersion0Referenced {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`sys.version[0]` referenced (python10), use `sys.version_info`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SysVersionCmpStr10;
|
|
);
|
|
impl Violation for SysVersionCmpStr10 {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`sys.version` compared to string (python10), use `sys.version_info`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SysVersionSlice1Referenced;
|
|
);
|
|
impl Violation for SysVersionSlice1Referenced {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`sys.version[:1]` referenced (python10), use `sys.version_info`")
|
|
}
|
|
}
|
|
|
|
// 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: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for YodaConditions {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let YodaConditions { suggestion } = self;
|
|
format!("Yoda conditions are discouraged, use `{suggestion}` instead")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let YodaConditions { suggestion } = self;
|
|
format!("Replace Yoda condition with `{suggestion}`")
|
|
}
|
|
}
|
|
|
|
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")
|
|
}
|
|
}
|
|
|
|
// pyupgrade
|
|
|
|
define_violation!(
|
|
pub struct UselessMetaclassType;
|
|
);
|
|
impl AlwaysAutofixableViolation for UselessMetaclassType {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`__metaclass__ = type` is implied")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove `__metaclass__ = type`".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct TypeOfPrimitive {
|
|
pub primitive: Primitive,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for TypeOfPrimitive {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let TypeOfPrimitive { primitive } = self;
|
|
format!("Use `{}` instead of `type(...)`", primitive.builtin())
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let TypeOfPrimitive { primitive } = self;
|
|
format!("Replace `type(...)` with `{}`", primitive.builtin())
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UselessObjectInheritance {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for UselessObjectInheritance {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UselessObjectInheritance { name } = self;
|
|
format!("Class `{name}` inherits from `object`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove `object` inheritance".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct DeprecatedUnittestAlias {
|
|
pub alias: String,
|
|
pub target: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for DeprecatedUnittestAlias {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let DeprecatedUnittestAlias { alias, target } = self;
|
|
format!("`{alias}` is deprecated, use `{target}`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let DeprecatedUnittestAlias { alias, target } = self;
|
|
format!("Replace `{target}` with `{alias}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UsePEP585Annotation {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for UsePEP585Annotation {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UsePEP585Annotation { name } = self;
|
|
format!(
|
|
"Use `{}` instead of `{}` for type annotations",
|
|
name.to_lowercase(),
|
|
name,
|
|
)
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let UsePEP585Annotation { name } = self;
|
|
format!("Replace `{name}` with `{}`", name.to_lowercase(),)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UsePEP604Annotation;
|
|
);
|
|
impl AlwaysAutofixableViolation for UsePEP604Annotation {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use `X | Y` for type annotations")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Convert to `X | Y`".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SuperCallWithParameters;
|
|
);
|
|
impl AlwaysAutofixableViolation for SuperCallWithParameters {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use `super()` instead of `super(__class__, self)`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove `__super__` parameters".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PEP3120UnnecessaryCodingComment;
|
|
);
|
|
impl AlwaysAutofixableViolation for PEP3120UnnecessaryCodingComment {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("UTF-8 encoding declaration is unnecessary")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove unnecessary coding comment".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryFutureImport {
|
|
pub names: Vec<String>,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryFutureImport {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnnecessaryFutureImport { names } = self;
|
|
if names.len() == 1 {
|
|
let import = &names[0];
|
|
format!("Unnecessary `__future__` import `{import}` for target Python version")
|
|
} else {
|
|
let imports = names.iter().map(|name| format!("`{name}`")).join(", ");
|
|
format!("Unnecessary `__future__` imports {imports} for target Python version")
|
|
}
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove unnecessary `__future__` import".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct LRUCacheWithoutParameters;
|
|
);
|
|
impl AlwaysAutofixableViolation for LRUCacheWithoutParameters {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Unnecessary parameters to `functools.lru_cache`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove unnecessary parameters".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryEncodeUTF8;
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryEncodeUTF8 {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Unnecessary call to `encode` as UTF-8")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove unnecessary `encode`".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ConvertTypedDictFunctionalToClass {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for ConvertTypedDictFunctionalToClass {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let ConvertTypedDictFunctionalToClass { name } = self;
|
|
format!("Convert `{name}` from `TypedDict` functional to class syntax")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let ConvertTypedDictFunctionalToClass { name } = self;
|
|
format!("Convert `{name}` to class syntax")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ConvertNamedTupleFunctionalToClass {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for ConvertNamedTupleFunctionalToClass {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let ConvertNamedTupleFunctionalToClass { name } = self;
|
|
format!("Convert `{name}` from `NamedTuple` functional to class syntax")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let ConvertNamedTupleFunctionalToClass { name } = self;
|
|
format!("Convert `{name}` to class syntax")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct RedundantOpenModes {
|
|
pub replacement: Option<String>,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for RedundantOpenModes {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let RedundantOpenModes { replacement } = self;
|
|
match replacement {
|
|
None => format!("Unnecessary open mode parameters"),
|
|
Some(replacement) => {
|
|
format!("Unnecessary open mode parameters, use \"{replacement}\"")
|
|
}
|
|
}
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let RedundantOpenModes { replacement } = self;
|
|
match replacement {
|
|
None => "Remove open mode parameters".to_string(),
|
|
Some(replacement) => {
|
|
format!("Replace with \"{replacement}\"")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct DatetimeTimezoneUTC {
|
|
pub straight_import: bool,
|
|
}
|
|
);
|
|
impl Violation for DatetimeTimezoneUTC {
|
|
const AUTOFIX: Option<AutofixKind> = Some(AutofixKind::new(Availability::Always));
|
|
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use `datetime.UTC` alias")
|
|
}
|
|
|
|
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
|
|
if self.straight_import {
|
|
Some(|_| "Convert to `datetime.UTC` alias".to_string())
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum LiteralType {
|
|
Str,
|
|
Bytes,
|
|
}
|
|
|
|
impl fmt::Display for LiteralType {
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
|
match self {
|
|
LiteralType::Str => fmt.write_str("str"),
|
|
LiteralType::Bytes => fmt.write_str("bytes"),
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NativeLiterals {
|
|
pub literal_type: LiteralType,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for NativeLiterals {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let NativeLiterals { literal_type } = self;
|
|
format!("Unnecessary call to `{literal_type}`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let NativeLiterals { literal_type } = self;
|
|
format!("Replace with `{literal_type}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct TypingTextStrAlias;
|
|
);
|
|
impl AlwaysAutofixableViolation for TypingTextStrAlias {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`typing.Text` is deprecated, use `str`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Replace with `str`".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct OpenAlias;
|
|
);
|
|
impl AlwaysAutofixableViolation for OpenAlias {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use builtin `open`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Replace with builtin `open`".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ReplaceUniversalNewlines;
|
|
);
|
|
impl AlwaysAutofixableViolation for ReplaceUniversalNewlines {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`universal_newlines` is deprecated, use `text`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Replace with `text` keyword argument".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PrintfStringFormatting;
|
|
);
|
|
impl AlwaysAutofixableViolation for PrintfStringFormatting {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use format specifiers instead of percent format")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Replace with format specifiers".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ReplaceStdoutStderr;
|
|
);
|
|
impl AlwaysAutofixableViolation for ReplaceStdoutStderr {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Sending stdout and stderr to pipe is deprecated, use `capture_output`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Replace with `capture_output` keyword argument".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct RewriteCElementTree;
|
|
);
|
|
impl AlwaysAutofixableViolation for RewriteCElementTree {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`cElementTree` is deprecated, use `ElementTree`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Replace with `ElementTree`".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct OSErrorAlias {
|
|
pub name: Option<String>,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for OSErrorAlias {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Replace aliased errors with `OSError`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let OSErrorAlias { name } = self;
|
|
match name {
|
|
None => "Replace with builtin `OSError`".to_string(),
|
|
Some(name) => format!("Replace `{name}` with builtin `OSError`"),
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct RewriteUnicodeLiteral;
|
|
);
|
|
impl AlwaysAutofixableViolation for RewriteUnicodeLiteral {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Remove unicode literals from strings")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove unicode prefix".to_string()
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum MockReference {
|
|
Import,
|
|
Attribute,
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct RewriteMockImport {
|
|
pub reference_type: MockReference,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for RewriteMockImport {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`mock` is deprecated, use `unittest.mock`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let RewriteMockImport { reference_type } = self;
|
|
match reference_type {
|
|
MockReference::Import => "Import from `unittest.mock` instead".to_string(),
|
|
MockReference::Attribute => "Replace `mock.mock` with `mock`".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct RewriteListComprehension;
|
|
);
|
|
impl AlwaysAutofixableViolation for RewriteListComprehension {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Replace unpacked list comprehension with a generator expression")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Replace with generator expression".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct RewriteYieldFrom;
|
|
);
|
|
impl AlwaysAutofixableViolation for RewriteYieldFrom {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Replace `yield` over `for` loop with `yield from`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Replace with `yield from`".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnnecessaryBuiltinImport {
|
|
pub names: Vec<String>,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for UnnecessaryBuiltinImport {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnnecessaryBuiltinImport { names } = self;
|
|
if names.len() == 1 {
|
|
let import = &names[0];
|
|
format!("Unnecessary builtin import: `{import}`")
|
|
} else {
|
|
let imports = names.iter().map(|name| format!("`{name}`")).join(", ");
|
|
format!("Unnecessary builtin imports: {imports}")
|
|
}
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove unnecessary builtin import".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct FormatLiterals;
|
|
);
|
|
impl AlwaysAutofixableViolation for FormatLiterals {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use implicit references for positional format fields")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove explicit positional indexes".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ExtraneousParentheses;
|
|
);
|
|
impl AlwaysAutofixableViolation for ExtraneousParentheses {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Avoid extraneous parentheses")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove extraneous parentheses".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct FString;
|
|
);
|
|
impl AlwaysAutofixableViolation for FString {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use f-string instead of `format` call")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Convert to f-string".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct FunctoolsCache;
|
|
);
|
|
impl AlwaysAutofixableViolation for FunctoolsCache {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use `@functools.cache` instead of `@functools.lru_cache(maxsize=None)`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Rewrite with `@functools.cache".to_string()
|
|
}
|
|
}
|
|
|
|
// pydocstyle
|
|
|
|
define_violation!(
|
|
pub struct PublicModule;
|
|
);
|
|
impl Violation for PublicModule {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Missing docstring in public module")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PublicClass;
|
|
);
|
|
impl Violation for PublicClass {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Missing docstring in public class")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PublicMethod;
|
|
);
|
|
impl Violation for PublicMethod {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Missing docstring in public method")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PublicFunction;
|
|
);
|
|
impl Violation for PublicFunction {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Missing docstring in public function")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PublicPackage;
|
|
);
|
|
impl Violation for PublicPackage {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Missing docstring in public package")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MagicMethod;
|
|
);
|
|
impl Violation for MagicMethod {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Missing docstring in magic method")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PublicNestedClass;
|
|
);
|
|
impl Violation for PublicNestedClass {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Missing docstring in public nested class")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PublicInit;
|
|
);
|
|
impl Violation for PublicInit {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Missing docstring in `__init__`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct FitsOnOneLine;
|
|
);
|
|
impl AlwaysAutofixableViolation for FitsOnOneLine {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("One-line docstring should fit on one line")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Reformat to one line".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NoBlankLineBeforeFunction {
|
|
pub num_lines: usize,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for NoBlankLineBeforeFunction {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let NoBlankLineBeforeFunction { num_lines } = self;
|
|
format!("No blank lines allowed before function docstring (found {num_lines})")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove blank line(s) before function docstring".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NoBlankLineAfterFunction {
|
|
pub num_lines: usize,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for NoBlankLineAfterFunction {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let NoBlankLineAfterFunction { num_lines } = self;
|
|
format!("No blank lines allowed after function docstring (found {num_lines})")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove blank line(s) after function docstring".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct OneBlankLineBeforeClass {
|
|
pub lines: usize,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for OneBlankLineBeforeClass {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("1 blank line required before class docstring")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Insert 1 blank line before class docstring".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct OneBlankLineAfterClass {
|
|
pub lines: usize,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for OneBlankLineAfterClass {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("1 blank line required after class docstring")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Insert 1 blank line after class docstring".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct BlankLineAfterSummary {
|
|
pub num_lines: usize,
|
|
}
|
|
);
|
|
fn fmt_blank_line_after_summary_autofix_msg(_: &BlankLineAfterSummary) -> String {
|
|
"Insert single blank line".to_string()
|
|
}
|
|
impl Violation for BlankLineAfterSummary {
|
|
const AUTOFIX: Option<AutofixKind> = Some(AutofixKind::new(Availability::Always));
|
|
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let BlankLineAfterSummary { num_lines } = self;
|
|
if *num_lines == 0 {
|
|
format!("1 blank line required between summary line and description")
|
|
} else {
|
|
format!(
|
|
"1 blank line required between summary line and description (found {num_lines})"
|
|
)
|
|
}
|
|
}
|
|
|
|
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
|
|
let BlankLineAfterSummary { num_lines } = self;
|
|
if *num_lines > 0 {
|
|
return Some(fmt_blank_line_after_summary_autofix_msg);
|
|
}
|
|
None
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct IndentWithSpaces;
|
|
);
|
|
impl Violation for IndentWithSpaces {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Docstring should be indented with spaces, not tabs")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NoUnderIndentation;
|
|
);
|
|
impl AlwaysAutofixableViolation for NoUnderIndentation {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Docstring is under-indented")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Increase indentation".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NoOverIndentation;
|
|
);
|
|
impl AlwaysAutofixableViolation for NoOverIndentation {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Docstring is over-indented")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove over-indentation".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NewLineAfterLastParagraph;
|
|
);
|
|
impl AlwaysAutofixableViolation for NewLineAfterLastParagraph {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Multi-line docstring closing quotes should be on a separate line")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Move closing quotes to new line".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NoSurroundingWhitespace;
|
|
);
|
|
impl AlwaysAutofixableViolation for NoSurroundingWhitespace {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("No whitespaces allowed surrounding docstring text")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Trim surrounding whitespace".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NoBlankLineBeforeClass {
|
|
pub lines: usize,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for NoBlankLineBeforeClass {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("No blank lines allowed before class docstring")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove blank line(s) before class docstring".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MultiLineSummaryFirstLine;
|
|
);
|
|
impl AlwaysAutofixableViolation for MultiLineSummaryFirstLine {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Multi-line docstring summary should start at the first line")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove whitespace after opening quotes".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MultiLineSummarySecondLine;
|
|
);
|
|
impl AlwaysAutofixableViolation for MultiLineSummarySecondLine {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Multi-line docstring summary should start at the second line")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Insert line break and indentation after opening quotes".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SectionNotOverIndented {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for SectionNotOverIndented {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let SectionNotOverIndented { name } = self;
|
|
format!("Section is over-indented (\"{name}\")")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let SectionNotOverIndented { name } = self;
|
|
format!("Remove over-indentation from \"{name}\"")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SectionUnderlineNotOverIndented {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for SectionUnderlineNotOverIndented {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let SectionUnderlineNotOverIndented { name } = self;
|
|
format!("Section underline is over-indented (\"{name}\")")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let SectionUnderlineNotOverIndented { name } = self;
|
|
format!("Remove over-indentation from \"{name}\" underline")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UsesTripleQuotes;
|
|
);
|
|
impl Violation for UsesTripleQuotes {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(r#"Use """triple double quotes""""#)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UsesRPrefixForBackslashedContent;
|
|
);
|
|
impl Violation for UsesRPrefixForBackslashedContent {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(r#"Use r""" if any backslashes in a docstring"#)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct EndsInPeriod;
|
|
);
|
|
impl AlwaysAutofixableViolation for EndsInPeriod {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("First line should end with a period")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Add period".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NoSignature;
|
|
);
|
|
impl Violation for NoSignature {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("First line should not be the function's signature")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct FirstLineCapitalized;
|
|
);
|
|
impl Violation for FirstLineCapitalized {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("First word of the first line should be properly capitalized")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NoThisPrefix;
|
|
);
|
|
impl Violation for NoThisPrefix {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(r#"First word of the docstring should not be "This""#)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct CapitalizeSectionName {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for CapitalizeSectionName {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let CapitalizeSectionName { name } = self;
|
|
format!("Section name should be properly capitalized (\"{name}\")")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let CapitalizeSectionName { name } = self;
|
|
format!("Capitalize \"{name}\"")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NewLineAfterSectionName {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for NewLineAfterSectionName {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let NewLineAfterSectionName { name } = self;
|
|
format!("Section name should end with a newline (\"{name}\")")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let NewLineAfterSectionName { name } = self;
|
|
format!("Add newline after \"{name}\"")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct DashedUnderlineAfterSection {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for DashedUnderlineAfterSection {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let DashedUnderlineAfterSection { name } = self;
|
|
format!("Missing dashed underline after section (\"{name}\")")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let DashedUnderlineAfterSection { name } = self;
|
|
format!("Add dashed line under \"{name}\"")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SectionUnderlineAfterName {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for SectionUnderlineAfterName {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let SectionUnderlineAfterName { name } = self;
|
|
format!("Section underline should be in the line following the section's name (\"{name}\")")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let SectionUnderlineAfterName { name } = self;
|
|
format!("Add underline to \"{name}\"")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SectionUnderlineMatchesSectionLength {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for SectionUnderlineMatchesSectionLength {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let SectionUnderlineMatchesSectionLength { name } = self;
|
|
format!("Section underline should match the length of its name (\"{name}\")")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let SectionUnderlineMatchesSectionLength { name } = self;
|
|
format!("Adjust underline length to match \"{name}\"")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct BlankLineAfterSection {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for BlankLineAfterSection {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let BlankLineAfterSection { name } = self;
|
|
format!("Missing blank line after section (\"{name}\")")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let BlankLineAfterSection { name } = self;
|
|
format!("Add blank line after \"{name}\"")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct BlankLineBeforeSection {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for BlankLineBeforeSection {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let BlankLineBeforeSection { name } = self;
|
|
format!("Missing blank line before section (\"{name}\")")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let BlankLineBeforeSection { name } = self;
|
|
format!("Add blank line before \"{name}\"")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NoBlankLinesBetweenHeaderAndContent {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for NoBlankLinesBetweenHeaderAndContent {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let NoBlankLinesBetweenHeaderAndContent { name } = self;
|
|
format!("No blank lines allowed between a section header and its content (\"{name}\")")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove blank line(s)".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct BlankLineAfterLastSection {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for BlankLineAfterLastSection {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let BlankLineAfterLastSection { name } = self;
|
|
format!("Missing blank line after last section (\"{name}\")")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let BlankLineAfterLastSection { name } = self;
|
|
format!("Add blank line after \"{name}\"")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NonEmptySection {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for NonEmptySection {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let NonEmptySection { name } = self;
|
|
format!("Section has no content (\"{name}\")")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct EndsInPunctuation;
|
|
);
|
|
impl AlwaysAutofixableViolation for EndsInPunctuation {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("First line should end with a period, question mark, or exclamation point")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Add closing punctuation".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SectionNameEndsInColon {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for SectionNameEndsInColon {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let SectionNameEndsInColon { name } = self;
|
|
format!("Section name should end with a colon (\"{name}\")")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let SectionNameEndsInColon { name } = self;
|
|
format!("Add colon to \"{name}\"")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct DocumentAllArguments {
|
|
pub names: Vec<String>,
|
|
}
|
|
);
|
|
impl Violation for DocumentAllArguments {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let DocumentAllArguments { names } = self;
|
|
if names.len() == 1 {
|
|
let name = &names[0];
|
|
format!("Missing argument description in the docstring: `{name}`")
|
|
} else {
|
|
let names = names.iter().map(|name| format!("`{name}`")).join(", ");
|
|
format!("Missing argument descriptions in the docstring: {names}")
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SkipDocstring;
|
|
);
|
|
impl Violation for SkipDocstring {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Function decorated with `@overload` shouldn't contain a docstring")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NonEmpty;
|
|
);
|
|
impl Violation for NonEmpty {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Docstring is empty")
|
|
}
|
|
}
|
|
|
|
// pep8-naming
|
|
|
|
define_violation!(
|
|
pub struct InvalidClassName {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for InvalidClassName {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let InvalidClassName { name } = self;
|
|
format!("Class name `{name}` should use CapWords convention ")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct InvalidFunctionName {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for InvalidFunctionName {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let InvalidFunctionName { name } = self;
|
|
format!("Function name `{name}` should be lowercase")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct InvalidArgumentName {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for InvalidArgumentName {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let InvalidArgumentName { name } = self;
|
|
format!("Argument name `{name}` should be lowercase")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct InvalidFirstArgumentNameForClassMethod;
|
|
);
|
|
impl Violation for InvalidFirstArgumentNameForClassMethod {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("First argument of a class method should be named `cls`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct InvalidFirstArgumentNameForMethod;
|
|
);
|
|
impl Violation for InvalidFirstArgumentNameForMethod {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("First argument of a method should be named `self`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct NonLowercaseVariableInFunction {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for NonLowercaseVariableInFunction {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let NonLowercaseVariableInFunction { name } = self;
|
|
format!("Variable `{name}` in function should be lowercase")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct DunderFunctionName;
|
|
);
|
|
impl Violation for DunderFunctionName {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Function name should not start and end with `__`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ConstantImportedAsNonConstant {
|
|
pub name: String,
|
|
pub asname: String,
|
|
}
|
|
);
|
|
impl Violation for ConstantImportedAsNonConstant {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let ConstantImportedAsNonConstant { name, asname } = self;
|
|
format!("Constant `{name}` imported as non-constant `{asname}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct LowercaseImportedAsNonLowercase {
|
|
pub name: String,
|
|
pub asname: String,
|
|
}
|
|
);
|
|
impl Violation for LowercaseImportedAsNonLowercase {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let LowercaseImportedAsNonLowercase { name, asname } = self;
|
|
format!("Lowercase `{name}` imported as non-lowercase `{asname}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct CamelcaseImportedAsLowercase {
|
|
pub name: String,
|
|
pub asname: String,
|
|
}
|
|
);
|
|
impl Violation for CamelcaseImportedAsLowercase {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let CamelcaseImportedAsLowercase { name, asname } = self;
|
|
format!("Camelcase `{name}` imported as lowercase `{asname}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct CamelcaseImportedAsConstant {
|
|
pub name: String,
|
|
pub asname: String,
|
|
}
|
|
);
|
|
impl Violation for CamelcaseImportedAsConstant {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let CamelcaseImportedAsConstant { name, asname } = self;
|
|
format!("Camelcase `{name}` imported as constant `{asname}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MixedCaseVariableInClassScope {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for MixedCaseVariableInClassScope {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let MixedCaseVariableInClassScope { name } = self;
|
|
format!("Variable `{name}` in class scope should not be mixedCase")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct MixedCaseVariableInGlobalScope {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for MixedCaseVariableInGlobalScope {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let MixedCaseVariableInGlobalScope { name } = self;
|
|
format!("Variable `{name}` in global scope should not be mixedCase")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct CamelcaseImportedAsAcronym {
|
|
pub name: String,
|
|
pub asname: String,
|
|
}
|
|
);
|
|
impl Violation for CamelcaseImportedAsAcronym {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let CamelcaseImportedAsAcronym { name, asname } = self;
|
|
format!("Camelcase `{name}` imported as acronym `{asname}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ErrorSuffixOnExceptionName {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for ErrorSuffixOnExceptionName {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let ErrorSuffixOnExceptionName { name } = self;
|
|
format!("Exception name `{name}` should be named with an Error suffix")
|
|
}
|
|
}
|
|
|
|
// flake8-bandit
|
|
|
|
define_violation!(
|
|
pub struct Jinja2AutoescapeFalse {
|
|
pub value: bool,
|
|
}
|
|
);
|
|
impl Violation for Jinja2AutoescapeFalse {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let Jinja2AutoescapeFalse { value } = self;
|
|
match value {
|
|
true => format!(
|
|
"Using jinja2 templates with `autoescape=False` is dangerous and can lead to XSS. \
|
|
Ensure `autoescape=True` or use the `select_autoescape` function."
|
|
),
|
|
false => format!(
|
|
"By default, jinja2 sets `autoescape` to `False`. Consider using \
|
|
`autoescape=True` or the `select_autoescape` function to mitigate XSS \
|
|
vulnerabilities."
|
|
),
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct AssertUsed;
|
|
);
|
|
impl Violation for AssertUsed {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use of `assert` detected")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ExecUsed;
|
|
);
|
|
impl Violation for ExecUsed {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use of `exec` detected")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct BadFilePermissions {
|
|
pub mask: u16,
|
|
}
|
|
);
|
|
impl Violation for BadFilePermissions {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let BadFilePermissions { mask } = self;
|
|
format!("`os.chmod` setting a permissive mask `{mask:#o}` on file or directory",)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct HardcodedBindAllInterfaces;
|
|
);
|
|
impl Violation for HardcodedBindAllInterfaces {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Possible binding to all interfaces")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct HardcodedPasswordString {
|
|
pub string: String,
|
|
}
|
|
);
|
|
impl Violation for HardcodedPasswordString {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let HardcodedPasswordString { string } = self;
|
|
format!("Possible hardcoded password: \"{}\"", string.escape_debug())
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct HardcodedPasswordFuncArg {
|
|
pub string: String,
|
|
}
|
|
);
|
|
impl Violation for HardcodedPasswordFuncArg {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let HardcodedPasswordFuncArg { string } = self;
|
|
format!("Possible hardcoded password: \"{}\"", string.escape_debug())
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct HardcodedPasswordDefault {
|
|
pub string: String,
|
|
}
|
|
);
|
|
impl Violation for HardcodedPasswordDefault {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let HardcodedPasswordDefault { string } = self;
|
|
format!("Possible hardcoded password: \"{}\"", string.escape_debug())
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct HardcodedTempFile {
|
|
pub string: String,
|
|
}
|
|
);
|
|
impl Violation for HardcodedTempFile {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let HardcodedTempFile { string } = self;
|
|
format!(
|
|
"Probable insecure usage of temporary file or directory: \"{}\"",
|
|
string.escape_debug()
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct RequestWithoutTimeout {
|
|
pub timeout: Option<String>,
|
|
}
|
|
);
|
|
impl Violation for RequestWithoutTimeout {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let RequestWithoutTimeout { timeout } = self;
|
|
match timeout {
|
|
Some(value) => {
|
|
format!("Probable use of requests call with timeout set to `{value}`")
|
|
}
|
|
None => format!("Probable use of requests call without timeout"),
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct HashlibInsecureHashFunction {
|
|
pub string: String,
|
|
}
|
|
);
|
|
impl Violation for HashlibInsecureHashFunction {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let HashlibInsecureHashFunction { string } = self;
|
|
format!(
|
|
"Probable use of insecure hash functions in `hashlib`: \"{}\"",
|
|
string.escape_debug()
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct RequestWithNoCertValidation {
|
|
pub string: String,
|
|
}
|
|
);
|
|
impl Violation for RequestWithNoCertValidation {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let RequestWithNoCertValidation { string } = self;
|
|
format!(
|
|
"Probable use of `{string}` call with `verify=False` disabling SSL certificate checks"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnsafeYAMLLoad {
|
|
pub loader: Option<String>,
|
|
}
|
|
);
|
|
impl Violation for UnsafeYAMLLoad {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnsafeYAMLLoad { loader } = self;
|
|
match loader {
|
|
Some(name) => {
|
|
format!(
|
|
"Probable use of unsafe loader `{name}` with `yaml.load`. Allows \
|
|
instantiation of arbitrary objects. Consider `yaml.safe_load`."
|
|
)
|
|
}
|
|
None => format!(
|
|
"Probable use of unsafe `yaml.load`. Allows instantiation of arbitrary objects. \
|
|
Consider `yaml.safe_load`."
|
|
),
|
|
}
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SnmpInsecureVersion;
|
|
);
|
|
impl Violation for SnmpInsecureVersion {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("The use of SNMPv1 and SNMPv2 is insecure. Use SNMPv3 if able.")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct SnmpWeakCryptography;
|
|
);
|
|
impl Violation for SnmpWeakCryptography {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"You should not use SNMPv3 without encryption. `noAuthNoPriv` & `authNoPriv` is \
|
|
insecure."
|
|
)
|
|
}
|
|
}
|
|
|
|
// flake8-unused-arguments
|
|
|
|
define_violation!(
|
|
pub struct UnusedFunctionArgument {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for UnusedFunctionArgument {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnusedFunctionArgument { name } = self;
|
|
format!("Unused function argument: `{name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnusedMethodArgument {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for UnusedMethodArgument {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnusedMethodArgument { name } = self;
|
|
format!("Unused method argument: `{name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnusedClassMethodArgument {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for UnusedClassMethodArgument {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnusedClassMethodArgument { name } = self;
|
|
format!("Unused class method argument: `{name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnusedStaticMethodArgument {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for UnusedStaticMethodArgument {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnusedStaticMethodArgument { name } = self;
|
|
format!("Unused static method argument: `{name}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnusedLambdaArgument {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for UnusedLambdaArgument {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnusedLambdaArgument { name } = self;
|
|
format!("Unused lambda argument: `{name}`")
|
|
}
|
|
}
|
|
|
|
// flake8-datetimez
|
|
|
|
define_violation!(
|
|
pub struct CallDatetimeWithoutTzinfo;
|
|
);
|
|
impl Violation for CallDatetimeWithoutTzinfo {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("The use of `datetime.datetime()` without `tzinfo` argument is not allowed")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct CallDatetimeToday;
|
|
);
|
|
impl Violation for CallDatetimeToday {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"The use of `datetime.datetime.today()` is not allowed, use \
|
|
`datetime.datetime.now(tz=)` instead"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct CallDatetimeUtcnow;
|
|
);
|
|
impl Violation for CallDatetimeUtcnow {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"The use of `datetime.datetime.utcnow()` is not allowed, use \
|
|
`datetime.datetime.now(tz=)` instead"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct CallDatetimeUtcfromtimestamp;
|
|
);
|
|
impl Violation for CallDatetimeUtcfromtimestamp {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"The use of `datetime.datetime.utcfromtimestamp()` is not allowed, use \
|
|
`datetime.datetime.fromtimestamp(ts, tz=)` instead"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct CallDatetimeNowWithoutTzinfo;
|
|
);
|
|
impl Violation for CallDatetimeNowWithoutTzinfo {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("The use of `datetime.datetime.now()` without `tz` argument is not allowed")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct CallDatetimeFromtimestamp;
|
|
);
|
|
impl Violation for CallDatetimeFromtimestamp {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"The use of `datetime.datetime.fromtimestamp()` without `tz` argument is not allowed"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct CallDatetimeStrptimeWithoutZone;
|
|
);
|
|
impl Violation for CallDatetimeStrptimeWithoutZone {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"The use of `datetime.datetime.strptime()` without %z must be followed by \
|
|
`.replace(tzinfo=)` or `.astimezone()`"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct CallDateToday;
|
|
);
|
|
impl Violation for CallDateToday {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"The use of `datetime.date.today()` is not allowed, use \
|
|
`datetime.datetime.now(tz=).date()` instead"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct CallDateFromtimestamp;
|
|
);
|
|
impl Violation for CallDateFromtimestamp {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"The use of `datetime.date.fromtimestamp()` is not allowed, use \
|
|
`datetime.datetime.fromtimestamp(ts, tz=).date()` instead"
|
|
)
|
|
}
|
|
}
|
|
|
|
// pygrep-hooks
|
|
|
|
define_violation!(
|
|
pub struct NoEval;
|
|
);
|
|
impl Violation for NoEval {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("No builtin `eval()` allowed")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct DeprecatedLogWarn;
|
|
);
|
|
impl Violation for DeprecatedLogWarn {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`warn` is deprecated in favor of `warning`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct BlanketTypeIgnore;
|
|
);
|
|
impl Violation for BlanketTypeIgnore {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use specific rule codes when ignoring type issues")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct BlanketNOQA;
|
|
);
|
|
impl Violation for BlanketNOQA {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use specific rule codes when using `noqa`")
|
|
}
|
|
}
|
|
|
|
// pandas-vet
|
|
|
|
define_violation!(
|
|
pub struct UseOfInplaceArgument;
|
|
);
|
|
impl Violation for UseOfInplaceArgument {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`inplace=True` should be avoided; it has inconsistent behavior")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UseOfDotIsNull;
|
|
);
|
|
impl Violation for UseOfDotIsNull {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`.isna` is preferred to `.isnull`; functionality is equivalent")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UseOfDotNotNull;
|
|
);
|
|
impl Violation for UseOfDotNotNull {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`.notna` is preferred to `.notnull`; functionality is equivalent")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UseOfDotIx;
|
|
);
|
|
impl Violation for UseOfDotIx {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`.ix` is deprecated; use more explicit `.loc` or `.iloc`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UseOfDotAt;
|
|
);
|
|
impl Violation for UseOfDotAt {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use `.loc` instead of `.at`. If speed is important, use numpy.")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UseOfDotIat;
|
|
);
|
|
impl Violation for UseOfDotIat {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use `.iloc` instead of `.iat`. If speed is important, use numpy.")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UseOfDotPivotOrUnstack;
|
|
);
|
|
impl Violation for UseOfDotPivotOrUnstack {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"`.pivot_table` is preferred to `.pivot` or `.unstack`; provides same functionality"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UseOfDotValues;
|
|
);
|
|
impl Violation for UseOfDotValues {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use `.to_numpy()` instead of `.values`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UseOfDotReadTable;
|
|
);
|
|
impl Violation for UseOfDotReadTable {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`.read_csv` is preferred to `.read_table`; provides same functionality")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UseOfDotStack;
|
|
);
|
|
impl Violation for UseOfDotStack {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`.melt` is preferred to `.stack`; provides same functionality")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UseOfPdMerge;
|
|
);
|
|
impl Violation for UseOfPdMerge {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!(
|
|
"Use `.merge` method instead of `pd.merge` function. They have equivalent \
|
|
functionality."
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct DfIsABadVariableName;
|
|
);
|
|
impl Violation for DfIsABadVariableName {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`df` is a bad variable name. Be kinder to your future self.")
|
|
}
|
|
}
|
|
|
|
// flake8-errmsg
|
|
|
|
define_violation!(
|
|
pub struct RawStringInException;
|
|
);
|
|
impl Violation for RawStringInException {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Exception must not use a string literal, assign to variable first")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct FStringInException;
|
|
);
|
|
impl Violation for FStringInException {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Exception must not use an f-string literal, assign to variable first")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct DotFormatInException;
|
|
);
|
|
impl Violation for DotFormatInException {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Exception must not use a `.format()` string directly, assign to variable first")
|
|
}
|
|
}
|
|
|
|
// flake8-pytest-style
|
|
|
|
define_violation!(
|
|
pub struct ParametrizeNamesWrongType {
|
|
pub expected: ParametrizeNameType,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for ParametrizeNamesWrongType {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let ParametrizeNamesWrongType { expected } = self;
|
|
format!("Wrong name(s) type in `@pytest.mark.parametrize`, expected `{expected}`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let ParametrizeNamesWrongType { expected } = self;
|
|
format!("Use a `{expected}` for parameter names")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct ParametrizeValuesWrongType {
|
|
pub values: ParametrizeValuesType,
|
|
pub row: ParametrizeValuesRowType,
|
|
}
|
|
);
|
|
impl Violation for ParametrizeValuesWrongType {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let ParametrizeValuesWrongType { values, row } = self;
|
|
format!("Wrong values type in `@pytest.mark.parametrize` expected `{values}` of `{row}`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct PatchWithLambda;
|
|
);
|
|
impl Violation for PatchWithLambda {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Use `return_value=` instead of patching with `lambda`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnittestAssertion {
|
|
pub assertion: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for UnittestAssertion {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnittestAssertion { assertion } = self;
|
|
format!("Use a regular `assert` instead of unittest-style `{assertion}`")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let UnittestAssertion { assertion } = self;
|
|
format!("Replace `{assertion}(...)` with `assert ...`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct RaisesWithoutException;
|
|
);
|
|
impl Violation for RaisesWithoutException {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("set the expected exception in `pytest.raises()`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct RaisesTooBroad {
|
|
pub exception: String,
|
|
}
|
|
);
|
|
impl Violation for RaisesTooBroad {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let RaisesTooBroad { exception } = self;
|
|
format!(
|
|
"`pytest.raises({exception})` is too broad, set the `match` parameter or use a more \
|
|
specific exception"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct RaisesWithMultipleStatements;
|
|
);
|
|
impl Violation for RaisesWithMultipleStatements {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("`pytest.raises()` block should contain a single simple statement")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct IncorrectPytestImport;
|
|
);
|
|
impl Violation for IncorrectPytestImport {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Found incorrect import of pytest, use simple `import pytest` instead")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct AssertAlwaysFalse;
|
|
);
|
|
impl Violation for AssertAlwaysFalse {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Assertion always fails, replace with `pytest.fail()`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct FailWithoutMessage;
|
|
);
|
|
impl Violation for FailWithoutMessage {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("No message passed to `pytest.fail()`")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct AssertInExcept {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for AssertInExcept {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let AssertInExcept { name } = self;
|
|
format!(
|
|
"Found assertion on exception `{name}` in except block, use `pytest.raises()` instead"
|
|
)
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct CompositeAssertion;
|
|
);
|
|
impl Violation for CompositeAssertion {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Assertion should be broken down into multiple parts")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct IncorrectMarkParenthesesStyle {
|
|
pub mark_name: String,
|
|
pub expected_parens: String,
|
|
pub actual_parens: String,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for IncorrectMarkParenthesesStyle {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let IncorrectMarkParenthesesStyle {
|
|
mark_name,
|
|
expected_parens,
|
|
actual_parens,
|
|
} = self;
|
|
format!(
|
|
"Use `@pytest.mark.{mark_name}{expected_parens}` over \
|
|
`@pytest.mark.{mark_name}{actual_parens}`"
|
|
)
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Add/remove parentheses".to_string()
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UseFixturesWithoutParameters;
|
|
);
|
|
impl AlwaysAutofixableViolation for UseFixturesWithoutParameters {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
format!("Useless `pytest.mark.usefixtures` without parameters")
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove `usefixtures` decorator or pass parameters".to_string()
|
|
}
|
|
}
|
|
|
|
// ruff
|
|
|
|
define_violation!(
|
|
pub struct AmbiguousUnicodeCharacterString {
|
|
pub confusable: char,
|
|
pub representant: char,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for AmbiguousUnicodeCharacterString {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let AmbiguousUnicodeCharacterString {
|
|
confusable,
|
|
representant,
|
|
} = self;
|
|
format!(
|
|
"String contains ambiguous unicode character '{confusable}' (did you mean \
|
|
'{representant}'?)"
|
|
)
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let AmbiguousUnicodeCharacterString {
|
|
confusable,
|
|
representant,
|
|
} = self;
|
|
format!("Replace '{confusable}' with '{representant}'")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct AmbiguousUnicodeCharacterDocstring {
|
|
pub confusable: char,
|
|
pub representant: char,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for AmbiguousUnicodeCharacterDocstring {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let AmbiguousUnicodeCharacterDocstring {
|
|
confusable,
|
|
representant,
|
|
} = self;
|
|
format!(
|
|
"Docstring contains ambiguous unicode character '{confusable}' (did you mean \
|
|
'{representant}'?)"
|
|
)
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let AmbiguousUnicodeCharacterDocstring {
|
|
confusable,
|
|
representant,
|
|
} = self;
|
|
format!("Replace '{confusable}' with '{representant}'")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct AmbiguousUnicodeCharacterComment {
|
|
pub confusable: char,
|
|
pub representant: char,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for AmbiguousUnicodeCharacterComment {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let AmbiguousUnicodeCharacterComment {
|
|
confusable,
|
|
representant,
|
|
} = self;
|
|
format!(
|
|
"Comment contains ambiguous unicode character '{confusable}' (did you mean \
|
|
'{representant}'?)"
|
|
)
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
let AmbiguousUnicodeCharacterComment {
|
|
confusable,
|
|
representant,
|
|
} = self;
|
|
format!("Replace '{confusable}' with '{representant}'")
|
|
}
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct KeywordArgumentBeforeStarArgument {
|
|
pub name: String,
|
|
}
|
|
);
|
|
impl Violation for KeywordArgumentBeforeStarArgument {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let KeywordArgumentBeforeStarArgument { name } = self;
|
|
format!("Keyword argument `{name}` must come after starred arguments")
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct UnusedCodes {
|
|
pub unknown: Vec<String>,
|
|
pub disabled: Vec<String>,
|
|
pub unmatched: Vec<String>,
|
|
}
|
|
|
|
define_violation!(
|
|
pub struct UnusedNOQA {
|
|
pub codes: Option<UnusedCodes>,
|
|
}
|
|
);
|
|
impl AlwaysAutofixableViolation for UnusedNOQA {
|
|
#[derive_message_formats]
|
|
fn message(&self) -> String {
|
|
let UnusedNOQA { codes } = self;
|
|
match codes {
|
|
None => format!("Unused blanket `noqa` directive"),
|
|
Some(codes) => {
|
|
let mut codes_by_reason = vec![];
|
|
if !codes.unmatched.is_empty() {
|
|
codes_by_reason.push(format!(
|
|
"unused: {}",
|
|
codes
|
|
.unmatched
|
|
.iter()
|
|
.map(|code| format!("`{code}`"))
|
|
.join(", ")
|
|
));
|
|
}
|
|
if !codes.disabled.is_empty() {
|
|
codes_by_reason.push(format!(
|
|
"non-enabled: {}",
|
|
codes
|
|
.disabled
|
|
.iter()
|
|
.map(|code| format!("`{code}`"))
|
|
.join(", ")
|
|
));
|
|
}
|
|
if !codes.unknown.is_empty() {
|
|
codes_by_reason.push(format!(
|
|
"unknown: {}",
|
|
codes
|
|
.unknown
|
|
.iter()
|
|
.map(|code| format!("`{code}`"))
|
|
.join(", ")
|
|
));
|
|
}
|
|
if codes_by_reason.is_empty() {
|
|
format!("Unused `noqa` directive")
|
|
} else {
|
|
format!("Unused `noqa` directive ({})", codes_by_reason.join("; "))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn autofix_title(&self) -> String {
|
|
"Remove unused `noqa` directive".to_string()
|
|
}
|
|
}
|