mirror of https://github.com/astral-sh/ruff
6289 lines
158 KiB
Rust
6289 lines
158 KiB
Rust
use std::fmt;
|
||
|
||
use itertools::Itertools;
|
||
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, Violation};
|
||
|
||
// pycodestyle errors
|
||
|
||
define_violation!(
|
||
pub struct MultipleImportsOnOneLine;
|
||
);
|
||
impl Violation for MultipleImportsOnOneLine {
|
||
fn message(&self) -> String {
|
||
"Multiple imports on one line".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MultipleImportsOnOneLine
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ModuleImportNotAtTopOfFile;
|
||
);
|
||
impl Violation for ModuleImportNotAtTopOfFile {
|
||
fn message(&self) -> String {
|
||
"Module level import not at top of file".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ModuleImportNotAtTopOfFile
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct LineTooLong(pub usize, pub usize);
|
||
);
|
||
impl Violation for LineTooLong {
|
||
fn message(&self) -> String {
|
||
let LineTooLong(length, limit) = self;
|
||
format!("Line too long ({length} > {limit} characters)")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
LineTooLong(89, 88)
|
||
}
|
||
}
|
||
|
||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||
pub enum EqCmpop {
|
||
Eq,
|
||
NotEq,
|
||
}
|
||
|
||
impl From<&Cmpop> for EqCmpop {
|
||
fn from(cmpop: &Cmpop) -> Self {
|
||
match cmpop {
|
||
Cmpop::Eq => EqCmpop::Eq,
|
||
Cmpop::NotEq => EqCmpop::NotEq,
|
||
_ => unreachable!("Expected Cmpop::Eq | Cmpop::NotEq"),
|
||
}
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NoneComparison(pub EqCmpop);
|
||
);
|
||
impl AlwaysAutofixableViolation for NoneComparison {
|
||
fn message(&self) -> String {
|
||
let NoneComparison(op) = self;
|
||
match op {
|
||
EqCmpop::Eq => "Comparison to `None` should be `cond is None`".to_string(),
|
||
EqCmpop::NotEq => "Comparison to `None` should be `cond is not None`".to_string(),
|
||
}
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
let NoneComparison(op) = self;
|
||
match op {
|
||
EqCmpop::Eq => "Replace with `cond is None`".to_string(),
|
||
EqCmpop::NotEq => "Replace with `cond is not None`".to_string(),
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NoneComparison(EqCmpop::Eq)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct TrueFalseComparison(pub bool, pub EqCmpop);
|
||
);
|
||
impl AlwaysAutofixableViolation for TrueFalseComparison {
|
||
fn message(&self) -> String {
|
||
let TrueFalseComparison(value, op) = self;
|
||
match (value, op) {
|
||
(true, EqCmpop::Eq) => "Comparison to `True` should be `cond is True`".to_string(),
|
||
(true, EqCmpop::NotEq) => {
|
||
"Comparison to `True` should be `cond is not True`".to_string()
|
||
}
|
||
(false, EqCmpop::Eq) => "Comparison to `False` should be `cond is False`".to_string(),
|
||
(false, EqCmpop::NotEq) => {
|
||
"Comparison to `False` should be `cond is not False`".to_string()
|
||
}
|
||
}
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
let TrueFalseComparison(value, op) = self;
|
||
match (value, op) {
|
||
(true, EqCmpop::Eq) => "Replace with `cond is True`".to_string(),
|
||
(true, EqCmpop::NotEq) => "Replace with `cond is not True`".to_string(),
|
||
(false, EqCmpop::Eq) => "Replace with `cond is False`".to_string(),
|
||
(false, EqCmpop::NotEq) => "Replace with `cond is not False`".to_string(),
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
TrueFalseComparison(true, EqCmpop::Eq)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NotInTest;
|
||
);
|
||
impl AlwaysAutofixableViolation for NotInTest {
|
||
fn message(&self) -> String {
|
||
"Test for membership should be `not in`".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Convert to `not in`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NotInTest
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NotIsTest;
|
||
);
|
||
impl AlwaysAutofixableViolation for NotIsTest {
|
||
fn message(&self) -> String {
|
||
"Test for object identity should be `is not`".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Convert to `is not`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NotIsTest
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct TypeComparison;
|
||
);
|
||
impl Violation for TypeComparison {
|
||
fn message(&self) -> String {
|
||
"Do not compare types, use `isinstance()`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
TypeComparison
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DoNotUseBareExcept;
|
||
);
|
||
impl Violation for DoNotUseBareExcept {
|
||
fn message(&self) -> String {
|
||
"Do not use bare `except`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DoNotUseBareExcept
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DoNotAssignLambda(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for DoNotAssignLambda {
|
||
fn message(&self) -> String {
|
||
"Do not assign a `lambda` expression, use a `def`".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
let DoNotAssignLambda(name) = self;
|
||
format!("Rewrite `{name}` as a `def`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DoNotAssignLambda("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AmbiguousVariableName(pub String);
|
||
);
|
||
impl Violation for AmbiguousVariableName {
|
||
fn message(&self) -> String {
|
||
let AmbiguousVariableName(name) = self;
|
||
format!("Ambiguous variable name: `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AmbiguousVariableName("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AmbiguousClassName(pub String);
|
||
);
|
||
impl Violation for AmbiguousClassName {
|
||
fn message(&self) -> String {
|
||
let AmbiguousClassName(name) = self;
|
||
format!("Ambiguous class name: `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AmbiguousClassName("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AmbiguousFunctionName(pub String);
|
||
);
|
||
impl Violation for AmbiguousFunctionName {
|
||
fn message(&self) -> String {
|
||
let AmbiguousFunctionName(name) = self;
|
||
format!("Ambiguous function name: `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AmbiguousFunctionName("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct IOError(pub String);
|
||
);
|
||
impl Violation for IOError {
|
||
fn message(&self) -> String {
|
||
let IOError(message) = self;
|
||
message.clone()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
IOError("IOError: `...`".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SyntaxError(pub String);
|
||
);
|
||
impl Violation for SyntaxError {
|
||
fn message(&self) -> String {
|
||
let SyntaxError(message) = self;
|
||
format!("SyntaxError: {message}")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SyntaxError("`...`".to_string())
|
||
}
|
||
}
|
||
|
||
// pycodestyle warnings
|
||
|
||
define_violation!(
|
||
pub struct NoNewLineAtEndOfFile;
|
||
);
|
||
impl AlwaysAutofixableViolation for NoNewLineAtEndOfFile {
|
||
fn message(&self) -> String {
|
||
"No newline at end of file".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Add trailing newline".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NoNewLineAtEndOfFile
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct InvalidEscapeSequence(pub char);
|
||
);
|
||
impl AlwaysAutofixableViolation for InvalidEscapeSequence {
|
||
fn message(&self) -> String {
|
||
let InvalidEscapeSequence(char) = self;
|
||
format!("Invalid escape sequence: '\\{char}'")
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Add backslash to escape sequence".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
InvalidEscapeSequence('c')
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DocLineTooLong(pub usize, pub usize);
|
||
);
|
||
impl Violation for DocLineTooLong {
|
||
fn message(&self) -> String {
|
||
let DocLineTooLong(length, limit) = self;
|
||
format!("Doc line too long ({length} > {limit} characters)")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DocLineTooLong(89, 88)
|
||
}
|
||
}
|
||
|
||
// pyflakes
|
||
|
||
define_violation!(
|
||
pub struct UnusedImport(pub String, pub bool, pub 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 {
|
||
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)
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnusedImport("...".to_string(), false, false)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ImportShadowedByLoopVar(pub String, pub usize);
|
||
);
|
||
impl Violation for ImportShadowedByLoopVar {
|
||
fn message(&self) -> String {
|
||
let ImportShadowedByLoopVar(name, line) = self;
|
||
format!("Import `{name}` from line {line} shadowed by loop variable")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ImportShadowedByLoopVar("...".to_string(), 1)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ImportStarUsed(pub String);
|
||
);
|
||
impl Violation for ImportStarUsed {
|
||
fn message(&self) -> String {
|
||
let ImportStarUsed(name) = self;
|
||
format!("`from {name} import *` used; unable to detect undefined names")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ImportStarUsed("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct LateFutureImport;
|
||
);
|
||
impl Violation for LateFutureImport {
|
||
fn message(&self) -> String {
|
||
"`from __future__` imports must occur at the beginning of the file".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
LateFutureImport
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ImportStarUsage(pub String, pub Vec<String>);
|
||
);
|
||
impl Violation for ImportStarUsage {
|
||
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}")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ImportStarUsage("...".to_string(), vec!["...".to_string()])
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ImportStarNotPermitted(pub String);
|
||
);
|
||
impl Violation for ImportStarNotPermitted {
|
||
fn message(&self) -> String {
|
||
let ImportStarNotPermitted(name) = self;
|
||
format!("`from {name} import *` only allowed at module level")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ImportStarNotPermitted("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct FutureFeatureNotDefined(pub String);
|
||
);
|
||
impl Violation for FutureFeatureNotDefined {
|
||
fn message(&self) -> String {
|
||
let FutureFeatureNotDefined(name) = self;
|
||
format!("Future feature `{name}` is not defined")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FutureFeatureNotDefined("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PercentFormatInvalidFormat(pub String);
|
||
);
|
||
impl Violation for PercentFormatInvalidFormat {
|
||
fn message(&self) -> String {
|
||
let PercentFormatInvalidFormat(message) = self;
|
||
format!("'...' % ... has invalid format string: {message}")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PercentFormatInvalidFormat("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PercentFormatExpectedMapping;
|
||
);
|
||
impl Violation for PercentFormatExpectedMapping {
|
||
fn message(&self) -> String {
|
||
"'...' % ... expected mapping but got sequence".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PercentFormatExpectedMapping
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PercentFormatExpectedSequence;
|
||
);
|
||
impl Violation for PercentFormatExpectedSequence {
|
||
fn message(&self) -> String {
|
||
"'...' % ... expected sequence but got mapping".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PercentFormatExpectedSequence
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PercentFormatExtraNamedArguments(pub Vec<String>);
|
||
);
|
||
impl AlwaysAutofixableViolation for PercentFormatExtraNamedArguments {
|
||
fn message(&self) -> String {
|
||
let PercentFormatExtraNamedArguments(missing) = self;
|
||
let message = missing.join(", ");
|
||
format!("'...' % ... 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}")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PercentFormatExtraNamedArguments(vec!["...".to_string()])
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PercentFormatMissingArgument(pub Vec<String>);
|
||
);
|
||
impl Violation for PercentFormatMissingArgument {
|
||
fn message(&self) -> String {
|
||
let PercentFormatMissingArgument(missing) = self;
|
||
let message = missing.join(", ");
|
||
format!("'...' % ... is missing argument(s) for placeholder(s): {message}")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PercentFormatMissingArgument(vec!["...".to_string()])
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PercentFormatMixedPositionalAndNamed;
|
||
);
|
||
impl Violation for PercentFormatMixedPositionalAndNamed {
|
||
fn message(&self) -> String {
|
||
"'...' % ... has mixed positional and named placeholders".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PercentFormatMixedPositionalAndNamed
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PercentFormatPositionalCountMismatch(pub usize, pub usize);
|
||
);
|
||
impl Violation for PercentFormatPositionalCountMismatch {
|
||
fn message(&self) -> String {
|
||
let PercentFormatPositionalCountMismatch(wanted, got) = self;
|
||
format!("'...' % ... has {wanted} placeholder(s) but {got} substitution(s)")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PercentFormatPositionalCountMismatch(4, 2)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PercentFormatStarRequiresSequence;
|
||
);
|
||
impl Violation for PercentFormatStarRequiresSequence {
|
||
fn message(&self) -> String {
|
||
"'...' % ... `*` specifier requires sequence".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PercentFormatStarRequiresSequence
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PercentFormatUnsupportedFormatCharacter(pub char);
|
||
);
|
||
impl Violation for PercentFormatUnsupportedFormatCharacter {
|
||
fn message(&self) -> String {
|
||
let PercentFormatUnsupportedFormatCharacter(char) = self;
|
||
format!("'...' % ... has unsupported format character '{char}'")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PercentFormatUnsupportedFormatCharacter('c')
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct StringDotFormatInvalidFormat(pub String);
|
||
);
|
||
impl Violation for StringDotFormatInvalidFormat {
|
||
fn message(&self) -> String {
|
||
let StringDotFormatInvalidFormat(message) = self;
|
||
format!("'...'.format(...) has invalid format string: {message}")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
StringDotFormatInvalidFormat("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct StringDotFormatExtraNamedArguments(pub Vec<String>);
|
||
);
|
||
impl AlwaysAutofixableViolation for StringDotFormatExtraNamedArguments {
|
||
fn message(&self) -> String {
|
||
let StringDotFormatExtraNamedArguments(missing) = self;
|
||
let message = missing.join(", ");
|
||
format!("'...'.format(...) 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}")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
StringDotFormatExtraNamedArguments(vec!["...".to_string()])
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct StringDotFormatExtraPositionalArguments(pub Vec<String>);
|
||
);
|
||
impl Violation for StringDotFormatExtraPositionalArguments {
|
||
fn message(&self) -> String {
|
||
let StringDotFormatExtraPositionalArguments(missing) = self;
|
||
let message = missing.join(", ");
|
||
format!("'...'.format(...) has unused arguments at position(s): {message}")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
StringDotFormatExtraPositionalArguments(vec!["...".to_string()])
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct StringDotFormatMissingArguments(pub Vec<String>);
|
||
);
|
||
impl Violation for StringDotFormatMissingArguments {
|
||
fn message(&self) -> String {
|
||
let StringDotFormatMissingArguments(missing) = self;
|
||
let message = missing.join(", ");
|
||
format!("'...'.format(...) is missing argument(s) for placeholder(s): {message}")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
StringDotFormatMissingArguments(vec!["...".to_string()])
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct StringDotFormatMixingAutomatic;
|
||
);
|
||
impl Violation for StringDotFormatMixingAutomatic {
|
||
fn message(&self) -> String {
|
||
"'...'.format(...) mixes automatic and manual numbering".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
StringDotFormatMixingAutomatic
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct FStringMissingPlaceholders;
|
||
);
|
||
impl AlwaysAutofixableViolation for FStringMissingPlaceholders {
|
||
fn message(&self) -> String {
|
||
"f-string without any placeholders".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove extraneous `f` prefix".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FStringMissingPlaceholders
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MultiValueRepeatedKeyLiteral(pub String, pub bool);
|
||
);
|
||
impl Violation for MultiValueRepeatedKeyLiteral {
|
||
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
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MultiValueRepeatedKeyLiteral("...".to_string(), true)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MultiValueRepeatedKeyVariable(pub String, pub bool);
|
||
);
|
||
impl Violation for MultiValueRepeatedKeyVariable {
|
||
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
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MultiValueRepeatedKeyVariable("...".to_string(), true)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ExpressionsInStarAssignment;
|
||
);
|
||
impl Violation for ExpressionsInStarAssignment {
|
||
fn message(&self) -> String {
|
||
"Too many expressions in star-unpacking assignment".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ExpressionsInStarAssignment
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct TwoStarredExpressions;
|
||
);
|
||
impl Violation for TwoStarredExpressions {
|
||
fn message(&self) -> String {
|
||
"Two starred expressions in assignment".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
TwoStarredExpressions
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AssertTuple;
|
||
);
|
||
impl Violation for AssertTuple {
|
||
fn message(&self) -> String {
|
||
"Assert test is a non-empty tuple, which is always `True`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AssertTuple
|
||
}
|
||
}
|
||
|
||
#[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 IsCmpop);
|
||
);
|
||
impl AlwaysAutofixableViolation for IsLiteral {
|
||
fn message(&self) -> String {
|
||
let IsLiteral(cmpop) = self;
|
||
match cmpop {
|
||
IsCmpop::Is => "Use `==` to compare constant literals".to_string(),
|
||
IsCmpop::IsNot => "Use `!=` to compare constant literals".to_string(),
|
||
}
|
||
}
|
||
|
||
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(),
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
IsLiteral(IsCmpop::Is)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct InvalidPrintSyntax;
|
||
);
|
||
impl Violation for InvalidPrintSyntax {
|
||
fn message(&self) -> String {
|
||
"Use of `>>` is invalid with `print` function".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
InvalidPrintSyntax
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct IfTuple;
|
||
);
|
||
impl Violation for IfTuple {
|
||
fn message(&self) -> String {
|
||
"If test is a tuple, which is always `True`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
IfTuple
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct BreakOutsideLoop;
|
||
);
|
||
impl Violation for BreakOutsideLoop {
|
||
fn message(&self) -> String {
|
||
"`break` outside loop".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BreakOutsideLoop
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ContinueOutsideLoop;
|
||
);
|
||
impl Violation for ContinueOutsideLoop {
|
||
fn message(&self) -> String {
|
||
"`continue` not properly in loop".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ContinueOutsideLoop
|
||
}
|
||
}
|
||
|
||
#[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 DeferralKeyword);
|
||
);
|
||
impl Violation for YieldOutsideFunction {
|
||
fn message(&self) -> String {
|
||
let YieldOutsideFunction(keyword) = self;
|
||
format!("`{keyword}` statement outside of a function")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
YieldOutsideFunction(DeferralKeyword::Yield)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ReturnOutsideFunction;
|
||
);
|
||
impl Violation for ReturnOutsideFunction {
|
||
fn message(&self) -> String {
|
||
"`return` statement outside of a function/method".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ReturnOutsideFunction
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DefaultExceptNotLast;
|
||
);
|
||
impl Violation for DefaultExceptNotLast {
|
||
fn message(&self) -> String {
|
||
"An `except` block as not the last exception handler".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DefaultExceptNotLast
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ForwardAnnotationSyntaxError(pub String);
|
||
);
|
||
impl Violation for ForwardAnnotationSyntaxError {
|
||
fn message(&self) -> String {
|
||
let ForwardAnnotationSyntaxError(body) = self;
|
||
format!("Syntax error in forward annotation: `{body}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ForwardAnnotationSyntaxError("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RedefinedWhileUnused(pub String, pub usize);
|
||
);
|
||
impl Violation for RedefinedWhileUnused {
|
||
fn message(&self) -> String {
|
||
let RedefinedWhileUnused(name, line) = self;
|
||
format!("Redefinition of unused `{name}` from line {line}")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RedefinedWhileUnused("...".to_string(), 1)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UndefinedName(pub String);
|
||
);
|
||
impl Violation for UndefinedName {
|
||
fn message(&self) -> String {
|
||
let UndefinedName(name) = self;
|
||
format!("Undefined name `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UndefinedName("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UndefinedExport(pub String);
|
||
);
|
||
impl Violation for UndefinedExport {
|
||
fn message(&self) -> String {
|
||
let UndefinedExport(name) = self;
|
||
format!("Undefined name `{name}` in `__all__`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UndefinedExport("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UndefinedLocal(pub String);
|
||
);
|
||
impl Violation for UndefinedLocal {
|
||
fn message(&self) -> String {
|
||
let UndefinedLocal(name) = self;
|
||
format!("Local variable `{name}` referenced before assignment")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UndefinedLocal("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnusedVariable(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UnusedVariable {
|
||
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}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnusedVariable("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnusedAnnotation(pub String);
|
||
);
|
||
impl Violation for UnusedAnnotation {
|
||
fn message(&self) -> String {
|
||
let UnusedAnnotation(name) = self;
|
||
format!("Local variable `{name}` is annotated but never used")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnusedAnnotation("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RaiseNotImplemented;
|
||
);
|
||
impl AlwaysAutofixableViolation for RaiseNotImplemented {
|
||
fn message(&self) -> String {
|
||
"`raise NotImplemented` should be `raise NotImplementedError`".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Use `raise NotImplementedError`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RaiseNotImplemented
|
||
}
|
||
}
|
||
|
||
// pylint
|
||
|
||
define_violation!(
|
||
pub struct UselessImportAlias;
|
||
);
|
||
impl AlwaysAutofixableViolation for UselessImportAlias {
|
||
fn message(&self) -> String {
|
||
"Import alias does not rename original package".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove import alias".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UselessImportAlias
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MisplacedComparisonConstant(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for MisplacedComparisonConstant {
|
||
fn message(&self) -> String {
|
||
let MisplacedComparisonConstant(comparison) = self;
|
||
format!("Comparison should be {comparison}")
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
let MisplacedComparisonConstant(comparison) = self;
|
||
format!("Replace with {comparison}")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MisplacedComparisonConstant("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryDirectLambdaCall;
|
||
);
|
||
impl Violation for UnnecessaryDirectLambdaCall {
|
||
fn message(&self) -> String {
|
||
"Lambda expression called directly. Execute the expression inline instead.".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryDirectLambdaCall
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NonlocalWithoutBinding(pub String);
|
||
);
|
||
impl Violation for NonlocalWithoutBinding {
|
||
fn message(&self) -> String {
|
||
let NonlocalWithoutBinding(name) = self;
|
||
format!("Nonlocal name `{name}` found without binding")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NonlocalWithoutBinding("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UsedPriorGlobalDeclaration(pub String, pub usize);
|
||
);
|
||
impl Violation for UsedPriorGlobalDeclaration {
|
||
fn message(&self) -> String {
|
||
let UsedPriorGlobalDeclaration(name, line) = self;
|
||
format!("Name `{name}` is used prior to global declaration on line {line}")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UsedPriorGlobalDeclaration("...".to_string(), 1)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AwaitOutsideAsync;
|
||
);
|
||
impl Violation for AwaitOutsideAsync {
|
||
fn message(&self) -> String {
|
||
"`await` should be used within an async function".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AwaitOutsideAsync
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PropertyWithParameters;
|
||
);
|
||
impl Violation for PropertyWithParameters {
|
||
fn message(&self) -> String {
|
||
"Cannot have defined parameters for properties".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PropertyWithParameters
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ConsiderUsingFromImport(pub String, pub String);
|
||
);
|
||
impl Violation for ConsiderUsingFromImport {
|
||
fn message(&self) -> String {
|
||
let ConsiderUsingFromImport(module, name) = self;
|
||
format!("Use `from {module} import {name}` in lieu of alias")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ConsiderUsingFromImport("...".to_string(), "...".to_string())
|
||
}
|
||
}
|
||
|
||
#[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 {
|
||
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}`"
|
||
)
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ConstantComparison {
|
||
left_constant: "0".to_string(),
|
||
op: ViolationsCmpop::Eq,
|
||
right_constant: "0".to_string(),
|
||
}
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ConsiderMergingIsinstance(pub String, pub Vec<String>);
|
||
);
|
||
impl Violation for ConsiderMergingIsinstance {
|
||
fn message(&self) -> String {
|
||
let ConsiderMergingIsinstance(obj, types) = self;
|
||
let types = types.join(", ");
|
||
format!("Merge these isinstance calls: `isinstance({obj}, ({types}))`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ConsiderMergingIsinstance("...".to_string(), vec!["...".to_string()])
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UseSysExit(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UseSysExit {
|
||
fn message(&self) -> String {
|
||
let UseSysExit(name) = self;
|
||
format!("Use `sys.exit()` instead of `{name}`")
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
let UseSysExit(name) = self;
|
||
format!("Replace `{name}` with `sys.exit()`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseSysExit("exit".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MagicValueComparison(pub String);
|
||
);
|
||
impl Violation for MagicValueComparison {
|
||
fn message(&self) -> String {
|
||
let MagicValueComparison(value) = self;
|
||
format!(
|
||
"Magic value used in comparison, consider replacing {value} with a constant variable"
|
||
)
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MagicValueComparison("magic".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UselessElseOnLoop;
|
||
);
|
||
impl Violation for UselessElseOnLoop {
|
||
fn message(&self) -> String {
|
||
"Else clause on loop without a break statement, remove the else and de-indent all the code \
|
||
inside it"
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UselessElseOnLoop
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct GlobalVariableNotAssigned(pub String);
|
||
);
|
||
impl Violation for GlobalVariableNotAssigned {
|
||
fn message(&self) -> String {
|
||
let GlobalVariableNotAssigned(name) = self;
|
||
format!("Using global for `{name}` but no assignment is done")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
GlobalVariableNotAssigned("...".to_string())
|
||
}
|
||
}
|
||
|
||
// flake8-builtins
|
||
|
||
define_violation!(
|
||
pub struct BuiltinVariableShadowing(pub String);
|
||
);
|
||
impl Violation for BuiltinVariableShadowing {
|
||
fn message(&self) -> String {
|
||
let BuiltinVariableShadowing(name) = self;
|
||
format!("Variable `{name}` is shadowing a python builtin")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BuiltinVariableShadowing("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct BuiltinArgumentShadowing(pub String);
|
||
);
|
||
impl Violation for BuiltinArgumentShadowing {
|
||
fn message(&self) -> String {
|
||
let BuiltinArgumentShadowing(name) = self;
|
||
format!("Argument `{name}` is shadowing a python builtin")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BuiltinArgumentShadowing("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct BuiltinAttributeShadowing(pub String);
|
||
);
|
||
impl Violation for BuiltinAttributeShadowing {
|
||
fn message(&self) -> String {
|
||
let BuiltinAttributeShadowing(name) = self;
|
||
format!("Class attribute `{name}` is shadowing a python builtin")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BuiltinAttributeShadowing("...".to_string())
|
||
}
|
||
}
|
||
|
||
// flake8-bugbear
|
||
|
||
define_violation!(
|
||
pub struct UnaryPrefixIncrement;
|
||
);
|
||
impl Violation for UnaryPrefixIncrement {
|
||
fn message(&self) -> String {
|
||
"Python does not support the unary prefix increment. Writing `++n` is equivalent to \
|
||
`+(+(n))`, which equals `n`. You meant `n += 1`."
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnaryPrefixIncrement
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AssignmentToOsEnviron;
|
||
);
|
||
impl Violation for AssignmentToOsEnviron {
|
||
fn message(&self) -> String {
|
||
"Assigning to `os.environ` doesn't clear the environment".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AssignmentToOsEnviron
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnreliableCallableCheck;
|
||
);
|
||
impl Violation for UnreliableCallableCheck {
|
||
fn message(&self) -> String {
|
||
" Using `hasattr(x, '__call__')` to test if x is callable is unreliable. Use `callable(x)` \
|
||
for consistent results."
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnreliableCallableCheck
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct StripWithMultiCharacters;
|
||
);
|
||
impl Violation for StripWithMultiCharacters {
|
||
fn message(&self) -> String {
|
||
"Using `.strip()` with multi-character strings is misleading the reader".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
StripWithMultiCharacters
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MutableArgumentDefault;
|
||
);
|
||
impl Violation for MutableArgumentDefault {
|
||
fn message(&self) -> String {
|
||
"Do not use mutable data structures for argument defaults".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MutableArgumentDefault
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnusedLoopControlVariable(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UnusedLoopControlVariable {
|
||
fn message(&self) -> String {
|
||
let UnusedLoopControlVariable(name) = self;
|
||
format!(
|
||
"Loop control variable `{name}` not used within the loop body. If this is intended, \
|
||
start the name with an underscore."
|
||
)
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
let UnusedLoopControlVariable(name) = self;
|
||
format!("Rename unused `{name}` to `_{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnusedLoopControlVariable("i".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct FunctionCallArgumentDefault(pub Option<String>);
|
||
);
|
||
impl Violation for FunctionCallArgumentDefault {
|
||
fn message(&self) -> String {
|
||
let FunctionCallArgumentDefault(name) = self;
|
||
if let Some(name) = name {
|
||
format!("Do not perform function call `{name}` in argument defaults")
|
||
} else {
|
||
"Do not perform function call in argument defaults".to_string()
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FunctionCallArgumentDefault(None)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct GetAttrWithConstant;
|
||
);
|
||
impl AlwaysAutofixableViolation for GetAttrWithConstant {
|
||
fn message(&self) -> String {
|
||
"Do not call `getattr` with a constant attribute value. It is not any safer than normal \
|
||
property access."
|
||
.to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Replace `getattr` with attribute access".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
GetAttrWithConstant
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SetAttrWithConstant;
|
||
);
|
||
impl AlwaysAutofixableViolation for SetAttrWithConstant {
|
||
fn message(&self) -> String {
|
||
"Do not call `setattr` with a constant attribute value. It is not any safer than normal \
|
||
property access."
|
||
.to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Replace `setattr` with assignment".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SetAttrWithConstant
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DoNotAssertFalse;
|
||
);
|
||
impl AlwaysAutofixableViolation for DoNotAssertFalse {
|
||
fn message(&self) -> String {
|
||
"Do not `assert False` (`python -O` removes these calls), raise `AssertionError()`"
|
||
.to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Replace `assert False`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DoNotAssertFalse
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct JumpStatementInFinally(pub String);
|
||
);
|
||
impl Violation for JumpStatementInFinally {
|
||
fn message(&self) -> String {
|
||
let JumpStatementInFinally(name) = self;
|
||
format!("`{name}` inside finally blocks cause exceptions to be silenced")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
JumpStatementInFinally("return/continue/break".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RedundantTupleInExceptionHandler(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for RedundantTupleInExceptionHandler {
|
||
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}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RedundantTupleInExceptionHandler("ValueError".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DuplicateHandlerException(pub Vec<String>);
|
||
);
|
||
impl AlwaysAutofixableViolation for DuplicateHandlerException {
|
||
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()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DuplicateHandlerException(vec!["ValueError".to_string()])
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UselessComparison;
|
||
);
|
||
impl Violation for UselessComparison {
|
||
fn message(&self) -> String {
|
||
"Pointless comparison. This comparison does nothing but waste CPU instructions. Either \
|
||
prepend `assert` or remove it."
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UselessComparison
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CannotRaiseLiteral;
|
||
);
|
||
impl Violation for CannotRaiseLiteral {
|
||
fn message(&self) -> String {
|
||
"Cannot raise a literal. Did you intend to return it or raise an Exception?".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CannotRaiseLiteral
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NoAssertRaisesException;
|
||
);
|
||
impl Violation for NoAssertRaisesException {
|
||
fn message(&self) -> String {
|
||
"`assertRaises(Exception)` should be considered evil. It can lead to your test passing \
|
||
even if the code being tested is never executed due to a typo. Either assert for a more \
|
||
specific exception (builtin or custom), use `assertRaisesRegex`, or use the context \
|
||
manager form of `assertRaises`."
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NoAssertRaisesException
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UselessExpression;
|
||
);
|
||
impl Violation for UselessExpression {
|
||
fn message(&self) -> String {
|
||
"Found useless expression. Either assign it to a variable or remove it.".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UselessExpression
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CachedInstanceMethod;
|
||
);
|
||
impl Violation for CachedInstanceMethod {
|
||
fn message(&self) -> String {
|
||
"Use of `functools.lru_cache` or `functools.cache` on methods can lead to memory leaks"
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CachedInstanceMethod
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct LoopVariableOverridesIterator(pub String);
|
||
);
|
||
impl Violation for LoopVariableOverridesIterator {
|
||
fn message(&self) -> String {
|
||
let LoopVariableOverridesIterator(name) = self;
|
||
format!("Loop control variable `{name}` overrides iterable it iterates")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
LoopVariableOverridesIterator("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct FStringDocstring;
|
||
);
|
||
impl Violation for FStringDocstring {
|
||
fn message(&self) -> String {
|
||
"f-string used as docstring. This will be interpreted by python as a joined string rather \
|
||
than a docstring."
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FStringDocstring
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UselessContextlibSuppress;
|
||
);
|
||
impl Violation for UselessContextlibSuppress {
|
||
fn message(&self) -> String {
|
||
"No arguments passed to `contextlib.suppress`. No exceptions will be suppressed and \
|
||
therefore this context manager is redundant"
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UselessContextlibSuppress
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct FunctionUsesLoopVariable(pub String);
|
||
);
|
||
impl Violation for FunctionUsesLoopVariable {
|
||
fn message(&self) -> String {
|
||
let FunctionUsesLoopVariable(name) = self;
|
||
format!("Function definition does not bind loop variable `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FunctionUsesLoopVariable("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AbstractBaseClassWithoutAbstractMethod(pub String);
|
||
);
|
||
impl Violation for AbstractBaseClassWithoutAbstractMethod {
|
||
fn message(&self) -> String {
|
||
let AbstractBaseClassWithoutAbstractMethod(name) = self;
|
||
format!("`{name}` is an abstract base class, but it has no abstract methods")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AbstractBaseClassWithoutAbstractMethod("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DuplicateTryBlockException(pub String);
|
||
);
|
||
impl Violation for DuplicateTryBlockException {
|
||
fn message(&self) -> String {
|
||
let DuplicateTryBlockException(name) = self;
|
||
format!("try-except block with duplicate exception `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DuplicateTryBlockException("Exception".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct StarArgUnpackingAfterKeywordArg;
|
||
);
|
||
impl Violation for StarArgUnpackingAfterKeywordArg {
|
||
fn message(&self) -> String {
|
||
"Star-arg unpacking after a keyword argument is strongly discouraged. It only works when \
|
||
the keyword parameter is declared after all parameters supplied by the unpacked sequence, \
|
||
and this change of ordering can surprise and mislead readers."
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
StarArgUnpackingAfterKeywordArg
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct EmptyMethodWithoutAbstractDecorator(pub String);
|
||
);
|
||
impl Violation for EmptyMethodWithoutAbstractDecorator {
|
||
fn message(&self) -> String {
|
||
let EmptyMethodWithoutAbstractDecorator(name) = self;
|
||
format!(
|
||
"`{name}` is an empty method in an abstract base class, but has no abstract decorator"
|
||
)
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
EmptyMethodWithoutAbstractDecorator("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RaiseWithoutFromInsideExcept;
|
||
);
|
||
impl Violation for RaiseWithoutFromInsideExcept {
|
||
fn message(&self) -> String {
|
||
"Within an except clause, raise exceptions with `raise ... from err` or `raise ... from \
|
||
None` to distinguish them from errors in exception handling"
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RaiseWithoutFromInsideExcept
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ZipWithoutExplicitStrict;
|
||
);
|
||
impl Violation for ZipWithoutExplicitStrict {
|
||
fn message(&self) -> String {
|
||
"`zip()` without an explicit `strict=` parameter".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ZipWithoutExplicitStrict
|
||
}
|
||
}
|
||
|
||
// flake8-blind-except
|
||
|
||
define_violation!(
|
||
pub struct BlindExcept(pub String);
|
||
);
|
||
impl Violation for BlindExcept {
|
||
fn message(&self) -> String {
|
||
let BlindExcept(name) = self;
|
||
format!("Do not catch blind exception: `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BlindExcept("Exception".to_string())
|
||
}
|
||
}
|
||
|
||
// flake8-comprehensions
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryGeneratorList;
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryGeneratorList {
|
||
fn message(&self) -> String {
|
||
"Unnecessary generator (rewrite as a `list` comprehension)".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Rewrite as a `list` comprehension".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryGeneratorList
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryGeneratorSet;
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryGeneratorSet {
|
||
fn message(&self) -> String {
|
||
"Unnecessary generator (rewrite as a `set` comprehension)".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Rewrite as a `set` comprehension".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryGeneratorSet
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryGeneratorDict;
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryGeneratorDict {
|
||
fn message(&self) -> String {
|
||
"Unnecessary generator (rewrite as a `dict` comprehension)".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Rewrite as a `dict` comprehension".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryGeneratorDict
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryListComprehensionSet;
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryListComprehensionSet {
|
||
fn message(&self) -> String {
|
||
"Unnecessary `list` comprehension (rewrite as a `set` comprehension)".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Rewrite as a `set` comprehension".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryListComprehensionSet
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryListComprehensionDict;
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryListComprehensionDict {
|
||
fn message(&self) -> String {
|
||
"Unnecessary `list` comprehension (rewrite as a `dict` comprehension)".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Rewrite as a `dict` comprehension".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryListComprehensionDict
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryLiteralSet(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryLiteralSet {
|
||
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()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryLiteralSet("(list|tuple)".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryLiteralDict(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryLiteralDict {
|
||
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()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryLiteralDict("(list|tuple)".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryCollectionCall(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryCollectionCall {
|
||
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()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryCollectionCall("(dict|list|tuple)".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryLiteralWithinTupleCall(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryLiteralWithinTupleCall {
|
||
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()
|
||
}
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryLiteralWithinTupleCall("(list|tuple)".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryLiteralWithinListCall(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryLiteralWithinListCall {
|
||
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()
|
||
}
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryLiteralWithinListCall("(list|tuple)".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryListCall;
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryListCall {
|
||
fn message(&self) -> String {
|
||
"Unnecessary `list` call (remove the outer call to `list()`)".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove outer `list` call".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryListCall
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryCallAroundSorted(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryCallAroundSorted {
|
||
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")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryCallAroundSorted("(list|reversed)".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryDoubleCastOrProcess(pub String, pub String);
|
||
);
|
||
impl Violation for UnnecessaryDoubleCastOrProcess {
|
||
fn message(&self) -> String {
|
||
let UnnecessaryDoubleCastOrProcess(inner, outer) = self;
|
||
format!("Unnecessary `{inner}` call within `{outer}()`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryDoubleCastOrProcess(
|
||
"(list|reversed|set|sorted|tuple)".to_string(),
|
||
"(list|set|sorted|tuple)".to_string(),
|
||
)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessarySubscriptReversal(pub String);
|
||
);
|
||
impl Violation for UnnecessarySubscriptReversal {
|
||
fn message(&self) -> String {
|
||
let UnnecessarySubscriptReversal(func) = self;
|
||
format!("Unnecessary subscript reversal of iterable within `{func}()`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessarySubscriptReversal("(reversed|set|sorted)".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryComprehension(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryComprehension {
|
||
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}()`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryComprehension("(list|set)".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryMap(pub String);
|
||
);
|
||
impl Violation for UnnecessaryMap {
|
||
fn message(&self) -> String {
|
||
let UnnecessaryMap(obj_type) = self;
|
||
if obj_type == "generator" {
|
||
"Unnecessary `map` usage (rewrite using a generator expression)".to_string()
|
||
} else {
|
||
format!("Unnecessary `map` usage (rewrite using a `{obj_type}` comprehension)")
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryMap("(list|set|dict)".to_string())
|
||
}
|
||
}
|
||
|
||
// flake8-debugger
|
||
|
||
define_violation!(
|
||
pub struct Debugger(pub DebuggerUsingType);
|
||
);
|
||
impl Violation for Debugger {
|
||
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"),
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
Debugger(DebuggerUsingType::Import("...".to_string()))
|
||
}
|
||
}
|
||
|
||
// mccabe
|
||
|
||
define_violation!(
|
||
pub struct FunctionIsTooComplex(pub String, pub usize);
|
||
);
|
||
impl Violation for FunctionIsTooComplex {
|
||
fn message(&self) -> String {
|
||
let FunctionIsTooComplex(name, complexity) = self;
|
||
format!("`{name}` is too complex ({complexity})")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FunctionIsTooComplex("...".to_string(), 10)
|
||
}
|
||
}
|
||
|
||
// flake8-return
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryReturnNone;
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryReturnNone {
|
||
fn message(&self) -> String {
|
||
"Do not explicitly `return None` in function if it is the only possible return value"
|
||
.to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove explicit `return None`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryReturnNone
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ImplicitReturnValue;
|
||
);
|
||
impl AlwaysAutofixableViolation for ImplicitReturnValue {
|
||
fn message(&self) -> String {
|
||
"Do not implicitly `return None` in function able to return non-`None` value".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Add explicit `None` return value".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ImplicitReturnValue
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ImplicitReturn;
|
||
);
|
||
impl AlwaysAutofixableViolation for ImplicitReturn {
|
||
fn message(&self) -> String {
|
||
"Missing explicit `return` at the end of function able to return non-`None` value"
|
||
.to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Add explicit `return` statement".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ImplicitReturn
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryAssign;
|
||
);
|
||
impl Violation for UnnecessaryAssign {
|
||
fn message(&self) -> String {
|
||
"Unnecessary variable assignment before `return` statement".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryAssign
|
||
}
|
||
}
|
||
|
||
#[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);
|
||
);
|
||
impl Violation for SuperfluousElseReturn {
|
||
fn message(&self) -> String {
|
||
let SuperfluousElseReturn(branch) = self;
|
||
format!("Unnecessary `{branch}` after `return` statement")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SuperfluousElseReturn(Branch::Else)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SuperfluousElseRaise(pub Branch);
|
||
);
|
||
impl Violation for SuperfluousElseRaise {
|
||
fn message(&self) -> String {
|
||
let SuperfluousElseRaise(branch) = self;
|
||
format!("Unnecessary `{branch}` after `raise` statement")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SuperfluousElseRaise(Branch::Else)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SuperfluousElseContinue(pub Branch);
|
||
);
|
||
impl Violation for SuperfluousElseContinue {
|
||
fn message(&self) -> String {
|
||
let SuperfluousElseContinue(branch) = self;
|
||
format!("Unnecessary `{branch}` after `continue` statement")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SuperfluousElseContinue(Branch::Else)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SuperfluousElseBreak(pub Branch);
|
||
);
|
||
impl Violation for SuperfluousElseBreak {
|
||
fn message(&self) -> String {
|
||
let SuperfluousElseBreak(branch) = self;
|
||
format!("Unnecessary `{branch}` after `break` statement")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SuperfluousElseBreak(Branch::Else)
|
||
}
|
||
}
|
||
|
||
// flake8-implicit-str-concat
|
||
|
||
define_violation!(
|
||
pub struct SingleLineImplicitStringConcatenation;
|
||
);
|
||
impl Violation for SingleLineImplicitStringConcatenation {
|
||
fn message(&self) -> String {
|
||
"Implicitly concatenated string literals on one line".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SingleLineImplicitStringConcatenation
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MultiLineImplicitStringConcatenation;
|
||
);
|
||
impl Violation for MultiLineImplicitStringConcatenation {
|
||
fn message(&self) -> String {
|
||
"Implicitly concatenated string literals over continuation line".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MultiLineImplicitStringConcatenation
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ExplicitStringConcatenation;
|
||
);
|
||
impl Violation for ExplicitStringConcatenation {
|
||
fn message(&self) -> String {
|
||
"Explicitly concatenated string should be implicitly concatenated".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ExplicitStringConcatenation
|
||
}
|
||
}
|
||
|
||
// flake8-print
|
||
|
||
define_violation!(
|
||
pub struct PrintFound;
|
||
);
|
||
impl AlwaysAutofixableViolation for PrintFound {
|
||
fn message(&self) -> String {
|
||
"`print` found".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove `print`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PrintFound
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PPrintFound;
|
||
);
|
||
impl AlwaysAutofixableViolation for PPrintFound {
|
||
fn message(&self) -> String {
|
||
"`pprint` found".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove `pprint`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PPrintFound
|
||
}
|
||
}
|
||
|
||
// flake8-quotes
|
||
|
||
define_violation!(
|
||
pub struct BadQuotesInlineString(pub Quote);
|
||
);
|
||
impl AlwaysAutofixableViolation for BadQuotesInlineString {
|
||
fn message(&self) -> String {
|
||
let BadQuotesInlineString(quote) = self;
|
||
match quote {
|
||
Quote::Single => "Double quotes found but single quotes preferred".to_string(),
|
||
Quote::Double => "Single quotes found but double quotes preferred".to_string(),
|
||
}
|
||
}
|
||
|
||
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(),
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BadQuotesInlineString(Quote::Double)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct BadQuotesMultilineString(pub Quote);
|
||
);
|
||
impl AlwaysAutofixableViolation for BadQuotesMultilineString {
|
||
fn message(&self) -> String {
|
||
let BadQuotesMultilineString(quote) = self;
|
||
match quote {
|
||
Quote::Single => "Double quote multiline found but single quotes preferred".to_string(),
|
||
Quote::Double => "Single quote multiline found but double quotes preferred".to_string(),
|
||
}
|
||
}
|
||
|
||
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(),
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BadQuotesMultilineString(Quote::Double)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct BadQuotesDocstring(pub Quote);
|
||
);
|
||
impl AlwaysAutofixableViolation for BadQuotesDocstring {
|
||
fn message(&self) -> String {
|
||
let BadQuotesDocstring(quote) = self;
|
||
match quote {
|
||
Quote::Single => "Double quote docstring found but single quotes preferred".to_string(),
|
||
Quote::Double => "Single quote docstring found but double quotes preferred".to_string(),
|
||
}
|
||
}
|
||
|
||
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(),
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BadQuotesDocstring(Quote::Double)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AvoidQuoteEscape;
|
||
);
|
||
impl AlwaysAutofixableViolation for AvoidQuoteEscape {
|
||
fn message(&self) -> String {
|
||
"Change outer quotes to avoid escaping inner quotes".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Change outer quotes to avoid escaping inner quotes".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AvoidQuoteEscape
|
||
}
|
||
}
|
||
|
||
// flake8-annotations
|
||
|
||
define_violation!(
|
||
pub struct MissingTypeFunctionArgument(pub String);
|
||
);
|
||
impl Violation for MissingTypeFunctionArgument {
|
||
fn message(&self) -> String {
|
||
let MissingTypeFunctionArgument(name) = self;
|
||
format!("Missing type annotation for function argument `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MissingTypeFunctionArgument("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MissingTypeArgs(pub String);
|
||
);
|
||
impl Violation for MissingTypeArgs {
|
||
fn message(&self) -> String {
|
||
let MissingTypeArgs(name) = self;
|
||
format!("Missing type annotation for `*{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MissingTypeArgs("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MissingTypeKwargs(pub String);
|
||
);
|
||
impl Violation for MissingTypeKwargs {
|
||
fn message(&self) -> String {
|
||
let MissingTypeKwargs(name) = self;
|
||
format!("Missing type annotation for `**{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MissingTypeKwargs("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MissingTypeSelf(pub String);
|
||
);
|
||
impl Violation for MissingTypeSelf {
|
||
fn message(&self) -> String {
|
||
let MissingTypeSelf(name) = self;
|
||
format!("Missing type annotation for `{name}` in method")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MissingTypeSelf("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MissingTypeCls(pub String);
|
||
);
|
||
impl Violation for MissingTypeCls {
|
||
fn message(&self) -> String {
|
||
let MissingTypeCls(name) = self;
|
||
format!("Missing type annotation for `{name}` in classmethod")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MissingTypeCls("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MissingReturnTypePublicFunction(pub String);
|
||
);
|
||
impl Violation for MissingReturnTypePublicFunction {
|
||
fn message(&self) -> String {
|
||
let MissingReturnTypePublicFunction(name) = self;
|
||
format!("Missing return type annotation for public function `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MissingReturnTypePublicFunction("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MissingReturnTypePrivateFunction(pub String);
|
||
);
|
||
impl Violation for MissingReturnTypePrivateFunction {
|
||
fn message(&self) -> String {
|
||
let MissingReturnTypePrivateFunction(name) = self;
|
||
format!("Missing return type annotation for private function `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MissingReturnTypePrivateFunction("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MissingReturnTypeSpecialMethod(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for MissingReturnTypeSpecialMethod {
|
||
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()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MissingReturnTypeSpecialMethod("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MissingReturnTypeStaticMethod(pub String);
|
||
);
|
||
impl Violation for MissingReturnTypeStaticMethod {
|
||
fn message(&self) -> String {
|
||
let MissingReturnTypeStaticMethod(name) = self;
|
||
format!("Missing return type annotation for staticmethod `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MissingReturnTypeStaticMethod("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MissingReturnTypeClassMethod(pub String);
|
||
);
|
||
impl Violation for MissingReturnTypeClassMethod {
|
||
fn message(&self) -> String {
|
||
let MissingReturnTypeClassMethod(name) = self;
|
||
format!("Missing return type annotation for classmethod `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MissingReturnTypeClassMethod("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DynamicallyTypedExpression(pub String);
|
||
);
|
||
impl Violation for DynamicallyTypedExpression {
|
||
fn message(&self) -> String {
|
||
let DynamicallyTypedExpression(name) = self;
|
||
format!("Dynamically typed expressions (typing.Any) are disallowed in `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DynamicallyTypedExpression("...".to_string())
|
||
}
|
||
}
|
||
|
||
// flake8-2020
|
||
|
||
define_violation!(
|
||
pub struct SysVersionSlice3Referenced;
|
||
);
|
||
impl Violation for SysVersionSlice3Referenced {
|
||
fn message(&self) -> String {
|
||
"`sys.version[:3]` referenced (python3.10), use `sys.version_info`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SysVersionSlice3Referenced
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SysVersion2Referenced;
|
||
);
|
||
impl Violation for SysVersion2Referenced {
|
||
fn message(&self) -> String {
|
||
"`sys.version[2]` referenced (python3.10), use `sys.version_info`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SysVersion2Referenced
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SysVersionCmpStr3;
|
||
);
|
||
impl Violation for SysVersionCmpStr3 {
|
||
fn message(&self) -> String {
|
||
"`sys.version` compared to string (python3.10), use `sys.version_info`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SysVersionCmpStr3
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SysVersionInfo0Eq3Referenced;
|
||
);
|
||
impl Violation for SysVersionInfo0Eq3Referenced {
|
||
fn message(&self) -> String {
|
||
"`sys.version_info[0] == 3` referenced (python4), use `>=`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SysVersionInfo0Eq3Referenced
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SixPY3Referenced;
|
||
);
|
||
impl Violation for SixPY3Referenced {
|
||
fn message(&self) -> String {
|
||
"`six.PY3` referenced (python4), use `not six.PY2`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SixPY3Referenced
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SysVersionInfo1CmpInt;
|
||
);
|
||
impl Violation for SysVersionInfo1CmpInt {
|
||
fn message(&self) -> String {
|
||
"`sys.version_info[1]` compared to integer (python4), compare `sys.version_info` to tuple"
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SysVersionInfo1CmpInt
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SysVersionInfoMinorCmpInt;
|
||
);
|
||
impl Violation for SysVersionInfoMinorCmpInt {
|
||
fn message(&self) -> String {
|
||
"`sys.version_info.minor` compared to integer (python4), compare `sys.version_info` to \
|
||
tuple"
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SysVersionInfoMinorCmpInt
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SysVersion0Referenced;
|
||
);
|
||
impl Violation for SysVersion0Referenced {
|
||
fn message(&self) -> String {
|
||
"`sys.version[0]` referenced (python10), use `sys.version_info`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SysVersion0Referenced
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SysVersionCmpStr10;
|
||
);
|
||
impl Violation for SysVersionCmpStr10 {
|
||
fn message(&self) -> String {
|
||
"`sys.version` compared to string (python10), use `sys.version_info`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SysVersionCmpStr10
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SysVersionSlice1Referenced;
|
||
);
|
||
impl Violation for SysVersionSlice1Referenced {
|
||
fn message(&self) -> String {
|
||
"`sys.version[:1]` referenced (python10), use `sys.version_info`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SysVersionSlice1Referenced
|
||
}
|
||
}
|
||
|
||
// flake8-simplify
|
||
|
||
define_violation!(
|
||
pub struct OpenFileWithContextHandler;
|
||
);
|
||
impl Violation for OpenFileWithContextHandler {
|
||
fn message(&self) -> String {
|
||
"Use context handler for opening files".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
OpenFileWithContextHandler
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UseCapitalEnvironmentVariables(pub String, pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UseCapitalEnvironmentVariables {
|
||
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}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseCapitalEnvironmentVariables("...".to_string(), "...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DuplicateIsinstanceCall(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for DuplicateIsinstanceCall {
|
||
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}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DuplicateIsinstanceCall("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NestedIfStatements;
|
||
);
|
||
impl Violation for NestedIfStatements {
|
||
fn message(&self) -> String {
|
||
"Use a single `if` statement instead of nested `if` statements".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NestedIfStatements
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ReturnBoolConditionDirectly(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for ReturnBoolConditionDirectly {
|
||
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}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ReturnBoolConditionDirectly("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UseContextlibSuppress(pub String);
|
||
);
|
||
impl Violation for UseContextlibSuppress {
|
||
fn message(&self) -> String {
|
||
let UseContextlibSuppress(exception) = self;
|
||
format!("Use `contextlib.suppress({exception})` instead of try-except-pass")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseContextlibSuppress("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ReturnInTryExceptFinally;
|
||
);
|
||
impl Violation for ReturnInTryExceptFinally {
|
||
fn message(&self) -> String {
|
||
"Don't use `return` in `try`/`except` and `finally`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ReturnInTryExceptFinally
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UseTernaryOperator(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UseTernaryOperator {
|
||
fn message(&self) -> String {
|
||
let UseTernaryOperator(contents) = self;
|
||
format!("Use ternary operator `{contents}` instead of if-else-block")
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
let UseTernaryOperator(contents) = self;
|
||
format!("Replace if-else-block with `{contents}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseTernaryOperator("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CompareWithTuple(pub String, pub Vec<String>, pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for CompareWithTuple {
|
||
fn message(&self) -> String {
|
||
let CompareWithTuple(value, values, or_op) = self;
|
||
let values = values.join(", ");
|
||
format!("Use `{value} in ({values})` instead of `{or_op}`")
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
let CompareWithTuple(value, values, or_op) = self;
|
||
let values = values.join(", ");
|
||
format!("Replace `{or_op}` with `{value} in {values}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CompareWithTuple(
|
||
"value".to_string(),
|
||
vec!["...".to_string(), "...".to_string()],
|
||
"value == ... or value == ...".to_string(),
|
||
)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ConvertLoopToAny(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for ConvertLoopToAny {
|
||
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}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ConvertLoopToAny("return any(x for x in y)".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ConvertLoopToAll(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for ConvertLoopToAll {
|
||
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}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ConvertLoopToAll("return all(x for x in y)".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MultipleWithStatements;
|
||
);
|
||
impl Violation for MultipleWithStatements {
|
||
fn message(&self) -> String {
|
||
"Use a single `with` statement with multiple contexts instead of nested `with` statements"
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MultipleWithStatements
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct KeyInDict(pub String, pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for KeyInDict {
|
||
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}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
KeyInDict("key".to_string(), "dict".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NegateEqualOp(pub String, pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for NegateEqualOp {
|
||
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()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NegateEqualOp("left".to_string(), "right".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NegateNotEqualOp(pub String, pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for NegateNotEqualOp {
|
||
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()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NegateNotEqualOp("left".to_string(), "right".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DoubleNegation(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for DoubleNegation {
|
||
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}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DoubleNegation("expr".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AAndNotA(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for AAndNotA {
|
||
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()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AAndNotA("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AOrNotA(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for AOrNotA {
|
||
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()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AOrNotA("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct OrTrue;
|
||
);
|
||
impl AlwaysAutofixableViolation for OrTrue {
|
||
fn message(&self) -> String {
|
||
"Use `True` instead of `... or True`".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Replace with `True`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
OrTrue
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AndFalse;
|
||
);
|
||
impl AlwaysAutofixableViolation for AndFalse {
|
||
fn message(&self) -> String {
|
||
"Use `False` instead of `... and False`".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Replace with `False`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AndFalse
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct YodaConditions(pub String, pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for YodaConditions {
|
||
fn message(&self) -> String {
|
||
let YodaConditions(left, right) = self;
|
||
format!("Yoda conditions are discouraged, use `{left} == {right}` instead")
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
let YodaConditions(left, right) = self;
|
||
format!("Replace Yoda condition with `{left} == {right}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
YodaConditions("left".to_string(), "right".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct IfExprWithTrueFalse(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for IfExprWithTrueFalse {
|
||
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}")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
IfExprWithTrueFalse("expr".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct IfExprWithFalseTrue(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for IfExprWithFalseTrue {
|
||
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})")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
IfExprWithFalseTrue("expr".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct IfExprWithTwistedArms(pub String, pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for IfExprWithTwistedArms {
|
||
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}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
IfExprWithTwistedArms("a".to_string(), "b".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DictGetWithDefault(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for DictGetWithDefault {
|
||
fn message(&self) -> String {
|
||
let DictGetWithDefault(contents) = self;
|
||
format!("Use `{contents}` instead of an `if` block")
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
let DictGetWithDefault(contents) = self;
|
||
format!("Replace with `{contents}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DictGetWithDefault("var = dict.get(key, \"default\")".to_string())
|
||
}
|
||
}
|
||
// pyupgrade
|
||
|
||
define_violation!(
|
||
pub struct UselessMetaclassType;
|
||
);
|
||
impl AlwaysAutofixableViolation for UselessMetaclassType {
|
||
fn message(&self) -> String {
|
||
"`__metaclass__ = type` is implied".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove `__metaclass__ = type`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UselessMetaclassType
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct TypeOfPrimitive(pub Primitive);
|
||
);
|
||
impl AlwaysAutofixableViolation for TypeOfPrimitive {
|
||
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())
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
TypeOfPrimitive(Primitive::Str)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UselessObjectInheritance(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UselessObjectInheritance {
|
||
fn message(&self) -> String {
|
||
let UselessObjectInheritance(name) = self;
|
||
format!("Class `{name}` inherits from `object`")
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove `object` inheritance".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UselessObjectInheritance("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DeprecatedUnittestAlias(pub String, pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for DeprecatedUnittestAlias {
|
||
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}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DeprecatedUnittestAlias("assertEquals".to_string(), "assertEqual".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UsePEP585Annotation(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UsePEP585Annotation {
|
||
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(),)
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UsePEP585Annotation("List".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UsePEP604Annotation;
|
||
);
|
||
impl AlwaysAutofixableViolation for UsePEP604Annotation {
|
||
fn message(&self) -> String {
|
||
"Use `X | Y` for type annotations".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Convert to `X | Y`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UsePEP604Annotation
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SuperCallWithParameters;
|
||
);
|
||
impl AlwaysAutofixableViolation for SuperCallWithParameters {
|
||
fn message(&self) -> String {
|
||
"Use `super()` instead of `super(__class__, self)`".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove `__super__` parameters".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SuperCallWithParameters
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PEP3120UnnecessaryCodingComment;
|
||
);
|
||
impl AlwaysAutofixableViolation for PEP3120UnnecessaryCodingComment {
|
||
fn message(&self) -> String {
|
||
"UTF-8 encoding declaration is unnecessary".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove unnecessary coding comment".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PEP3120UnnecessaryCodingComment
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryFutureImport(pub Vec<String>);
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryFutureImport {
|
||
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()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryFutureImport(vec!["...".to_string()])
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct LRUCacheWithoutParameters;
|
||
);
|
||
impl AlwaysAutofixableViolation for LRUCacheWithoutParameters {
|
||
fn message(&self) -> String {
|
||
"Unnecessary parameters to `functools.lru_cache`".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove unnecessary parameters".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
LRUCacheWithoutParameters
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryEncodeUTF8;
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryEncodeUTF8 {
|
||
fn message(&self) -> String {
|
||
"Unnecessary call to `encode` as UTF-8".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove unnecessary `encode`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryEncodeUTF8
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ConvertTypedDictFunctionalToClass(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for ConvertTypedDictFunctionalToClass {
|
||
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")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ConvertTypedDictFunctionalToClass("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ConvertNamedTupleFunctionalToClass(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for ConvertNamedTupleFunctionalToClass {
|
||
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")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ConvertNamedTupleFunctionalToClass("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RedundantOpenModes(pub Option<String>);
|
||
);
|
||
impl AlwaysAutofixableViolation for RedundantOpenModes {
|
||
fn message(&self) -> String {
|
||
let RedundantOpenModes(replacement) = self;
|
||
match replacement {
|
||
None => "Unnecessary open mode parameters".to_string(),
|
||
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}\"")
|
||
}
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RedundantOpenModes(None)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RemoveSixCompat;
|
||
);
|
||
impl AlwaysAutofixableViolation for RemoveSixCompat {
|
||
fn message(&self) -> String {
|
||
"Unnecessary `six` compatibility usage".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove `six` usage".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RemoveSixCompat
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DatetimeTimezoneUTC {
|
||
pub straight_import: bool,
|
||
}
|
||
);
|
||
impl Violation for DatetimeTimezoneUTC {
|
||
fn message(&self) -> String {
|
||
"Use `datetime.UTC` alias".to_string()
|
||
}
|
||
|
||
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
|
||
if self.straight_import {
|
||
Some(|_| "Convert to `datetime.UTC` alias".to_string())
|
||
} else {
|
||
None
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DatetimeTimezoneUTC {
|
||
straight_import: true,
|
||
}
|
||
}
|
||
}
|
||
|
||
#[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 LiteralType);
|
||
);
|
||
impl AlwaysAutofixableViolation for NativeLiterals {
|
||
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}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NativeLiterals(LiteralType::Str)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct TypingTextStrAlias;
|
||
);
|
||
impl AlwaysAutofixableViolation for TypingTextStrAlias {
|
||
fn message(&self) -> String {
|
||
"`typing.Text` is deprecated, use `str`".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Replace with `str`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
TypingTextStrAlias
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct OpenAlias;
|
||
);
|
||
impl AlwaysAutofixableViolation for OpenAlias {
|
||
fn message(&self) -> String {
|
||
"Use builtin `open`".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Replace with builtin `open`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
OpenAlias
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ReplaceUniversalNewlines;
|
||
);
|
||
impl AlwaysAutofixableViolation for ReplaceUniversalNewlines {
|
||
fn message(&self) -> String {
|
||
"`universal_newlines` is deprecated, use `text`".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Replace with `text` keyword argument".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ReplaceUniversalNewlines
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ReplaceStdoutStderr;
|
||
);
|
||
impl AlwaysAutofixableViolation for ReplaceStdoutStderr {
|
||
fn message(&self) -> String {
|
||
"Sending stdout and stderr to pipe is deprecated, use `capture_output`".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Replace with `capture_output` keyword argument".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ReplaceStdoutStderr
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RewriteCElementTree;
|
||
);
|
||
impl AlwaysAutofixableViolation for RewriteCElementTree {
|
||
fn message(&self) -> String {
|
||
"`cElementTree` is deprecated, use `ElementTree`".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Replace with `ElementTree`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RewriteCElementTree
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct OSErrorAlias(pub Option<String>);
|
||
);
|
||
impl AlwaysAutofixableViolation for OSErrorAlias {
|
||
fn message(&self) -> String {
|
||
"Replace aliased errors with `OSError`".to_string()
|
||
}
|
||
|
||
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`"),
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
OSErrorAlias(None)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RewriteUnicodeLiteral;
|
||
);
|
||
impl AlwaysAutofixableViolation for RewriteUnicodeLiteral {
|
||
fn message(&self) -> String {
|
||
"Remove unicode literals from strings".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove unicode prefix".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RewriteUnicodeLiteral
|
||
}
|
||
}
|
||
|
||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||
pub enum MockReference {
|
||
Import,
|
||
Attribute,
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RewriteMockImport(pub MockReference);
|
||
);
|
||
impl AlwaysAutofixableViolation for RewriteMockImport {
|
||
fn message(&self) -> String {
|
||
"`mock` is deprecated, use `unittest.mock`".to_string()
|
||
}
|
||
|
||
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(),
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RewriteMockImport(MockReference::Import)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RewriteListComprehension;
|
||
);
|
||
impl AlwaysAutofixableViolation for RewriteListComprehension {
|
||
fn message(&self) -> String {
|
||
"Replace unpacked list comprehension with a generator expression".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Replace with generator expression".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RewriteListComprehension
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RewriteYieldFrom;
|
||
);
|
||
impl AlwaysAutofixableViolation for RewriteYieldFrom {
|
||
fn message(&self) -> String {
|
||
"Replace `yield` over `for` loop with `yield from`".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Replace with `yield from`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RewriteYieldFrom
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryBuiltinImport(pub Vec<String>);
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryBuiltinImport {
|
||
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()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryBuiltinImport(vec!["...".to_string()])
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct FormatLiterals;
|
||
);
|
||
impl AlwaysAutofixableViolation for FormatLiterals {
|
||
fn message(&self) -> String {
|
||
"Use implicit references for positional format fields".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove explicit positional indexes".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FormatLiterals
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct FString;
|
||
);
|
||
impl AlwaysAutofixableViolation for FString {
|
||
fn message(&self) -> String {
|
||
"Use f-string instead of `format` call".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Convert to f-string".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FString
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct FunctoolsCache;
|
||
);
|
||
impl AlwaysAutofixableViolation for FunctoolsCache {
|
||
fn message(&self) -> String {
|
||
"Use `@functools.cache` instead of `@functools.lru_cache(maxsize=None)`".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Rewrite with `@functools.cache".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FunctoolsCache
|
||
}
|
||
}
|
||
|
||
// pydocstyle
|
||
|
||
define_violation!(
|
||
pub struct PublicModule;
|
||
);
|
||
impl Violation for PublicModule {
|
||
fn message(&self) -> String {
|
||
"Missing docstring in public module".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PublicModule
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PublicClass;
|
||
);
|
||
impl Violation for PublicClass {
|
||
fn message(&self) -> String {
|
||
"Missing docstring in public class".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PublicClass
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PublicMethod;
|
||
);
|
||
impl Violation for PublicMethod {
|
||
fn message(&self) -> String {
|
||
"Missing docstring in public method".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PublicMethod
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PublicFunction;
|
||
);
|
||
impl Violation for PublicFunction {
|
||
fn message(&self) -> String {
|
||
"Missing docstring in public function".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PublicFunction
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PublicPackage;
|
||
);
|
||
impl Violation for PublicPackage {
|
||
fn message(&self) -> String {
|
||
"Missing docstring in public package".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PublicPackage
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MagicMethod;
|
||
);
|
||
impl Violation for MagicMethod {
|
||
fn message(&self) -> String {
|
||
"Missing docstring in magic method".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MagicMethod
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PublicNestedClass;
|
||
);
|
||
impl Violation for PublicNestedClass {
|
||
fn message(&self) -> String {
|
||
"Missing docstring in public nested class".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PublicNestedClass
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PublicInit;
|
||
);
|
||
impl Violation for PublicInit {
|
||
fn message(&self) -> String {
|
||
"Missing docstring in `__init__`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PublicInit
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct FitsOnOneLine;
|
||
);
|
||
impl Violation for FitsOnOneLine {
|
||
fn message(&self) -> String {
|
||
"One-line docstring should fit on one line".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FitsOnOneLine
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NoBlankLineBeforeFunction(pub usize);
|
||
);
|
||
impl AlwaysAutofixableViolation for NoBlankLineBeforeFunction {
|
||
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()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NoBlankLineBeforeFunction(1)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NoBlankLineAfterFunction(pub usize);
|
||
);
|
||
impl AlwaysAutofixableViolation for NoBlankLineAfterFunction {
|
||
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()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NoBlankLineAfterFunction(1)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct OneBlankLineBeforeClass(pub usize);
|
||
);
|
||
impl AlwaysAutofixableViolation for OneBlankLineBeforeClass {
|
||
fn message(&self) -> String {
|
||
"1 blank line required before class docstring".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Insert 1 blank line before class docstring".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
OneBlankLineBeforeClass(0)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct OneBlankLineAfterClass(pub usize);
|
||
);
|
||
impl AlwaysAutofixableViolation for OneBlankLineAfterClass {
|
||
fn message(&self) -> String {
|
||
"1 blank line required after class docstring".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Insert 1 blank line after class docstring".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
OneBlankLineAfterClass(0)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct BlankLineAfterSummary(pub usize);
|
||
);
|
||
fn fmt_blank_line_after_summary_autofix_msg(_: &BlankLineAfterSummary) -> String {
|
||
"Insert single blank line".to_string()
|
||
}
|
||
impl Violation for BlankLineAfterSummary {
|
||
fn message(&self) -> String {
|
||
let BlankLineAfterSummary(num_lines) = self;
|
||
if *num_lines == 0 {
|
||
"1 blank line required between summary line and description".to_string()
|
||
} else {
|
||
format!(
|
||
"1 blank line required between summary line and description (found {num_lines})"
|
||
)
|
||
}
|
||
}
|
||
|
||
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
|
||
let num_lines = self.0;
|
||
if num_lines > 0 {
|
||
return Some(fmt_blank_line_after_summary_autofix_msg);
|
||
}
|
||
None
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BlankLineAfterSummary(2)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct IndentWithSpaces;
|
||
);
|
||
impl Violation for IndentWithSpaces {
|
||
fn message(&self) -> String {
|
||
"Docstring should be indented with spaces, not tabs".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
IndentWithSpaces
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NoUnderIndentation;
|
||
);
|
||
impl AlwaysAutofixableViolation for NoUnderIndentation {
|
||
fn message(&self) -> String {
|
||
"Docstring is under-indented".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Increase indentation".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NoUnderIndentation
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NoOverIndentation;
|
||
);
|
||
impl AlwaysAutofixableViolation for NoOverIndentation {
|
||
fn message(&self) -> String {
|
||
"Docstring is over-indented".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove over-indentation".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NoOverIndentation
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NewLineAfterLastParagraph;
|
||
);
|
||
impl AlwaysAutofixableViolation for NewLineAfterLastParagraph {
|
||
fn message(&self) -> String {
|
||
"Multi-line docstring closing quotes should be on a separate line".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Move closing quotes to new line".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NewLineAfterLastParagraph
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NoSurroundingWhitespace;
|
||
);
|
||
impl AlwaysAutofixableViolation for NoSurroundingWhitespace {
|
||
fn message(&self) -> String {
|
||
"No whitespaces allowed surrounding docstring text".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Trim surrounding whitespace".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NoSurroundingWhitespace
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NoBlankLineBeforeClass(pub usize);
|
||
);
|
||
impl AlwaysAutofixableViolation for NoBlankLineBeforeClass {
|
||
fn message(&self) -> String {
|
||
"No blank lines allowed before class docstring".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove blank line(s) before class docstring".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NoBlankLineBeforeClass(1)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MultiLineSummaryFirstLine;
|
||
);
|
||
impl Violation for MultiLineSummaryFirstLine {
|
||
fn message(&self) -> String {
|
||
"Multi-line docstring summary should start at the first line".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MultiLineSummaryFirstLine
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MultiLineSummarySecondLine;
|
||
);
|
||
impl Violation for MultiLineSummarySecondLine {
|
||
fn message(&self) -> String {
|
||
"Multi-line docstring summary should start at the second line".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MultiLineSummarySecondLine
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SectionNotOverIndented(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for SectionNotOverIndented {
|
||
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}\"")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SectionNotOverIndented("Returns".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SectionUnderlineNotOverIndented(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for SectionUnderlineNotOverIndented {
|
||
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")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SectionUnderlineNotOverIndented("Returns".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UsesTripleQuotes;
|
||
);
|
||
impl Violation for UsesTripleQuotes {
|
||
fn message(&self) -> String {
|
||
r#"Use """triple double quotes""""#.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UsesTripleQuotes
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UsesRPrefixForBackslashedContent;
|
||
);
|
||
impl Violation for UsesRPrefixForBackslashedContent {
|
||
fn message(&self) -> String {
|
||
r#"Use r""" if any backslashes in a docstring"#.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UsesRPrefixForBackslashedContent
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct EndsInPeriod;
|
||
);
|
||
impl AlwaysAutofixableViolation for EndsInPeriod {
|
||
fn message(&self) -> String {
|
||
"First line should end with a period".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Add period".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
EndsInPeriod
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NoSignature;
|
||
);
|
||
impl Violation for NoSignature {
|
||
fn message(&self) -> String {
|
||
"First line should not be the function's signature".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NoSignature
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct FirstLineCapitalized;
|
||
);
|
||
impl Violation for FirstLineCapitalized {
|
||
fn message(&self) -> String {
|
||
"First word of the first line should be properly capitalized".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FirstLineCapitalized
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NoThisPrefix;
|
||
);
|
||
impl Violation for NoThisPrefix {
|
||
fn message(&self) -> String {
|
||
"First word of the docstring should not be \"This\"".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NoThisPrefix
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CapitalizeSectionName(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for CapitalizeSectionName {
|
||
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}\"")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CapitalizeSectionName("returns".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NewLineAfterSectionName(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for NewLineAfterSectionName {
|
||
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}\"")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NewLineAfterSectionName("Returns".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DashedUnderlineAfterSection(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for DashedUnderlineAfterSection {
|
||
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}\"")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DashedUnderlineAfterSection("Returns".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SectionUnderlineAfterName(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for SectionUnderlineAfterName {
|
||
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}\"")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SectionUnderlineAfterName("Returns".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SectionUnderlineMatchesSectionLength(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for SectionUnderlineMatchesSectionLength {
|
||
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}\"")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SectionUnderlineMatchesSectionLength("Returns".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct BlankLineAfterSection(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for BlankLineAfterSection {
|
||
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}\"")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BlankLineAfterSection("Returns".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct BlankLineBeforeSection(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for BlankLineBeforeSection {
|
||
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}\"")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BlankLineBeforeSection("Returns".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NoBlankLinesBetweenHeaderAndContent(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for NoBlankLinesBetweenHeaderAndContent {
|
||
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()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NoBlankLinesBetweenHeaderAndContent("Returns".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct BlankLineAfterLastSection(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for BlankLineAfterLastSection {
|
||
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}\"")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BlankLineAfterLastSection("Returns".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NonEmptySection(pub String);
|
||
);
|
||
impl Violation for NonEmptySection {
|
||
fn message(&self) -> String {
|
||
let NonEmptySection(name) = self;
|
||
format!("Section has no content (\"{name}\")")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NonEmptySection("Returns".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct EndsInPunctuation;
|
||
);
|
||
impl AlwaysAutofixableViolation for EndsInPunctuation {
|
||
fn message(&self) -> String {
|
||
"First line should end with a period, question mark, or exclamation point".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Add closing punctuation".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
EndsInPunctuation
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SectionNameEndsInColon(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for SectionNameEndsInColon {
|
||
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}\"")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SectionNameEndsInColon("Returns".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DocumentAllArguments(pub Vec<String>);
|
||
);
|
||
impl Violation for DocumentAllArguments {
|
||
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}")
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DocumentAllArguments(vec!["x".to_string(), "y".to_string()])
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SkipDocstring;
|
||
);
|
||
impl Violation for SkipDocstring {
|
||
fn message(&self) -> String {
|
||
"Function decorated with `@overload` shouldn't contain a docstring".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SkipDocstring
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NonEmpty;
|
||
);
|
||
impl Violation for NonEmpty {
|
||
fn message(&self) -> String {
|
||
"Docstring is empty".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NonEmpty
|
||
}
|
||
}
|
||
|
||
// pep8-naming
|
||
|
||
define_violation!(
|
||
pub struct InvalidClassName(pub String);
|
||
);
|
||
impl Violation for InvalidClassName {
|
||
fn message(&self) -> String {
|
||
let InvalidClassName(name) = self;
|
||
format!("Class name `{name}` should use CapWords convention ")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
InvalidClassName("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct InvalidFunctionName(pub String);
|
||
);
|
||
impl Violation for InvalidFunctionName {
|
||
fn message(&self) -> String {
|
||
let InvalidFunctionName(name) = self;
|
||
format!("Function name `{name}` should be lowercase")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
InvalidFunctionName("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct InvalidArgumentName(pub String);
|
||
);
|
||
impl Violation for InvalidArgumentName {
|
||
fn message(&self) -> String {
|
||
let InvalidArgumentName(name) = self;
|
||
format!("Argument name `{name}` should be lowercase")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
InvalidArgumentName("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct InvalidFirstArgumentNameForClassMethod;
|
||
);
|
||
impl Violation for InvalidFirstArgumentNameForClassMethod {
|
||
fn message(&self) -> String {
|
||
"First argument of a class method should be named `cls`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
InvalidFirstArgumentNameForClassMethod
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct InvalidFirstArgumentNameForMethod;
|
||
);
|
||
impl Violation for InvalidFirstArgumentNameForMethod {
|
||
fn message(&self) -> String {
|
||
"First argument of a method should be named `self`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
InvalidFirstArgumentNameForMethod
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct NonLowercaseVariableInFunction(pub String);
|
||
);
|
||
impl Violation for NonLowercaseVariableInFunction {
|
||
fn message(&self) -> String {
|
||
let NonLowercaseVariableInFunction(name) = self;
|
||
format!("Variable `{name}` in function should be lowercase")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NonLowercaseVariableInFunction("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DunderFunctionName;
|
||
);
|
||
impl Violation for DunderFunctionName {
|
||
fn message(&self) -> String {
|
||
"Function name should not start and end with `__`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DunderFunctionName
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ConstantImportedAsNonConstant(pub String, pub String);
|
||
);
|
||
impl Violation for ConstantImportedAsNonConstant {
|
||
fn message(&self) -> String {
|
||
let ConstantImportedAsNonConstant(name, asname) = self;
|
||
format!("Constant `{name}` imported as non-constant `{asname}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ConstantImportedAsNonConstant("...".to_string(), "...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct LowercaseImportedAsNonLowercase(pub String, pub String);
|
||
);
|
||
impl Violation for LowercaseImportedAsNonLowercase {
|
||
fn message(&self) -> String {
|
||
let LowercaseImportedAsNonLowercase(name, asname) = self;
|
||
format!("Lowercase `{name}` imported as non-lowercase `{asname}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
LowercaseImportedAsNonLowercase("...".to_string(), "...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CamelcaseImportedAsLowercase(pub String, pub String);
|
||
);
|
||
impl Violation for CamelcaseImportedAsLowercase {
|
||
fn message(&self) -> String {
|
||
let CamelcaseImportedAsLowercase(name, asname) = self;
|
||
format!("Camelcase `{name}` imported as lowercase `{asname}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CamelcaseImportedAsLowercase("...".to_string(), "...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CamelcaseImportedAsConstant(pub String, pub String);
|
||
);
|
||
impl Violation for CamelcaseImportedAsConstant {
|
||
fn message(&self) -> String {
|
||
let CamelcaseImportedAsConstant(name, asname) = self;
|
||
format!("Camelcase `{name}` imported as constant `{asname}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CamelcaseImportedAsConstant("...".to_string(), "...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MixedCaseVariableInClassScope(pub String);
|
||
);
|
||
impl Violation for MixedCaseVariableInClassScope {
|
||
fn message(&self) -> String {
|
||
let MixedCaseVariableInClassScope(name) = self;
|
||
format!("Variable `{name}` in class scope should not be mixedCase")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MixedCaseVariableInClassScope("mixedCase".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MixedCaseVariableInGlobalScope(pub String);
|
||
);
|
||
impl Violation for MixedCaseVariableInGlobalScope {
|
||
fn message(&self) -> String {
|
||
let MixedCaseVariableInGlobalScope(name) = self;
|
||
format!("Variable `{name}` in global scope should not be mixedCase")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MixedCaseVariableInGlobalScope("mixedCase".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CamelcaseImportedAsAcronym(pub String, pub String);
|
||
);
|
||
impl Violation for CamelcaseImportedAsAcronym {
|
||
fn message(&self) -> String {
|
||
let CamelcaseImportedAsAcronym(name, asname) = self;
|
||
format!("Camelcase `{name}` imported as acronym `{asname}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CamelcaseImportedAsAcronym("...".to_string(), "...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ErrorSuffixOnExceptionName(pub String);
|
||
);
|
||
impl Violation for ErrorSuffixOnExceptionName {
|
||
fn message(&self) -> String {
|
||
let ErrorSuffixOnExceptionName(name) = self;
|
||
format!("Exception name `{name}` should be named with an Error suffix")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ErrorSuffixOnExceptionName("...".to_string())
|
||
}
|
||
}
|
||
|
||
// isort
|
||
|
||
define_violation!(
|
||
pub struct UnsortedImports;
|
||
);
|
||
impl AlwaysAutofixableViolation for UnsortedImports {
|
||
fn message(&self) -> String {
|
||
"Import block is un-sorted or un-formatted".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Organize imports".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnsortedImports
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MissingRequiredImport(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for MissingRequiredImport {
|
||
fn message(&self) -> String {
|
||
let MissingRequiredImport(name) = self;
|
||
format!("Missing required import: `{name}`")
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
let MissingRequiredImport(name) = self;
|
||
format!("Insert required import: `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MissingRequiredImport("from __future__ import ...".to_string())
|
||
}
|
||
}
|
||
|
||
// eradicate
|
||
|
||
define_violation!(
|
||
pub struct CommentedOutCode;
|
||
);
|
||
impl AlwaysAutofixableViolation for CommentedOutCode {
|
||
fn message(&self) -> String {
|
||
"Found commented-out code".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove commented-out code".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CommentedOutCode
|
||
}
|
||
}
|
||
|
||
// flake8-bandit
|
||
|
||
define_violation!(
|
||
pub struct Jinja2AutoescapeFalse(pub bool);
|
||
);
|
||
impl Violation for Jinja2AutoescapeFalse {
|
||
fn message(&self) -> String {
|
||
let Jinja2AutoescapeFalse(value) = self;
|
||
match value {
|
||
true => "Using jinja2 templates with `autoescape=False` is dangerous and can lead to \
|
||
XSS. Ensure `autoescape=True` or use the `select_autoescape` function."
|
||
.to_string(),
|
||
false => "By default, jinja2 sets `autoescape` to `False`. Consider using \
|
||
`autoescape=True` or the `select_autoescape` function to mitigate XSS \
|
||
vulnerabilities."
|
||
.to_string(),
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
Jinja2AutoescapeFalse(false)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AssertUsed;
|
||
);
|
||
impl Violation for AssertUsed {
|
||
fn message(&self) -> String {
|
||
"Use of `assert` detected".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AssertUsed
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ExecUsed;
|
||
);
|
||
impl Violation for ExecUsed {
|
||
fn message(&self) -> String {
|
||
"Use of `exec` detected".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ExecUsed
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct BadFilePermissions(pub u16);
|
||
);
|
||
impl Violation for BadFilePermissions {
|
||
fn message(&self) -> String {
|
||
let BadFilePermissions(mask) = self;
|
||
format!("`os.chmod` setting a permissive mask `{mask:#o}` on file or directory",)
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BadFilePermissions(0o777)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct HardcodedBindAllInterfaces;
|
||
);
|
||
impl Violation for HardcodedBindAllInterfaces {
|
||
fn message(&self) -> String {
|
||
"Possible binding to all interfaces".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
HardcodedBindAllInterfaces
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct HardcodedPasswordString(pub String);
|
||
);
|
||
impl Violation for HardcodedPasswordString {
|
||
fn message(&self) -> String {
|
||
let HardcodedPasswordString(string) = self;
|
||
format!("Possible hardcoded password: \"{}\"", string.escape_debug())
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
HardcodedPasswordString("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct HardcodedPasswordFuncArg(pub String);
|
||
);
|
||
impl Violation for HardcodedPasswordFuncArg {
|
||
fn message(&self) -> String {
|
||
let HardcodedPasswordFuncArg(string) = self;
|
||
format!("Possible hardcoded password: \"{}\"", string.escape_debug())
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
HardcodedPasswordFuncArg("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct HardcodedPasswordDefault(pub String);
|
||
);
|
||
impl Violation for HardcodedPasswordDefault {
|
||
fn message(&self) -> String {
|
||
let HardcodedPasswordDefault(string) = self;
|
||
format!("Possible hardcoded password: \"{}\"", string.escape_debug())
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
HardcodedPasswordDefault("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct HardcodedTempFile(pub String);
|
||
);
|
||
impl Violation for HardcodedTempFile {
|
||
fn message(&self) -> String {
|
||
let HardcodedTempFile(string) = self;
|
||
format!(
|
||
"Probable insecure usage of temporary file or directory: \"{}\"",
|
||
string.escape_debug()
|
||
)
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
HardcodedTempFile("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RequestWithoutTimeout(pub Option<String>);
|
||
);
|
||
impl Violation for RequestWithoutTimeout {
|
||
fn message(&self) -> String {
|
||
let RequestWithoutTimeout(timeout) = self;
|
||
match timeout {
|
||
Some(value) => {
|
||
format!("Probable use of requests call with timeout set to `{value}`")
|
||
}
|
||
None => "Probable use of requests call without timeout".to_string(),
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RequestWithoutTimeout(None)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct HashlibInsecureHashFunction(pub String);
|
||
);
|
||
impl Violation for HashlibInsecureHashFunction {
|
||
fn message(&self) -> String {
|
||
let HashlibInsecureHashFunction(string) = self;
|
||
format!(
|
||
"Probable use of insecure hash functions in `hashlib`: \"{}\"",
|
||
string.escape_debug()
|
||
)
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
HashlibInsecureHashFunction("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RequestWithNoCertValidation(pub String);
|
||
);
|
||
impl Violation for RequestWithNoCertValidation {
|
||
fn message(&self) -> String {
|
||
let RequestWithNoCertValidation(string) = self;
|
||
format!(
|
||
"Probable use of `{string}` call with `verify=False` disabling SSL certificate checks"
|
||
)
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RequestWithNoCertValidation("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnsafeYAMLLoad(pub Option<String>);
|
||
);
|
||
impl Violation for UnsafeYAMLLoad {
|
||
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 => "Probable use of unsafe `yaml.load`. Allows instantiation of arbitrary \
|
||
objects. Consider `yaml.safe_load`."
|
||
.to_string(),
|
||
}
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnsafeYAMLLoad(None)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SnmpInsecureVersion;
|
||
);
|
||
impl Violation for SnmpInsecureVersion {
|
||
fn message(&self) -> String {
|
||
"The use of SNMPv1 and SNMPv2 is insecure. Use SNMPv3 if able.".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SnmpInsecureVersion
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct SnmpWeakCryptography;
|
||
);
|
||
impl Violation for SnmpWeakCryptography {
|
||
fn message(&self) -> String {
|
||
"You should not use SNMPv3 without encryption. `noAuthNoPriv` & `authNoPriv` is insecure."
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
SnmpWeakCryptography
|
||
}
|
||
}
|
||
|
||
// flake8-boolean-trap
|
||
|
||
define_violation!(
|
||
pub struct BooleanPositionalArgInFunctionDefinition;
|
||
);
|
||
impl Violation for BooleanPositionalArgInFunctionDefinition {
|
||
fn message(&self) -> String {
|
||
"Boolean positional arg in function definition".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BooleanPositionalArgInFunctionDefinition
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct BooleanDefaultValueInFunctionDefinition;
|
||
);
|
||
impl Violation for BooleanDefaultValueInFunctionDefinition {
|
||
fn message(&self) -> String {
|
||
"Boolean default value in function definition".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BooleanDefaultValueInFunctionDefinition
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct BooleanPositionalValueInFunctionCall;
|
||
);
|
||
impl Violation for BooleanPositionalValueInFunctionCall {
|
||
fn message(&self) -> String {
|
||
"Boolean positional value in function call".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BooleanPositionalValueInFunctionCall
|
||
}
|
||
}
|
||
|
||
// flake8-unused-arguments
|
||
|
||
define_violation!(
|
||
pub struct UnusedFunctionArgument(pub String);
|
||
);
|
||
impl Violation for UnusedFunctionArgument {
|
||
fn message(&self) -> String {
|
||
let UnusedFunctionArgument(name) = self;
|
||
format!("Unused function argument: `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnusedFunctionArgument("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnusedMethodArgument(pub String);
|
||
);
|
||
impl Violation for UnusedMethodArgument {
|
||
fn message(&self) -> String {
|
||
let UnusedMethodArgument(name) = self;
|
||
format!("Unused method argument: `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnusedMethodArgument("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnusedClassMethodArgument(pub String);
|
||
);
|
||
impl Violation for UnusedClassMethodArgument {
|
||
fn message(&self) -> String {
|
||
let UnusedClassMethodArgument(name) = self;
|
||
format!("Unused class method argument: `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnusedClassMethodArgument("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnusedStaticMethodArgument(pub String);
|
||
);
|
||
impl Violation for UnusedStaticMethodArgument {
|
||
fn message(&self) -> String {
|
||
let UnusedStaticMethodArgument(name) = self;
|
||
format!("Unused static method argument: `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnusedStaticMethodArgument("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnusedLambdaArgument(pub String);
|
||
);
|
||
impl Violation for UnusedLambdaArgument {
|
||
fn message(&self) -> String {
|
||
let UnusedLambdaArgument(name) = self;
|
||
format!("Unused lambda argument: `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnusedLambdaArgument("...".to_string())
|
||
}
|
||
}
|
||
|
||
// flake8-import-conventions
|
||
|
||
define_violation!(
|
||
pub struct ImportAliasIsNotConventional(pub String, pub String);
|
||
);
|
||
impl Violation for ImportAliasIsNotConventional {
|
||
fn message(&self) -> String {
|
||
let ImportAliasIsNotConventional(name, asname) = self;
|
||
format!("`{name}` should be imported as `{asname}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ImportAliasIsNotConventional("...".to_string(), "...".to_string())
|
||
}
|
||
}
|
||
|
||
// flake8-datetimez
|
||
|
||
define_violation!(
|
||
pub struct CallDatetimeWithoutTzinfo;
|
||
);
|
||
impl Violation for CallDatetimeWithoutTzinfo {
|
||
fn message(&self) -> String {
|
||
"The use of `datetime.datetime()` without `tzinfo` argument is not allowed".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CallDatetimeWithoutTzinfo
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CallDatetimeToday;
|
||
);
|
||
impl Violation for CallDatetimeToday {
|
||
fn message(&self) -> String {
|
||
"The use of `datetime.datetime.today()` is not allowed. Use `datetime.datetime.now(tz=)` \
|
||
instead."
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CallDatetimeToday
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CallDatetimeUtcnow;
|
||
);
|
||
impl Violation for CallDatetimeUtcnow {
|
||
fn message(&self) -> String {
|
||
"The use of `datetime.datetime.utcnow()` is not allowed. Use `datetime.datetime.now(tz=)` \
|
||
instead."
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CallDatetimeUtcnow
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CallDatetimeUtcfromtimestamp;
|
||
);
|
||
impl Violation for CallDatetimeUtcfromtimestamp {
|
||
fn message(&self) -> String {
|
||
"The use of `datetime.datetime.utcfromtimestamp()` is not allowed. Use \
|
||
`datetime.datetime.fromtimestamp(, tz=)` instead."
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CallDatetimeUtcfromtimestamp
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CallDatetimeNowWithoutTzinfo;
|
||
);
|
||
impl Violation for CallDatetimeNowWithoutTzinfo {
|
||
fn message(&self) -> String {
|
||
"The use of `datetime.datetime.now()` without `tz` argument is not allowed".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CallDatetimeNowWithoutTzinfo
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CallDatetimeFromtimestamp;
|
||
);
|
||
impl Violation for CallDatetimeFromtimestamp {
|
||
fn message(&self) -> String {
|
||
"The use of `datetime.datetime.fromtimestamp()` without `tz` argument is not allowed"
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CallDatetimeFromtimestamp
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CallDatetimeStrptimeWithoutZone;
|
||
);
|
||
impl Violation for CallDatetimeStrptimeWithoutZone {
|
||
fn message(&self) -> String {
|
||
"The use of `datetime.datetime.strptime()` without %z must be followed by \
|
||
`.replace(tzinfo=)`"
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CallDatetimeStrptimeWithoutZone
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CallDateToday;
|
||
);
|
||
impl Violation for CallDateToday {
|
||
fn message(&self) -> String {
|
||
"The use of `datetime.date.today()` is not allowed. Use \
|
||
`datetime.datetime.now(tz=).date()` instead."
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CallDateToday
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CallDateFromtimestamp;
|
||
);
|
||
impl Violation for CallDateFromtimestamp {
|
||
fn message(&self) -> String {
|
||
"The use of `datetime.date.fromtimestamp()` is not allowed. Use \
|
||
`datetime.datetime.fromtimestamp(, tz=).date()` instead."
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CallDateFromtimestamp
|
||
}
|
||
}
|
||
|
||
// pygrep-hooks
|
||
|
||
define_violation!(
|
||
pub struct NoEval;
|
||
);
|
||
impl Violation for NoEval {
|
||
fn message(&self) -> String {
|
||
"No builtin `eval()` allowed".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NoEval
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DeprecatedLogWarn;
|
||
);
|
||
impl Violation for DeprecatedLogWarn {
|
||
fn message(&self) -> String {
|
||
"`warn` is deprecated in favor of `warning`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DeprecatedLogWarn
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct BlanketTypeIgnore;
|
||
);
|
||
impl Violation for BlanketTypeIgnore {
|
||
fn message(&self) -> String {
|
||
"Use specific rule codes when ignoring type issues".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BlanketTypeIgnore
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct BlanketNOQA;
|
||
);
|
||
impl Violation for BlanketNOQA {
|
||
fn message(&self) -> String {
|
||
"Use specific rule codes when using `noqa`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
BlanketNOQA
|
||
}
|
||
}
|
||
|
||
// pandas-vet
|
||
|
||
define_violation!(
|
||
pub struct UseOfInplaceArgument;
|
||
);
|
||
impl Violation for UseOfInplaceArgument {
|
||
fn message(&self) -> String {
|
||
"`inplace=True` should be avoided; it has inconsistent behavior".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseOfInplaceArgument
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UseOfDotIsNull;
|
||
);
|
||
impl Violation for UseOfDotIsNull {
|
||
fn message(&self) -> String {
|
||
"`.isna` is preferred to `.isnull`; functionality is equivalent".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseOfDotIsNull
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UseOfDotNotNull;
|
||
);
|
||
impl Violation for UseOfDotNotNull {
|
||
fn message(&self) -> String {
|
||
"`.notna` is preferred to `.notnull`; functionality is equivalent".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseOfDotNotNull
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UseOfDotIx;
|
||
);
|
||
impl Violation for UseOfDotIx {
|
||
fn message(&self) -> String {
|
||
"`.ix` is deprecated; use more explicit `.loc` or `.iloc`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseOfDotIx
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UseOfDotAt;
|
||
);
|
||
impl Violation for UseOfDotAt {
|
||
fn message(&self) -> String {
|
||
"Use `.loc` instead of `.at`. If speed is important, use numpy.".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseOfDotAt
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UseOfDotIat;
|
||
);
|
||
impl Violation for UseOfDotIat {
|
||
fn message(&self) -> String {
|
||
"Use `.iloc` instead of `.iat`. If speed is important, use numpy.".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseOfDotIat
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UseOfDotPivotOrUnstack;
|
||
);
|
||
impl Violation for UseOfDotPivotOrUnstack {
|
||
fn message(&self) -> String {
|
||
"`.pivot_table` is preferred to `.pivot` or `.unstack`; provides same functionality"
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseOfDotPivotOrUnstack
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UseOfDotValues;
|
||
);
|
||
impl Violation for UseOfDotValues {
|
||
fn message(&self) -> String {
|
||
"Use `.to_numpy()` instead of `.values`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseOfDotValues
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UseOfDotReadTable;
|
||
);
|
||
impl Violation for UseOfDotReadTable {
|
||
fn message(&self) -> String {
|
||
"`.read_csv` is preferred to `.read_table`; provides same functionality".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseOfDotReadTable
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UseOfDotStack;
|
||
);
|
||
impl Violation for UseOfDotStack {
|
||
fn message(&self) -> String {
|
||
"`.melt` is preferred to `.stack`; provides same functionality".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseOfDotStack
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UseOfPdMerge;
|
||
);
|
||
impl Violation for UseOfPdMerge {
|
||
fn message(&self) -> String {
|
||
"Use `.merge` method instead of `pd.merge` function. They have equivalent functionality."
|
||
.to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseOfPdMerge
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DfIsABadVariableName;
|
||
);
|
||
impl Violation for DfIsABadVariableName {
|
||
fn message(&self) -> String {
|
||
"`df` is a bad variable name. Be kinder to your future self.".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DfIsABadVariableName
|
||
}
|
||
}
|
||
|
||
// flake8-errmsg
|
||
|
||
define_violation!(
|
||
pub struct RawStringInException;
|
||
);
|
||
impl Violation for RawStringInException {
|
||
fn message(&self) -> String {
|
||
"Exception must not use a string literal, assign to variable first".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RawStringInException
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct FStringInException;
|
||
);
|
||
impl Violation for FStringInException {
|
||
fn message(&self) -> String {
|
||
"Exception must not use an f-string literal, assign to variable first".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FStringInException
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DotFormatInException;
|
||
);
|
||
impl Violation for DotFormatInException {
|
||
fn message(&self) -> String {
|
||
"Exception must not use a `.format()` string directly, assign to variable first".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DotFormatInException
|
||
}
|
||
}
|
||
|
||
// flake8-pytest-style
|
||
|
||
define_violation!(
|
||
pub struct IncorrectFixtureParenthesesStyle(pub String, pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for IncorrectFixtureParenthesesStyle {
|
||
fn message(&self) -> String {
|
||
let IncorrectFixtureParenthesesStyle(expected_parens, actual_parens) = self;
|
||
format!("Use `@pytest.fixture{expected_parens}` over `@pytest.fixture{actual_parens}`")
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Add/remove parentheses".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
IncorrectFixtureParenthesesStyle("()".to_string(), String::new())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct FixturePositionalArgs(pub String);
|
||
);
|
||
impl Violation for FixturePositionalArgs {
|
||
fn message(&self) -> String {
|
||
let FixturePositionalArgs(function) = self;
|
||
format!("Configuration for fixture `{function}` specified via positional args, use kwargs")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FixturePositionalArgs("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ExtraneousScopeFunction;
|
||
);
|
||
impl Violation for ExtraneousScopeFunction {
|
||
fn message(&self) -> String {
|
||
"`scope='function'` is implied in `@pytest.fixture()`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ExtraneousScopeFunction
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct MissingFixtureNameUnderscore(pub String);
|
||
);
|
||
impl Violation for MissingFixtureNameUnderscore {
|
||
fn message(&self) -> String {
|
||
let MissingFixtureNameUnderscore(function) = self;
|
||
format!("Fixture `{function}` does not return anything, add leading underscore")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
MissingFixtureNameUnderscore("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct IncorrectFixtureNameUnderscore(pub String);
|
||
);
|
||
impl Violation for IncorrectFixtureNameUnderscore {
|
||
fn message(&self) -> String {
|
||
let IncorrectFixtureNameUnderscore(function) = self;
|
||
format!("Fixture `{function}` returns a value, remove leading underscore")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
IncorrectFixtureNameUnderscore("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ParametrizeNamesWrongType(pub ParametrizeNameType);
|
||
);
|
||
impl AlwaysAutofixableViolation for ParametrizeNamesWrongType {
|
||
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")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ParametrizeNamesWrongType(ParametrizeNameType::Tuple)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ParametrizeValuesWrongType(pub ParametrizeValuesType, pub ParametrizeValuesRowType);
|
||
);
|
||
impl Violation for ParametrizeValuesWrongType {
|
||
fn message(&self) -> String {
|
||
let ParametrizeValuesWrongType(values, row) = self;
|
||
format!("Wrong values type in `@pytest.mark.parametrize` expected `{values}` of `{row}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ParametrizeValuesWrongType(ParametrizeValuesType::List, ParametrizeValuesRowType::Tuple)
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PatchWithLambda;
|
||
);
|
||
impl Violation for PatchWithLambda {
|
||
fn message(&self) -> String {
|
||
"Use `return_value=` instead of patching with `lambda`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PatchWithLambda
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnittestAssertion(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UnittestAssertion {
|
||
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 ...`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnittestAssertion("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RaisesWithoutException;
|
||
);
|
||
impl Violation for RaisesWithoutException {
|
||
fn message(&self) -> String {
|
||
"set the expected exception in `pytest.raises()`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RaisesWithoutException
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RaisesTooBroad(pub String);
|
||
);
|
||
impl Violation for RaisesTooBroad {
|
||
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"
|
||
)
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RaisesTooBroad("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct RaisesWithMultipleStatements;
|
||
);
|
||
impl Violation for RaisesWithMultipleStatements {
|
||
fn message(&self) -> String {
|
||
"`pytest.raises()` block should contain a single simple statement".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
RaisesWithMultipleStatements
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct IncorrectPytestImport;
|
||
);
|
||
impl Violation for IncorrectPytestImport {
|
||
fn message(&self) -> String {
|
||
"Found incorrect import of pytest, use simple `import pytest` instead".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
IncorrectPytestImport
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AssertAlwaysFalse;
|
||
);
|
||
impl Violation for AssertAlwaysFalse {
|
||
fn message(&self) -> String {
|
||
"Assertion always fails, replace with `pytest.fail()`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AssertAlwaysFalse
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct FailWithoutMessage;
|
||
);
|
||
impl Violation for FailWithoutMessage {
|
||
fn message(&self) -> String {
|
||
"No message passed to `pytest.fail()`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FailWithoutMessage
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AssertInExcept(pub String);
|
||
);
|
||
impl Violation for AssertInExcept {
|
||
fn message(&self) -> String {
|
||
let AssertInExcept(name) = self;
|
||
format!(
|
||
"Found assertion on exception `{name}` in except block, use `pytest.raises()` instead"
|
||
)
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AssertInExcept("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct CompositeAssertion;
|
||
);
|
||
impl Violation for CompositeAssertion {
|
||
fn message(&self) -> String {
|
||
"Assertion should be broken down into multiple parts".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
CompositeAssertion
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct FixtureParamWithoutValue(pub String);
|
||
);
|
||
impl Violation for FixtureParamWithoutValue {
|
||
fn message(&self) -> String {
|
||
let FixtureParamWithoutValue(name) = self;
|
||
format!(
|
||
"Fixture `{name}` without value is injected as parameter, use \
|
||
`@pytest.mark.usefixtures` instead"
|
||
)
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FixtureParamWithoutValue("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DeprecatedYieldFixture;
|
||
);
|
||
impl Violation for DeprecatedYieldFixture {
|
||
fn message(&self) -> String {
|
||
"`@pytest.yield_fixture` is deprecated, use `@pytest.fixture`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DeprecatedYieldFixture
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct FixtureFinalizerCallback;
|
||
);
|
||
impl Violation for FixtureFinalizerCallback {
|
||
fn message(&self) -> String {
|
||
"Use `yield` instead of `request.addfinalizer`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
FixtureFinalizerCallback
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UselessYieldFixture(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for UselessYieldFixture {
|
||
fn message(&self) -> String {
|
||
let UselessYieldFixture(name) = self;
|
||
format!("No teardown in fixture `{name}`, use `return` instead of `yield`")
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Replace `yield` with `return`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UselessYieldFixture("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct IncorrectMarkParenthesesStyle(pub String, pub String, pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for IncorrectMarkParenthesesStyle {
|
||
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()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
IncorrectMarkParenthesesStyle("...".to_string(), String::new(), "()".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UnnecessaryAsyncioMarkOnFixture;
|
||
);
|
||
impl AlwaysAutofixableViolation for UnnecessaryAsyncioMarkOnFixture {
|
||
fn message(&self) -> String {
|
||
"`pytest.mark.asyncio` is unnecessary for fixtures".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove `pytest.mark.asyncio`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnnecessaryAsyncioMarkOnFixture
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct ErroneousUseFixturesOnFixture;
|
||
);
|
||
impl AlwaysAutofixableViolation for ErroneousUseFixturesOnFixture {
|
||
fn message(&self) -> String {
|
||
"`pytest.mark.usefixtures` has no effect on fixtures".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove `pytest.mark.usefixtures`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ErroneousUseFixturesOnFixture
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct UseFixturesWithoutParameters;
|
||
);
|
||
impl AlwaysAutofixableViolation for UseFixturesWithoutParameters {
|
||
fn message(&self) -> String {
|
||
"Useless `pytest.mark.usefixtures` without parameters".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove `usefixtures` decorator or pass parameters".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UseFixturesWithoutParameters
|
||
}
|
||
}
|
||
|
||
// flake8-pie
|
||
|
||
define_violation!(
|
||
pub struct NoUnnecessaryPass;
|
||
);
|
||
impl AlwaysAutofixableViolation for NoUnnecessaryPass {
|
||
fn message(&self) -> String {
|
||
"Unnecessary `pass` statement".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove unnecessary `pass`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
NoUnnecessaryPass
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct DupeClassFieldDefinitions(pub String);
|
||
);
|
||
impl AlwaysAutofixableViolation for DupeClassFieldDefinitions {
|
||
fn message(&self) -> String {
|
||
let DupeClassFieldDefinitions(name) = self;
|
||
format!("Class field `{name}` is defined multiple times")
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
let DupeClassFieldDefinitions(name) = self;
|
||
format!("Remove duplicate field definition for `{name}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
DupeClassFieldDefinitions("...".to_string())
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PreferUniqueEnums {
|
||
pub value: String,
|
||
}
|
||
);
|
||
impl Violation for PreferUniqueEnums {
|
||
fn message(&self) -> String {
|
||
let PreferUniqueEnums { value } = self;
|
||
format!("Enum contains duplicate value: `{value}`")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PreferUniqueEnums {
|
||
value: "...".to_string(),
|
||
}
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct PreferListBuiltin;
|
||
);
|
||
impl AlwaysAutofixableViolation for PreferListBuiltin {
|
||
fn message(&self) -> String {
|
||
"Prefer `list()` over useless lambda".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Replace with `list`".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
PreferListBuiltin
|
||
}
|
||
}
|
||
|
||
// flake8-commas
|
||
|
||
define_violation!(
|
||
pub struct TrailingCommaMissing;
|
||
);
|
||
impl AlwaysAutofixableViolation for TrailingCommaMissing {
|
||
fn message(&self) -> String {
|
||
"Trailing comma missing".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Add trailing comma".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
TrailingCommaMissing
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct TrailingCommaOnBareTupleProhibited;
|
||
);
|
||
impl Violation for TrailingCommaOnBareTupleProhibited {
|
||
fn message(&self) -> String {
|
||
"Trailing comma on bare tuple prohibited".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
TrailingCommaOnBareTupleProhibited
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct TrailingCommaProhibited;
|
||
);
|
||
impl AlwaysAutofixableViolation for TrailingCommaProhibited {
|
||
fn message(&self) -> String {
|
||
"Trailing comma prohibited".to_string()
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove trailing comma".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
TrailingCommaProhibited
|
||
}
|
||
}
|
||
|
||
// flake8-no-pep420
|
||
|
||
define_violation!(
|
||
pub struct ImplicitNamespacePackage(pub String);
|
||
);
|
||
impl Violation for ImplicitNamespacePackage {
|
||
fn message(&self) -> String {
|
||
let ImplicitNamespacePackage(filename) = self;
|
||
format!("File `{filename}` is part of an implicit namespace package. Add an `__init__.py`.")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
ImplicitNamespacePackage("...".to_string())
|
||
}
|
||
}
|
||
|
||
// Ruff
|
||
|
||
define_violation!(
|
||
pub struct AmbiguousUnicodeCharacterString {
|
||
pub confusable: char,
|
||
pub representant: char,
|
||
}
|
||
);
|
||
impl AlwaysAutofixableViolation for AmbiguousUnicodeCharacterString {
|
||
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}'")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AmbiguousUnicodeCharacterString {
|
||
confusable: '𝐁',
|
||
representant: 'B',
|
||
}
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AmbiguousUnicodeCharacterDocstring {
|
||
pub confusable: char,
|
||
pub representant: char,
|
||
}
|
||
);
|
||
impl AlwaysAutofixableViolation for AmbiguousUnicodeCharacterDocstring {
|
||
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}'")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AmbiguousUnicodeCharacterDocstring {
|
||
confusable: '𝐁',
|
||
representant: 'B',
|
||
}
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct AmbiguousUnicodeCharacterComment {
|
||
pub confusable: char,
|
||
pub representant: char,
|
||
}
|
||
);
|
||
impl AlwaysAutofixableViolation for AmbiguousUnicodeCharacterComment {
|
||
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}'")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
AmbiguousUnicodeCharacterComment {
|
||
confusable: '𝐁',
|
||
representant: 'B',
|
||
}
|
||
}
|
||
}
|
||
|
||
define_violation!(
|
||
pub struct KeywordArgumentBeforeStarArgument(pub String);
|
||
);
|
||
impl Violation for KeywordArgumentBeforeStarArgument {
|
||
fn message(&self) -> String {
|
||
let KeywordArgumentBeforeStarArgument(name) = self;
|
||
format!("Keyword argument `{name}` must come after starred arguments")
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
KeywordArgumentBeforeStarArgument("...".to_string())
|
||
}
|
||
}
|
||
|
||
#[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 Option<UnusedCodes>);
|
||
);
|
||
impl AlwaysAutofixableViolation for UnusedNOQA {
|
||
fn message(&self) -> String {
|
||
let UnusedNOQA(codes) = self;
|
||
match codes {
|
||
None => "Unused blanket `noqa` directive".to_string(),
|
||
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() {
|
||
"Unused `noqa` directive".to_string()
|
||
} else {
|
||
format!("Unused `noqa` directive ({})", codes_by_reason.join("; "))
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
fn autofix_title(&self) -> String {
|
||
"Remove unused `noqa` directive".to_string()
|
||
}
|
||
|
||
fn placeholder() -> Self {
|
||
UnusedNOQA(None)
|
||
}
|
||
}
|