mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 20:39:13 +00:00
Move violations for pycodestyle rules to rules files (#2138)
This commit is contained in:
parent
4190f1045e
commit
708295f4c9
17 changed files with 329 additions and 317 deletions
|
@ -211,6 +211,7 @@ mod tests {
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
use crate::noqa::{add_noqa_inner, NOQA_LINE_REGEX};
|
use crate::noqa::{add_noqa_inner, NOQA_LINE_REGEX};
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
|
use crate::rules::pycodestyle::rules::AmbiguousVariableName;
|
||||||
use crate::settings::hashable::HashableHashSet;
|
use crate::settings::hashable::HashableHashSet;
|
||||||
use crate::source_code::LineEnding;
|
use crate::source_code::LineEnding;
|
||||||
use crate::violations;
|
use crate::violations;
|
||||||
|
@ -264,7 +265,7 @@ mod tests {
|
||||||
|
|
||||||
let diagnostics = vec![
|
let diagnostics = vec![
|
||||||
Diagnostic::new(
|
Diagnostic::new(
|
||||||
violations::AmbiguousVariableName("x".to_string()),
|
AmbiguousVariableName("x".to_string()),
|
||||||
Range::new(Location::new(1, 0), Location::new(1, 0)),
|
Range::new(Location::new(1, 0), Location::new(1, 0)),
|
||||||
),
|
),
|
||||||
Diagnostic::new(
|
Diagnostic::new(
|
||||||
|
@ -287,7 +288,7 @@ mod tests {
|
||||||
|
|
||||||
let diagnostics = vec![
|
let diagnostics = vec![
|
||||||
Diagnostic::new(
|
Diagnostic::new(
|
||||||
violations::AmbiguousVariableName("x".to_string()),
|
AmbiguousVariableName("x".to_string()),
|
||||||
Range::new(Location::new(1, 0), Location::new(1, 0)),
|
Range::new(Location::new(1, 0), Location::new(1, 0)),
|
||||||
),
|
),
|
||||||
Diagnostic::new(
|
Diagnostic::new(
|
||||||
|
|
|
@ -13,26 +13,26 @@ use crate::{rules, violations};
|
||||||
|
|
||||||
ruff_macros::define_rule_mapping!(
|
ruff_macros::define_rule_mapping!(
|
||||||
// pycodestyle errors
|
// pycodestyle errors
|
||||||
E101 => violations::MixedSpacesAndTabs,
|
E101 => rules::pycodestyle::rules::MixedSpacesAndTabs,
|
||||||
E401 => violations::MultipleImportsOnOneLine,
|
E401 => violations::MultipleImportsOnOneLine,
|
||||||
E402 => violations::ModuleImportNotAtTopOfFile,
|
E402 => violations::ModuleImportNotAtTopOfFile,
|
||||||
E501 => violations::LineTooLong,
|
E501 => rules::pycodestyle::rules::LineTooLong,
|
||||||
E711 => violations::NoneComparison,
|
E711 => rules::pycodestyle::rules::NoneComparison,
|
||||||
E712 => violations::TrueFalseComparison,
|
E712 => rules::pycodestyle::rules::TrueFalseComparison,
|
||||||
E713 => violations::NotInTest,
|
E713 => rules::pycodestyle::rules::NotInTest,
|
||||||
E714 => violations::NotIsTest,
|
E714 => rules::pycodestyle::rules::NotIsTest,
|
||||||
E721 => violations::TypeComparison,
|
E721 => rules::pycodestyle::rules::TypeComparison,
|
||||||
E722 => violations::DoNotUseBareExcept,
|
E722 => rules::pycodestyle::rules::DoNotUseBareExcept,
|
||||||
E731 => violations::DoNotAssignLambda,
|
E731 => rules::pycodestyle::rules::DoNotAssignLambda,
|
||||||
E741 => violations::AmbiguousVariableName,
|
E741 => rules::pycodestyle::rules::AmbiguousVariableName,
|
||||||
E742 => violations::AmbiguousClassName,
|
E742 => rules::pycodestyle::rules::AmbiguousClassName,
|
||||||
E743 => violations::AmbiguousFunctionName,
|
E743 => rules::pycodestyle::rules::AmbiguousFunctionName,
|
||||||
E902 => violations::IOError,
|
E902 => violations::IOError,
|
||||||
E999 => violations::SyntaxError,
|
E999 => violations::SyntaxError,
|
||||||
// pycodestyle warnings
|
// pycodestyle warnings
|
||||||
W292 => violations::NoNewLineAtEndOfFile,
|
W292 => rules::pycodestyle::rules::NoNewLineAtEndOfFile,
|
||||||
W505 => violations::DocLineTooLong,
|
W505 => rules::pycodestyle::rules::DocLineTooLong,
|
||||||
W605 => violations::InvalidEscapeSequence,
|
W605 => rules::pycodestyle::rules::InvalidEscapeSequence,
|
||||||
// pyflakes
|
// pyflakes
|
||||||
F401 => violations::UnusedImport,
|
F401 => violations::UnusedImport,
|
||||||
F402 => violations::ImportShadowedByLoopVar,
|
F402 => violations::ImportShadowedByLoopVar,
|
||||||
|
|
|
@ -1,7 +1,21 @@
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
|
use crate::define_violation;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::rules::pycodestyle::helpers::is_ambiguous_name;
|
use crate::rules::pycodestyle::helpers::is_ambiguous_name;
|
||||||
use crate::violations;
|
use crate::violation::Violation;
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct AmbiguousClassName(pub String);
|
||||||
|
);
|
||||||
|
impl Violation for AmbiguousClassName {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let AmbiguousClassName(name) = self;
|
||||||
|
format!("Ambiguous class name: `{name}`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// E742
|
/// E742
|
||||||
pub fn ambiguous_class_name<F>(name: &str, locate: F) -> Option<Diagnostic>
|
pub fn ambiguous_class_name<F>(name: &str, locate: F) -> Option<Diagnostic>
|
||||||
|
@ -10,7 +24,7 @@ where
|
||||||
{
|
{
|
||||||
if is_ambiguous_name(name) {
|
if is_ambiguous_name(name) {
|
||||||
Some(Diagnostic::new(
|
Some(Diagnostic::new(
|
||||||
violations::AmbiguousClassName(name.to_string()),
|
AmbiguousClassName(name.to_string()),
|
||||||
locate(),
|
locate(),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,7 +1,21 @@
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
|
use crate::define_violation;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::rules::pycodestyle::helpers::is_ambiguous_name;
|
use crate::rules::pycodestyle::helpers::is_ambiguous_name;
|
||||||
use crate::violations;
|
use crate::violation::Violation;
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct AmbiguousFunctionName(pub String);
|
||||||
|
);
|
||||||
|
impl Violation for AmbiguousFunctionName {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let AmbiguousFunctionName(name) = self;
|
||||||
|
format!("Ambiguous function name: `{name}`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// E743
|
/// E743
|
||||||
pub fn ambiguous_function_name<F>(name: &str, locate: F) -> Option<Diagnostic>
|
pub fn ambiguous_function_name<F>(name: &str, locate: F) -> Option<Diagnostic>
|
||||||
|
@ -10,7 +24,7 @@ where
|
||||||
{
|
{
|
||||||
if is_ambiguous_name(name) {
|
if is_ambiguous_name(name) {
|
||||||
Some(Diagnostic::new(
|
Some(Diagnostic::new(
|
||||||
violations::AmbiguousFunctionName(name.to_string()),
|
AmbiguousFunctionName(name.to_string()),
|
||||||
locate(),
|
locate(),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,13 +1,27 @@
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
|
use crate::define_violation;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::rules::pycodestyle::helpers::is_ambiguous_name;
|
use crate::rules::pycodestyle::helpers::is_ambiguous_name;
|
||||||
use crate::violations;
|
use crate::violation::Violation;
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct AmbiguousVariableName(pub String);
|
||||||
|
);
|
||||||
|
impl Violation for AmbiguousVariableName {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let AmbiguousVariableName(name) = self;
|
||||||
|
format!("Ambiguous variable name: `{name}`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// E741
|
/// E741
|
||||||
pub fn ambiguous_variable_name(name: &str, range: Range) -> Option<Diagnostic> {
|
pub fn ambiguous_variable_name(name: &str, range: Range) -> Option<Diagnostic> {
|
||||||
if is_ambiguous_name(name) {
|
if is_ambiguous_name(name) {
|
||||||
Some(Diagnostic::new(
|
Some(Diagnostic::new(
|
||||||
violations::AmbiguousVariableName(name.to_string()),
|
AmbiguousVariableName(name.to_string()),
|
||||||
range,
|
range,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Arguments, Location, Stmt, StmtKind};
|
use rustpython_ast::{Arguments, Location, Stmt, StmtKind};
|
||||||
use rustpython_parser::ast::{Expr, ExprKind};
|
use rustpython_parser::ast::{Expr, ExprKind};
|
||||||
|
|
||||||
|
@ -5,19 +6,33 @@ use crate::ast::helpers::{match_leading_content, match_trailing_content, unparse
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
use crate::ast::whitespace::leading_space;
|
use crate::ast::whitespace::leading_space;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
use crate::define_violation;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::source_code::Stylist;
|
use crate::source_code::Stylist;
|
||||||
use crate::violations;
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct DoNotAssignLambda(pub String);
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for DoNotAssignLambda {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Do not assign a `lambda` expression, use a `def`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
let DoNotAssignLambda(name) = self;
|
||||||
|
format!("Rewrite `{name}` as a `def`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// E731
|
/// E731
|
||||||
pub fn do_not_assign_lambda(checker: &mut Checker, target: &Expr, value: &Expr, stmt: &Stmt) {
|
pub fn do_not_assign_lambda(checker: &mut Checker, target: &Expr, value: &Expr, stmt: &Stmt) {
|
||||||
if let ExprKind::Name { id, .. } = &target.node {
|
if let ExprKind::Name { id, .. } = &target.node {
|
||||||
if let ExprKind::Lambda { args, body } = &value.node {
|
if let ExprKind::Lambda { args, body } = &value.node {
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic =
|
||||||
violations::DoNotAssignLambda(id.to_string()),
|
Diagnostic::new(DoNotAssignLambda(id.to_string()), Range::from_located(stmt));
|
||||||
Range::from_located(stmt),
|
|
||||||
);
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
if !match_leading_content(stmt, checker.locator)
|
if !match_leading_content(stmt, checker.locator)
|
||||||
&& !match_trailing_content(stmt, checker.locator)
|
&& !match_trailing_content(stmt, checker.locator)
|
||||||
|
|
|
@ -1,10 +1,22 @@
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Excepthandler, Stmt, StmtKind};
|
use rustpython_ast::{Excepthandler, Stmt, StmtKind};
|
||||||
use rustpython_parser::ast::Expr;
|
use rustpython_parser::ast::Expr;
|
||||||
|
|
||||||
use crate::ast::helpers::except_range;
|
use crate::ast::helpers::except_range;
|
||||||
|
use crate::define_violation;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::source_code::Locator;
|
use crate::source_code::Locator;
|
||||||
use crate::violations;
|
use crate::violation::Violation;
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct DoNotUseBareExcept;
|
||||||
|
);
|
||||||
|
impl Violation for DoNotUseBareExcept {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Do not use bare `except`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// E722
|
/// E722
|
||||||
pub fn do_not_use_bare_except(
|
pub fn do_not_use_bare_except(
|
||||||
|
@ -19,7 +31,7 @@ pub fn do_not_use_bare_except(
|
||||||
.any(|stmt| matches!(stmt.node, StmtKind::Raise { exc: None, .. }))
|
.any(|stmt| matches!(stmt.node, StmtKind::Raise { exc: None, .. }))
|
||||||
{
|
{
|
||||||
Some(Diagnostic::new(
|
Some(Diagnostic::new(
|
||||||
violations::DoNotUseBareExcept,
|
DoNotUseBareExcept,
|
||||||
except_range(handler, locator),
|
except_range(handler, locator),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,10 +1,23 @@
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::Location;
|
use rustpython_ast::Location;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
|
use crate::define_violation;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::rules::pycodestyle::helpers::is_overlong;
|
use crate::rules::pycodestyle::helpers::is_overlong;
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
use crate::violations;
|
use crate::violation::Violation;
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct DocLineTooLong(pub usize, pub usize);
|
||||||
|
);
|
||||||
|
impl Violation for DocLineTooLong {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let DocLineTooLong(length, limit) = self;
|
||||||
|
format!("Doc line too long ({length} > {limit} characters)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// W505
|
/// W505
|
||||||
pub fn doc_line_too_long(lineno: usize, line: &str, settings: &Settings) -> Option<Diagnostic> {
|
pub fn doc_line_too_long(lineno: usize, line: &str, settings: &Settings) -> Option<Diagnostic> {
|
||||||
|
@ -21,7 +34,7 @@ pub fn doc_line_too_long(lineno: usize, line: &str, settings: &Settings) -> Opti
|
||||||
&settings.task_tags,
|
&settings.task_tags,
|
||||||
) {
|
) {
|
||||||
Some(Diagnostic::new(
|
Some(Diagnostic::new(
|
||||||
violations::DocLineTooLong(line_length, limit),
|
DocLineTooLong(line_length, limit),
|
||||||
Range::new(
|
Range::new(
|
||||||
Location::new(lineno + 1, limit),
|
Location::new(lineno + 1, limit),
|
||||||
Location::new(lineno + 1, line_length),
|
Location::new(lineno + 1, line_length),
|
||||||
|
|
|
@ -1,10 +1,27 @@
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::Location;
|
use rustpython_ast::Location;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
|
use crate::define_violation;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::source_code::Locator;
|
use crate::source_code::Locator;
|
||||||
use crate::violations;
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct InvalidEscapeSequence(pub char);
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for InvalidEscapeSequence {
|
||||||
|
#[derive_message_formats]
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// See: https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals
|
// See: https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals
|
||||||
const VALID_ESCAPE_SEQUENCES: &[char; 23] = &[
|
const VALID_ESCAPE_SEQUENCES: &[char; 23] = &[
|
||||||
|
@ -75,7 +92,7 @@ pub fn invalid_escape_sequence(
|
||||||
let location = Location::new(start.row() + row_offset, col);
|
let location = Location::new(start.row() + row_offset, col);
|
||||||
let end_location = Location::new(location.row(), location.column() + 2);
|
let end_location = Location::new(location.row(), location.column() + 2);
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::InvalidEscapeSequence(next_char),
|
InvalidEscapeSequence(next_char),
|
||||||
Range::new(location, end_location),
|
Range::new(location, end_location),
|
||||||
);
|
);
|
||||||
if autofix {
|
if autofix {
|
||||||
|
|
|
@ -1,10 +1,23 @@
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::Location;
|
use rustpython_ast::Location;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
|
use crate::define_violation;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::rules::pycodestyle::helpers::is_overlong;
|
use crate::rules::pycodestyle::helpers::is_overlong;
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
use crate::violations;
|
use crate::violation::Violation;
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct LineTooLong(pub usize, pub usize);
|
||||||
|
);
|
||||||
|
impl Violation for LineTooLong {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let LineTooLong(length, limit) = self;
|
||||||
|
format!("Line too long ({length} > {limit} characters)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// E501
|
/// E501
|
||||||
pub fn line_too_long(lineno: usize, line: &str, settings: &Settings) -> Option<Diagnostic> {
|
pub fn line_too_long(lineno: usize, line: &str, settings: &Settings) -> Option<Diagnostic> {
|
||||||
|
@ -18,7 +31,7 @@ pub fn line_too_long(lineno: usize, line: &str, settings: &Settings) -> Option<D
|
||||||
&settings.task_tags,
|
&settings.task_tags,
|
||||||
) {
|
) {
|
||||||
Some(Diagnostic::new(
|
Some(Diagnostic::new(
|
||||||
violations::LineTooLong(line_length, limit),
|
LineTooLong(line_length, limit),
|
||||||
Range::new(
|
Range::new(
|
||||||
Location::new(lineno + 1, limit),
|
Location::new(lineno + 1, limit),
|
||||||
Location::new(lineno + 1, line_length),
|
Location::new(lineno + 1, line_length),
|
||||||
|
|
|
@ -1,15 +1,86 @@
|
||||||
use itertools::izip;
|
use itertools::izip;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use rustpython_ast::Constant;
|
use rustpython_ast::Constant;
|
||||||
use rustpython_parser::ast::{Cmpop, Expr, ExprKind};
|
use rustpython_parser::ast::{Cmpop, Expr, ExprKind};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::ast::helpers;
|
use crate::ast::helpers;
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
use crate::define_violation;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::rules::pycodestyle::helpers::compare;
|
use crate::rules::pycodestyle::helpers::compare;
|
||||||
use crate::violations;
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
|
||||||
|
#[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 {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let NoneComparison(op) = self;
|
||||||
|
match op {
|
||||||
|
EqCmpop::Eq => format!("Comparison to `None` should be `cond is None`"),
|
||||||
|
EqCmpop::NotEq => format!("Comparison to `None` should be `cond is not None`"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct TrueFalseComparison(pub bool, pub EqCmpop);
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for TrueFalseComparison {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let TrueFalseComparison(value, op) = self;
|
||||||
|
match (value, op) {
|
||||||
|
(true, EqCmpop::Eq) => format!("Comparison to `True` should be `cond is True`"),
|
||||||
|
(true, EqCmpop::NotEq) => {
|
||||||
|
format!("Comparison to `True` should be `cond is not True`")
|
||||||
|
}
|
||||||
|
(false, EqCmpop::Eq) => format!("Comparison to `False` should be `cond is False`"),
|
||||||
|
(false, EqCmpop::NotEq) => {
|
||||||
|
format!("Comparison to `False` should be `cond is not False`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// E711, E712
|
/// E711, E712
|
||||||
pub fn literal_comparisons(
|
pub fn literal_comparisons(
|
||||||
|
@ -43,20 +114,16 @@ pub fn literal_comparisons(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if matches!(op, Cmpop::Eq) {
|
if matches!(op, Cmpop::Eq) {
|
||||||
let diagnostic = Diagnostic::new(
|
let diagnostic =
|
||||||
violations::NoneComparison(op.into()),
|
Diagnostic::new(NoneComparison(op.into()), Range::from_located(comparator));
|
||||||
Range::from_located(comparator),
|
|
||||||
);
|
|
||||||
if checker.patch(diagnostic.kind.rule()) && !helpers::is_constant_non_singleton(next) {
|
if checker.patch(diagnostic.kind.rule()) && !helpers::is_constant_non_singleton(next) {
|
||||||
bad_ops.insert(0, Cmpop::Is);
|
bad_ops.insert(0, Cmpop::Is);
|
||||||
}
|
}
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
if matches!(op, Cmpop::NotEq) {
|
if matches!(op, Cmpop::NotEq) {
|
||||||
let diagnostic = Diagnostic::new(
|
let diagnostic =
|
||||||
violations::NoneComparison(op.into()),
|
Diagnostic::new(NoneComparison(op.into()), Range::from_located(comparator));
|
||||||
Range::from_located(comparator),
|
|
||||||
);
|
|
||||||
if checker.patch(diagnostic.kind.rule()) && !helpers::is_constant_non_singleton(next) {
|
if checker.patch(diagnostic.kind.rule()) && !helpers::is_constant_non_singleton(next) {
|
||||||
bad_ops.insert(0, Cmpop::IsNot);
|
bad_ops.insert(0, Cmpop::IsNot);
|
||||||
}
|
}
|
||||||
|
@ -72,7 +139,7 @@ pub fn literal_comparisons(
|
||||||
{
|
{
|
||||||
if matches!(op, Cmpop::Eq) {
|
if matches!(op, Cmpop::Eq) {
|
||||||
let diagnostic = Diagnostic::new(
|
let diagnostic = Diagnostic::new(
|
||||||
violations::TrueFalseComparison(value, op.into()),
|
TrueFalseComparison(value, op.into()),
|
||||||
Range::from_located(comparator),
|
Range::from_located(comparator),
|
||||||
);
|
);
|
||||||
if checker.patch(diagnostic.kind.rule())
|
if checker.patch(diagnostic.kind.rule())
|
||||||
|
@ -84,7 +151,7 @@ pub fn literal_comparisons(
|
||||||
}
|
}
|
||||||
if matches!(op, Cmpop::NotEq) {
|
if matches!(op, Cmpop::NotEq) {
|
||||||
let diagnostic = Diagnostic::new(
|
let diagnostic = Diagnostic::new(
|
||||||
violations::TrueFalseComparison(value, op.into()),
|
TrueFalseComparison(value, op.into()),
|
||||||
Range::from_located(comparator),
|
Range::from_located(comparator),
|
||||||
);
|
);
|
||||||
if checker.patch(diagnostic.kind.rule())
|
if checker.patch(diagnostic.kind.rule())
|
||||||
|
@ -109,10 +176,8 @@ pub fn literal_comparisons(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if matches!(op, Cmpop::Eq) {
|
if matches!(op, Cmpop::Eq) {
|
||||||
let diagnostic = Diagnostic::new(
|
let diagnostic =
|
||||||
violations::NoneComparison(op.into()),
|
Diagnostic::new(NoneComparison(op.into()), Range::from_located(next));
|
||||||
Range::from_located(next),
|
|
||||||
);
|
|
||||||
if checker.patch(diagnostic.kind.rule())
|
if checker.patch(diagnostic.kind.rule())
|
||||||
&& !helpers::is_constant_non_singleton(comparator)
|
&& !helpers::is_constant_non_singleton(comparator)
|
||||||
{
|
{
|
||||||
|
@ -121,10 +186,8 @@ pub fn literal_comparisons(
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
if matches!(op, Cmpop::NotEq) {
|
if matches!(op, Cmpop::NotEq) {
|
||||||
let diagnostic = Diagnostic::new(
|
let diagnostic =
|
||||||
violations::NoneComparison(op.into()),
|
Diagnostic::new(NoneComparison(op.into()), Range::from_located(next));
|
||||||
Range::from_located(next),
|
|
||||||
);
|
|
||||||
if checker.patch(diagnostic.kind.rule())
|
if checker.patch(diagnostic.kind.rule())
|
||||||
&& !helpers::is_constant_non_singleton(comparator)
|
&& !helpers::is_constant_non_singleton(comparator)
|
||||||
{
|
{
|
||||||
|
@ -142,7 +205,7 @@ pub fn literal_comparisons(
|
||||||
{
|
{
|
||||||
if matches!(op, Cmpop::Eq) {
|
if matches!(op, Cmpop::Eq) {
|
||||||
let diagnostic = Diagnostic::new(
|
let diagnostic = Diagnostic::new(
|
||||||
violations::TrueFalseComparison(value, op.into()),
|
TrueFalseComparison(value, op.into()),
|
||||||
Range::from_located(next),
|
Range::from_located(next),
|
||||||
);
|
);
|
||||||
if checker.patch(diagnostic.kind.rule())
|
if checker.patch(diagnostic.kind.rule())
|
||||||
|
@ -154,7 +217,7 @@ pub fn literal_comparisons(
|
||||||
}
|
}
|
||||||
if matches!(op, Cmpop::NotEq) {
|
if matches!(op, Cmpop::NotEq) {
|
||||||
let diagnostic = Diagnostic::new(
|
let diagnostic = Diagnostic::new(
|
||||||
violations::TrueFalseComparison(value, op.into()),
|
TrueFalseComparison(value, op.into()),
|
||||||
Range::from_located(next),
|
Range::from_located(next),
|
||||||
);
|
);
|
||||||
if checker.patch(diagnostic.kind.rule())
|
if checker.patch(diagnostic.kind.rule())
|
||||||
|
|
|
@ -1,9 +1,21 @@
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::Location;
|
use rustpython_ast::Location;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
use crate::ast::whitespace::leading_space;
|
use crate::ast::whitespace::leading_space;
|
||||||
|
use crate::define_violation;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
use crate::violation::Violation;
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct MixedSpacesAndTabs;
|
||||||
|
);
|
||||||
|
impl Violation for MixedSpacesAndTabs {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Indentation contains mixed spaces and tabs")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// E101
|
/// E101
|
||||||
pub fn mixed_spaces_and_tabs(lineno: usize, line: &str) -> Option<Diagnostic> {
|
pub fn mixed_spaces_and_tabs(lineno: usize, line: &str) -> Option<Diagnostic> {
|
||||||
|
@ -11,7 +23,7 @@ pub fn mixed_spaces_and_tabs(lineno: usize, line: &str) -> Option<Diagnostic> {
|
||||||
|
|
||||||
if indent.contains(' ') && indent.contains('\t') {
|
if indent.contains(' ') && indent.contains('\t') {
|
||||||
Some(Diagnostic::new(
|
Some(Diagnostic::new(
|
||||||
violations::MixedSpacesAndTabs,
|
MixedSpacesAndTabs,
|
||||||
Range::new(
|
Range::new(
|
||||||
Location::new(lineno + 1, 0),
|
Location::new(lineno + 1, 0),
|
||||||
Location::new(lineno + 1, indent.chars().count()),
|
Location::new(lineno + 1, indent.chars().count()),
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
pub use ambiguous_class_name::ambiguous_class_name;
|
pub use ambiguous_class_name::{ambiguous_class_name, AmbiguousClassName};
|
||||||
pub use ambiguous_function_name::ambiguous_function_name;
|
pub use ambiguous_function_name::{ambiguous_function_name, AmbiguousFunctionName};
|
||||||
pub use ambiguous_variable_name::ambiguous_variable_name;
|
pub use ambiguous_variable_name::{ambiguous_variable_name, AmbiguousVariableName};
|
||||||
pub use do_not_assign_lambda::do_not_assign_lambda;
|
pub use do_not_assign_lambda::{do_not_assign_lambda, DoNotAssignLambda};
|
||||||
pub use do_not_use_bare_except::do_not_use_bare_except;
|
pub use do_not_use_bare_except::{do_not_use_bare_except, DoNotUseBareExcept};
|
||||||
pub use doc_line_too_long::doc_line_too_long;
|
pub use doc_line_too_long::{doc_line_too_long, DocLineTooLong};
|
||||||
pub use invalid_escape_sequence::invalid_escape_sequence;
|
pub use invalid_escape_sequence::{invalid_escape_sequence, InvalidEscapeSequence};
|
||||||
pub use line_too_long::line_too_long;
|
pub use line_too_long::{line_too_long, LineTooLong};
|
||||||
pub use literal_comparisons::literal_comparisons;
|
pub use literal_comparisons::{literal_comparisons, NoneComparison, TrueFalseComparison};
|
||||||
pub use mixed_spaces_and_tabs::mixed_spaces_and_tabs;
|
pub use mixed_spaces_and_tabs::{mixed_spaces_and_tabs, MixedSpacesAndTabs};
|
||||||
pub use no_newline_at_end_of_file::no_newline_at_end_of_file;
|
pub use no_newline_at_end_of_file::{no_newline_at_end_of_file, NoNewLineAtEndOfFile};
|
||||||
pub use not_tests::not_tests;
|
pub use not_tests::{not_tests, NotInTest, NotIsTest};
|
||||||
pub use type_comparison::type_comparison;
|
pub use type_comparison::{type_comparison, TypeComparison};
|
||||||
|
|
||||||
mod ambiguous_class_name;
|
mod ambiguous_class_name;
|
||||||
mod ambiguous_function_name;
|
mod ambiguous_function_name;
|
||||||
|
|
|
@ -1,10 +1,26 @@
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::Location;
|
use rustpython_ast::Location;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
|
use crate::define_violation;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::source_code::Stylist;
|
use crate::source_code::Stylist;
|
||||||
use crate::violations;
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct NoNewLineAtEndOfFile;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for NoNewLineAtEndOfFile {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("No newline at end of file")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Add trailing newline".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// W292
|
/// W292
|
||||||
pub fn no_newline_at_end_of_file(
|
pub fn no_newline_at_end_of_file(
|
||||||
|
@ -18,10 +34,8 @@ pub fn no_newline_at_end_of_file(
|
||||||
if let Some(line) = contents.lines().last() {
|
if let Some(line) = contents.lines().last() {
|
||||||
// Both locations are at the end of the file (and thus the same).
|
// Both locations are at the end of the file (and thus the same).
|
||||||
let location = Location::new(contents.lines().count(), line.len());
|
let location = Location::new(contents.lines().count(), line.len());
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic =
|
||||||
violations::NoNewLineAtEndOfFile,
|
Diagnostic::new(NoNewLineAtEndOfFile, Range::new(location, location));
|
||||||
Range::new(location, location),
|
|
||||||
);
|
|
||||||
if autofix {
|
if autofix {
|
||||||
diagnostic.amend(Fix::insertion(stylist.line_ending().to_string(), location));
|
diagnostic.amend(Fix::insertion(stylist.line_ending().to_string(), location));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,42 @@
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::Unaryop;
|
use rustpython_ast::Unaryop;
|
||||||
use rustpython_parser::ast::{Cmpop, Expr, ExprKind};
|
use rustpython_parser::ast::{Cmpop, Expr, ExprKind};
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
use crate::define_violation;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::rules::pycodestyle::helpers::compare;
|
use crate::rules::pycodestyle::helpers::compare;
|
||||||
use crate::violations;
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct NotInTest;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for NotInTest {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Test for membership should be `not in`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Convert to `not in`".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct NotIsTest;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for NotIsTest {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Test for object identity should be `is not`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Convert to `is not`".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// E713, E714
|
/// E713, E714
|
||||||
pub fn not_tests(
|
pub fn not_tests(
|
||||||
|
@ -30,10 +60,8 @@ pub fn not_tests(
|
||||||
match op {
|
match op {
|
||||||
Cmpop::In => {
|
Cmpop::In => {
|
||||||
if check_not_in {
|
if check_not_in {
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic =
|
||||||
violations::NotInTest,
|
Diagnostic::new(NotInTest, Range::from_located(operand));
|
||||||
Range::from_located(operand),
|
|
||||||
);
|
|
||||||
if checker.patch(diagnostic.kind.rule()) && should_fix {
|
if checker.patch(diagnostic.kind.rule()) && should_fix {
|
||||||
diagnostic.amend(Fix::replacement(
|
diagnostic.amend(Fix::replacement(
|
||||||
compare(left, &[Cmpop::NotIn], comparators, checker.stylist),
|
compare(left, &[Cmpop::NotIn], comparators, checker.stylist),
|
||||||
|
@ -46,10 +74,8 @@ pub fn not_tests(
|
||||||
}
|
}
|
||||||
Cmpop::Is => {
|
Cmpop::Is => {
|
||||||
if check_not_is {
|
if check_not_is {
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic =
|
||||||
violations::NotIsTest,
|
Diagnostic::new(NotIsTest, Range::from_located(operand));
|
||||||
Range::from_located(operand),
|
|
||||||
);
|
|
||||||
if checker.patch(diagnostic.kind.rule()) && should_fix {
|
if checker.patch(diagnostic.kind.rule()) && should_fix {
|
||||||
diagnostic.amend(Fix::replacement(
|
diagnostic.amend(Fix::replacement(
|
||||||
compare(left, &[Cmpop::IsNot], comparators, checker.stylist),
|
compare(left, &[Cmpop::IsNot], comparators, checker.stylist),
|
||||||
|
|
|
@ -1,10 +1,22 @@
|
||||||
use itertools::izip;
|
use itertools::izip;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::Constant;
|
use rustpython_ast::Constant;
|
||||||
use rustpython_parser::ast::{Cmpop, Expr, ExprKind};
|
use rustpython_parser::ast::{Cmpop, Expr, ExprKind};
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
|
use crate::define_violation;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
use crate::violation::Violation;
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct TypeComparison;
|
||||||
|
);
|
||||||
|
impl Violation for TypeComparison {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Do not compare types, use `isinstance()`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// E721
|
/// E721
|
||||||
pub fn type_comparison(ops: &[Cmpop], comparators: &[Expr], location: Range) -> Vec<Diagnostic> {
|
pub fn type_comparison(ops: &[Cmpop], comparators: &[Expr], location: Range) -> Vec<Diagnostic> {
|
||||||
|
@ -29,8 +41,7 @@ pub fn type_comparison(ops: &[Cmpop], comparators: &[Expr], location: Range) ->
|
||||||
kind: None
|
kind: None
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
diagnostics
|
diagnostics.push(Diagnostic::new(TypeComparison, location));
|
||||||
.push(Diagnostic::new(violations::TypeComparison, location));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +51,7 @@ pub fn type_comparison(ops: &[Cmpop], comparators: &[Expr], location: Range) ->
|
||||||
if let ExprKind::Name { id, .. } = &value.node {
|
if let ExprKind::Name { id, .. } = &value.node {
|
||||||
// Ex) types.IntType
|
// Ex) types.IntType
|
||||||
if id == "types" {
|
if id == "types" {
|
||||||
diagnostics.push(Diagnostic::new(violations::TypeComparison, location));
|
diagnostics.push(Diagnostic::new(TypeComparison, location));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,191 +37,6 @@ impl Violation for ModuleImportNotAtTopOfFile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct LineTooLong(pub usize, pub usize);
|
|
||||||
);
|
|
||||||
impl Violation for LineTooLong {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let LineTooLong(length, limit) = self;
|
|
||||||
format!("Line too long ({length} > {limit} characters)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct MixedSpacesAndTabs;
|
|
||||||
);
|
|
||||||
impl Violation for MixedSpacesAndTabs {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Indentation contains mixed spaces and tabs")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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 {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let NoneComparison(op) = self;
|
|
||||||
match op {
|
|
||||||
EqCmpop::Eq => format!("Comparison to `None` should be `cond is None`"),
|
|
||||||
EqCmpop::NotEq => format!("Comparison to `None` should be `cond is not None`"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct TrueFalseComparison(pub bool, pub EqCmpop);
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for TrueFalseComparison {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let TrueFalseComparison(value, op) = self;
|
|
||||||
match (value, op) {
|
|
||||||
(true, EqCmpop::Eq) => format!("Comparison to `True` should be `cond is True`"),
|
|
||||||
(true, EqCmpop::NotEq) => {
|
|
||||||
format!("Comparison to `True` should be `cond is not True`")
|
|
||||||
}
|
|
||||||
(false, EqCmpop::Eq) => format!("Comparison to `False` should be `cond is False`"),
|
|
||||||
(false, EqCmpop::NotEq) => {
|
|
||||||
format!("Comparison to `False` should be `cond is not False`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct NotInTest;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for NotInTest {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Test for membership should be `not in`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Convert to `not in`".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct NotIsTest;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for NotIsTest {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Test for object identity should be `is not`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Convert to `is not`".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct TypeComparison;
|
|
||||||
);
|
|
||||||
impl Violation for TypeComparison {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Do not compare types, use `isinstance()`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct DoNotUseBareExcept;
|
|
||||||
);
|
|
||||||
impl Violation for DoNotUseBareExcept {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Do not use bare `except`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct DoNotAssignLambda(pub String);
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for DoNotAssignLambda {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Do not assign a `lambda` expression, use a `def`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
let DoNotAssignLambda(name) = self;
|
|
||||||
format!("Rewrite `{name}` as a `def`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct AmbiguousVariableName(pub String);
|
|
||||||
);
|
|
||||||
impl Violation for AmbiguousVariableName {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let AmbiguousVariableName(name) = self;
|
|
||||||
format!("Ambiguous variable name: `{name}`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct AmbiguousClassName(pub String);
|
|
||||||
);
|
|
||||||
impl Violation for AmbiguousClassName {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let AmbiguousClassName(name) = self;
|
|
||||||
format!("Ambiguous class name: `{name}`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct AmbiguousFunctionName(pub String);
|
|
||||||
);
|
|
||||||
impl Violation for AmbiguousFunctionName {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let AmbiguousFunctionName(name) = self;
|
|
||||||
format!("Ambiguous function name: `{name}`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
define_violation!(
|
||||||
pub struct IOError(pub String);
|
pub struct IOError(pub String);
|
||||||
);
|
);
|
||||||
|
@ -244,48 +59,6 @@ impl Violation for SyntaxError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pycodestyle warnings
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct NoNewLineAtEndOfFile;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for NoNewLineAtEndOfFile {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("No newline at end of file")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Add trailing newline".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct InvalidEscapeSequence(pub char);
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for InvalidEscapeSequence {
|
|
||||||
#[derive_message_formats]
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct DocLineTooLong(pub usize, pub usize);
|
|
||||||
);
|
|
||||||
impl Violation for DocLineTooLong {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let DocLineTooLong(length, limit) = self;
|
|
||||||
format!("Doc line too long ({length} > {limit} characters)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// pyflakes
|
// pyflakes
|
||||||
|
|
||||||
define_violation!(
|
define_violation!(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue