mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-01 17:32:25 +00:00
refactor: move violations to linters (#2234)
This commit is contained in:
parent
8766e6a666
commit
9d3a5530af
11 changed files with 275 additions and 289 deletions
|
@ -318,10 +318,10 @@ ruff_macros::define_rule_mapping!(
|
|||
N817 => violations::CamelcaseImportedAsAcronym,
|
||||
N818 => violations::ErrorSuffixOnExceptionName,
|
||||
// isort
|
||||
I001 => violations::UnsortedImports,
|
||||
I002 => violations::MissingRequiredImport,
|
||||
I001 => rules::isort::rules::UnsortedImports,
|
||||
I002 => rules::isort::rules::MissingRequiredImport,
|
||||
// eradicate
|
||||
ERA001 => violations::CommentedOutCode,
|
||||
ERA001 => rules::eradicate::rules::CommentedOutCode,
|
||||
// flake8-bandit
|
||||
S101 => violations::AssertUsed,
|
||||
S102 => violations::ExecUsed,
|
||||
|
@ -340,9 +340,9 @@ ruff_macros::define_rule_mapping!(
|
|||
S612 => rules::flake8_bandit::rules::LoggingConfigInsecureListen,
|
||||
S701 => violations::Jinja2AutoescapeFalse,
|
||||
// flake8-boolean-trap
|
||||
FBT001 => violations::BooleanPositionalArgInFunctionDefinition,
|
||||
FBT002 => violations::BooleanDefaultValueInFunctionDefinition,
|
||||
FBT003 => violations::BooleanPositionalValueInFunctionCall,
|
||||
FBT001 => rules::flake8_boolean_trap::rules::BooleanPositionalArgInFunctionDefinition,
|
||||
FBT002 => rules::flake8_boolean_trap::rules::BooleanDefaultValueInFunctionDefinition,
|
||||
FBT003 => rules::flake8_boolean_trap::rules::BooleanPositionalValueInFunctionCall,
|
||||
// flake8-unused-arguments
|
||||
ARG001 => violations::UnusedFunctionArgument,
|
||||
ARG002 => violations::UnusedMethodArgument,
|
||||
|
@ -350,7 +350,7 @@ ruff_macros::define_rule_mapping!(
|
|||
ARG004 => violations::UnusedStaticMethodArgument,
|
||||
ARG005 => violations::UnusedLambdaArgument,
|
||||
// flake8-import-conventions
|
||||
ICN001 => violations::ImportAliasIsNotConventional,
|
||||
ICN001 => rules::flake8_import_conventions::rules::ImportAliasIsNotConventional,
|
||||
// flake8-datetimez
|
||||
DTZ001 => violations::CallDatetimeWithoutTzinfo,
|
||||
DTZ002 => violations::CallDatetimeToday,
|
||||
|
@ -410,18 +410,18 @@ ruff_macros::define_rule_mapping!(
|
|||
PT025 => violations::ErroneousUseFixturesOnFixture,
|
||||
PT026 => violations::UseFixturesWithoutParameters,
|
||||
// flake8-pie
|
||||
PIE790 => violations::NoUnnecessaryPass,
|
||||
PIE794 => violations::DupeClassFieldDefinitions,
|
||||
PIE796 => violations::PreferUniqueEnums,
|
||||
PIE800 => violations::NoUnnecessarySpread,
|
||||
PIE804 => violations::NoUnnecessaryDictKwargs,
|
||||
PIE807 => violations::PreferListBuiltin,
|
||||
PIE790 => rules::flake8_pie::rules::NoUnnecessaryPass,
|
||||
PIE794 => rules::flake8_pie::rules::DupeClassFieldDefinitions,
|
||||
PIE796 => rules::flake8_pie::rules::PreferUniqueEnums,
|
||||
PIE800 => rules::flake8_pie::rules::NoUnnecessarySpread,
|
||||
PIE804 => rules::flake8_pie::rules::NoUnnecessaryDictKwargs,
|
||||
PIE807 => rules::flake8_pie::rules::PreferListBuiltin,
|
||||
// flake8-commas
|
||||
COM812 => violations::TrailingCommaMissing,
|
||||
COM818 => violations::TrailingCommaOnBareTupleProhibited,
|
||||
COM819 => violations::TrailingCommaProhibited,
|
||||
COM812 => rules::flake8_commas::rules::TrailingCommaMissing,
|
||||
COM818 => rules::flake8_commas::rules::TrailingCommaOnBareTupleProhibited,
|
||||
COM819 => rules::flake8_commas::rules::TrailingCommaProhibited,
|
||||
// flake8-no-pep420
|
||||
INP001 => violations::ImplicitNamespacePackage,
|
||||
INP001 => rules::flake8_no_pep420::rules::ImplicitNamespacePackage,
|
||||
// flake8-executable
|
||||
EXE001 => rules::flake8_executable::rules::ShebangNotExecutable,
|
||||
EXE002 => rules::flake8_executable::rules::ShebangMissingExecutableFile,
|
||||
|
|
|
@ -1,12 +1,28 @@
|
|||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::Location;
|
||||
|
||||
use super::detection::comment_contains_code;
|
||||
use crate::ast::types::Range;
|
||||
use crate::define_violation;
|
||||
use crate::fix::Fix;
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use crate::settings::{flags, Settings};
|
||||
use crate::source_code::Locator;
|
||||
use crate::violations;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
|
||||
define_violation!(
|
||||
pub struct CommentedOutCode;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for CommentedOutCode {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Found commented-out code")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Remove commented-out code".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
fn is_standalone_comment(line: &str) -> bool {
|
||||
for char in line.chars() {
|
||||
|
@ -33,7 +49,7 @@ pub fn commented_out_code(
|
|||
|
||||
// Verify that the comment is on its own line, and that it contains code.
|
||||
if is_standalone_comment(line) && comment_contains_code(line, &settings.task_tags[..]) {
|
||||
let mut diagnostic = Diagnostic::new(violations::CommentedOutCode, Range::new(start, end));
|
||||
let mut diagnostic = Diagnostic::new(CommentedOutCode, Range::new(start, end));
|
||||
if matches!(autofix, flags::Autofix::Enabled)
|
||||
&& settings.rules.should_fix(&Rule::CommentedOutCode)
|
||||
{
|
||||
|
|
|
@ -1,10 +1,42 @@
|
|||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Arguments, ExprKind};
|
||||
use rustpython_parser::ast::{Constant, Expr};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::define_violation;
|
||||
use crate::registry::{Diagnostic, DiagnosticKind};
|
||||
use crate::violations;
|
||||
use crate::violation::Violation;
|
||||
|
||||
define_violation!(
|
||||
pub struct BooleanPositionalArgInFunctionDefinition;
|
||||
);
|
||||
impl Violation for BooleanPositionalArgInFunctionDefinition {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Boolean positional arg in function definition")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct BooleanDefaultValueInFunctionDefinition;
|
||||
);
|
||||
impl Violation for BooleanDefaultValueInFunctionDefinition {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Boolean default value in function definition")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct BooleanPositionalValueInFunctionCall;
|
||||
);
|
||||
impl Violation for BooleanPositionalValueInFunctionCall {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Boolean positional value in function call")
|
||||
}
|
||||
}
|
||||
|
||||
const FUNC_NAME_ALLOWLIST: &[&str] = &[
|
||||
"assertEqual",
|
||||
|
@ -77,7 +109,7 @@ pub fn check_positional_boolean_in_def(checker: &mut Checker, arguments: &Argume
|
|||
continue;
|
||||
}
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
violations::BooleanPositionalArgInFunctionDefinition,
|
||||
BooleanPositionalArgInFunctionDefinition,
|
||||
Range::from_located(arg),
|
||||
));
|
||||
}
|
||||
|
@ -88,11 +120,7 @@ pub fn check_boolean_default_value_in_function_definition(
|
|||
arguments: &Arguments,
|
||||
) {
|
||||
for arg in &arguments.defaults {
|
||||
add_if_boolean(
|
||||
checker,
|
||||
arg,
|
||||
violations::BooleanDefaultValueInFunctionDefinition.into(),
|
||||
);
|
||||
add_if_boolean(checker, arg, BooleanDefaultValueInFunctionDefinition.into());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,10 +133,6 @@ pub fn check_boolean_positional_value_in_function_call(
|
|||
if allow_boolean_trap(func) {
|
||||
continue;
|
||||
}
|
||||
add_if_boolean(
|
||||
checker,
|
||||
arg,
|
||||
violations::BooleanPositionalValueInFunctionCall.into(),
|
||||
);
|
||||
add_if_boolean(checker, arg, BooleanPositionalValueInFunctionCall.into());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
use itertools::Itertools;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_parser::lexer::{LexResult, Spanned};
|
||||
use rustpython_parser::token::Tok;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::define_violation;
|
||||
use crate::fix::Fix;
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use crate::settings::{flags, Settings};
|
||||
use crate::violations;
|
||||
use crate::violation::{AlwaysAutofixableViolation, Violation};
|
||||
|
||||
/// Simplified token type.
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
|
@ -107,6 +109,44 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct TrailingCommaMissing;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for TrailingCommaMissing {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Trailing comma missing")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Add trailing comma".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct TrailingCommaOnBareTupleProhibited;
|
||||
);
|
||||
impl Violation for TrailingCommaOnBareTupleProhibited {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Trailing comma on bare tuple prohibited")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct TrailingCommaProhibited;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for TrailingCommaProhibited {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Trailing comma prohibited")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Remove trailing comma".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// COM812, COM818, COM819
|
||||
pub fn trailing_commas(
|
||||
tokens: &[LexResult],
|
||||
|
@ -212,7 +252,7 @@ pub fn trailing_commas(
|
|||
if comma_prohibited {
|
||||
let comma = prev.spanned.unwrap();
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::TrailingCommaProhibited,
|
||||
TrailingCommaProhibited,
|
||||
Range {
|
||||
location: comma.0,
|
||||
end_location: comma.2,
|
||||
|
@ -233,7 +273,7 @@ pub fn trailing_commas(
|
|||
if bare_comma_prohibited {
|
||||
let comma = prev.spanned.unwrap();
|
||||
diagnostics.push(Diagnostic::new(
|
||||
violations::TrailingCommaOnBareTupleProhibited,
|
||||
TrailingCommaOnBareTupleProhibited,
|
||||
Range {
|
||||
location: comma.0,
|
||||
end_location: comma.2,
|
||||
|
@ -258,7 +298,7 @@ pub fn trailing_commas(
|
|||
if comma_required {
|
||||
let missing_comma = prev_prev.spanned.unwrap();
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::TrailingCommaMissing,
|
||||
TrailingCommaMissing,
|
||||
Range {
|
||||
location: missing_comma.2,
|
||||
end_location: missing_comma.2,
|
||||
|
|
|
@ -1,9 +1,22 @@
|
|||
use ruff_macros::derive_message_formats;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustpython_ast::Stmt;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::define_violation;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
use crate::violation::Violation;
|
||||
|
||||
define_violation!(
|
||||
pub struct ImportAliasIsNotConventional(pub String, pub String);
|
||||
);
|
||||
impl Violation for ImportAliasIsNotConventional {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let ImportAliasIsNotConventional(name, asname) = self;
|
||||
format!("`{name}` should be imported as `{asname}`")
|
||||
}
|
||||
}
|
||||
|
||||
/// ICN001
|
||||
pub fn check_conventional_import(
|
||||
|
@ -25,10 +38,7 @@ pub fn check_conventional_import(
|
|||
}
|
||||
if !is_valid_import {
|
||||
return Some(Diagnostic::new(
|
||||
violations::ImportAliasIsNotConventional(
|
||||
name.to_string(),
|
||||
expected_alias.to_string(),
|
||||
),
|
||||
ImportAliasIsNotConventional(name.to_string(), expected_alias.to_string()),
|
||||
Range::from_located(import_from),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -1,14 +1,28 @@
|
|||
use std::path::Path;
|
||||
|
||||
use ruff_macros::derive_message_formats;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::{fs, violations};
|
||||
use crate::violation::Violation;
|
||||
use crate::{define_violation, fs};
|
||||
|
||||
define_violation!(
|
||||
pub struct ImplicitNamespacePackage(pub String);
|
||||
);
|
||||
impl Violation for ImplicitNamespacePackage {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let ImplicitNamespacePackage(filename) = self;
|
||||
format!("File `{filename}` is part of an implicit namespace package. Add an `__init__.py`.")
|
||||
}
|
||||
}
|
||||
|
||||
/// INP001
|
||||
pub fn implicit_namespace_package(path: &Path, package: Option<&Path>) -> Option<Diagnostic> {
|
||||
if package.is_none() {
|
||||
Some(Diagnostic::new(
|
||||
violations::ImplicitNamespacePackage(fs::relativize_path(path)),
|
||||
ImplicitNamespacePackage(fs::relativize_path(path)),
|
||||
Range::default(),
|
||||
))
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use log::error;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustc_hash::FxHashSet;
|
||||
use rustpython_ast::{Constant, Expr, ExprKind, Keyword, Stmt, StmtKind};
|
||||
|
||||
|
@ -7,10 +8,88 @@ use crate::ast::helpers::unparse_expr;
|
|||
use crate::ast::types::{Range, RefEquality};
|
||||
use crate::autofix::helpers::delete_stmt;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::define_violation;
|
||||
use crate::fix::Fix;
|
||||
use crate::python::identifiers::is_identifier;
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use crate::violations;
|
||||
use crate::violation::{AlwaysAutofixableViolation, Violation};
|
||||
|
||||
define_violation!(
|
||||
pub struct NoUnnecessaryPass;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for NoUnnecessaryPass {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Unnecessary `pass` statement")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Remove unnecessary `pass`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct DupeClassFieldDefinitions(pub String);
|
||||
);
|
||||
impl AlwaysAutofixableViolation for DupeClassFieldDefinitions {
|
||||
#[derive_message_formats]
|
||||
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}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct PreferUniqueEnums {
|
||||
pub value: String,
|
||||
}
|
||||
);
|
||||
impl Violation for PreferUniqueEnums {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let PreferUniqueEnums { value } = self;
|
||||
format!("Enum contains duplicate value: `{value}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct NoUnnecessarySpread;
|
||||
);
|
||||
impl Violation for NoUnnecessarySpread {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Unnecessary spread `**`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct NoUnnecessaryDictKwargs;
|
||||
);
|
||||
impl Violation for NoUnnecessaryDictKwargs {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Unnecessary `dict` kwargs")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct PreferListBuiltin;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for PreferListBuiltin {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Prefer `list` over useless lambda")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Replace with `list`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// PIE790
|
||||
pub fn no_unnecessary_pass(checker: &mut Checker, body: &[Stmt]) {
|
||||
|
@ -30,10 +109,8 @@ pub fn no_unnecessary_pass(checker: &mut Checker, body: &[Stmt]) {
|
|||
}
|
||||
) {
|
||||
if matches!(pass_stmt.node, StmtKind::Pass) {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::NoUnnecessaryPass,
|
||||
Range::from_located(pass_stmt),
|
||||
);
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(NoUnnecessaryPass, Range::from_located(pass_stmt));
|
||||
if checker.patch(&Rule::NoUnnecessaryPass) {
|
||||
match delete_stmt(
|
||||
pass_stmt,
|
||||
|
@ -91,7 +168,7 @@ pub fn dupe_class_field_definitions<'a, 'b>(
|
|||
|
||||
if !seen_targets.insert(target) {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::DupeClassFieldDefinitions(target.to_string()),
|
||||
DupeClassFieldDefinitions(target.to_string()),
|
||||
Range::from_located(stmt),
|
||||
);
|
||||
if checker.patch(&Rule::DupeClassFieldDefinitions) {
|
||||
|
@ -157,7 +234,7 @@ where
|
|||
|
||||
if !seen_targets.insert(ComparableExpr::from(value)) {
|
||||
let diagnostic = Diagnostic::new(
|
||||
violations::PreferUniqueEnums {
|
||||
PreferUniqueEnums {
|
||||
value: unparse_expr(value, checker.stylist),
|
||||
},
|
||||
Range::from_located(stmt),
|
||||
|
@ -174,8 +251,7 @@ pub fn no_unnecessary_spread(checker: &mut Checker, keys: &[Option<Expr>], value
|
|||
// We only care about when the key is None which indicates a spread `**`
|
||||
// inside a dict.
|
||||
if let ExprKind::Dict { .. } = value.node {
|
||||
let diagnostic =
|
||||
Diagnostic::new(violations::NoUnnecessarySpread, Range::from_located(value));
|
||||
let diagnostic = Diagnostic::new(NoUnnecessarySpread, Range::from_located(value));
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
|
@ -206,10 +282,8 @@ pub fn no_unnecessary_dict_kwargs(checker: &mut Checker, expr: &Expr, kwargs: &[
|
|||
// handle case of foo(**{**bar})
|
||||
(keys.len() == 1 && keys[0].is_none())
|
||||
{
|
||||
let diagnostic = Diagnostic::new(
|
||||
violations::NoUnnecessaryDictKwargs,
|
||||
Range::from_located(expr),
|
||||
);
|
||||
let diagnostic =
|
||||
Diagnostic::new(NoUnnecessaryDictKwargs, Range::from_located(expr));
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
|
@ -225,8 +299,7 @@ pub fn prefer_list_builtin(checker: &mut Checker, expr: &Expr) {
|
|||
if args.args.is_empty() {
|
||||
if let ExprKind::List { elts, .. } = &body.node {
|
||||
if elts.is_empty() {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(violations::PreferListBuiltin, Range::from_located(expr));
|
||||
let mut diagnostic = Diagnostic::new(PreferListBuiltin, Range::from_located(expr));
|
||||
if checker.patch(&Rule::PreferListBuiltin) {
|
||||
diagnostic.amend(Fix::replacement(
|
||||
"list".to_string(),
|
||||
|
|
|
@ -1,17 +1,35 @@
|
|||
use std::fmt;
|
||||
|
||||
use log::error;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Location, StmtKind, Suite};
|
||||
|
||||
use super::super::helpers;
|
||||
use super::super::track::Block;
|
||||
use crate::ast::helpers::is_docstring_stmt;
|
||||
use crate::ast::types::Range;
|
||||
use crate::define_violation;
|
||||
use crate::fix::Fix;
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use crate::settings::{flags, Settings};
|
||||
use crate::source_code::{Locator, Stylist};
|
||||
use crate::violations;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
|
||||
define_violation!(
|
||||
pub struct MissingRequiredImport(pub String);
|
||||
);
|
||||
impl AlwaysAutofixableViolation for MissingRequiredImport {
|
||||
#[derive_message_formats]
|
||||
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}`")
|
||||
}
|
||||
}
|
||||
|
||||
struct Alias<'a> {
|
||||
name: &'a str,
|
||||
|
@ -123,7 +141,7 @@ fn add_required_import(
|
|||
// Always insert the diagnostic at top-of-file.
|
||||
let required_import = required_import.to_string();
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::MissingRequiredImport(required_import.clone()),
|
||||
MissingRequiredImport(required_import.clone()),
|
||||
Range::new(Location::default(), Location::default()),
|
||||
);
|
||||
if matches!(autofix, flags::Autofix::Enabled)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
pub use add_required_imports::add_required_imports;
|
||||
pub use organize_imports::organize_imports;
|
||||
pub use add_required_imports::{add_required_imports, MissingRequiredImport};
|
||||
pub use organize_imports::{organize_imports, UnsortedImports};
|
||||
|
||||
pub mod add_required_imports;
|
||||
pub mod organize_imports;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::path::Path;
|
||||
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Location, Stmt};
|
||||
use textwrap::{dedent, indent};
|
||||
|
||||
|
@ -10,11 +11,26 @@ use crate::ast::helpers::{
|
|||
};
|
||||
use crate::ast::types::Range;
|
||||
use crate::ast::whitespace::leading_space;
|
||||
use crate::define_violation;
|
||||
use crate::fix::Fix;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::settings::{flags, Settings};
|
||||
use crate::source_code::{Indexer, Locator, Stylist};
|
||||
use crate::violations;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
|
||||
define_violation!(
|
||||
pub struct UnsortedImports;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for UnsortedImports {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Import block is un-sorted or un-formatted")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Organize imports".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_range(body: &[&Stmt]) -> Range {
|
||||
let location = body.first().unwrap().location;
|
||||
|
@ -47,7 +63,7 @@ pub fn organize_imports(
|
|||
if preceded_by_multi_statement_line(block.imports.first().unwrap(), locator, indexer)
|
||||
|| followed_by_multi_statement_line(block.imports.last().unwrap(), locator)
|
||||
{
|
||||
return Some(Diagnostic::new(violations::UnsortedImports, range));
|
||||
return Some(Diagnostic::new(UnsortedImports, range));
|
||||
}
|
||||
|
||||
// Extract comments. Take care to grab any inline comments from the last line.
|
||||
|
@ -100,7 +116,7 @@ pub fn organize_imports(
|
|||
if actual == dedent(&expected) {
|
||||
None
|
||||
} else {
|
||||
let mut diagnostic = Diagnostic::new(violations::UnsortedImports, range);
|
||||
let mut diagnostic = Diagnostic::new(UnsortedImports, range);
|
||||
if matches!(autofix, flags::Autofix::Enabled)
|
||||
&& settings.rules.should_fix(diagnostic.kind.rule())
|
||||
{
|
||||
|
|
|
@ -3781,54 +3781,6 @@ impl Violation for ErrorSuffixOnExceptionName {
|
|||
}
|
||||
}
|
||||
|
||||
// isort
|
||||
|
||||
define_violation!(
|
||||
pub struct UnsortedImports;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for UnsortedImports {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Import block is un-sorted or un-formatted")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Organize imports".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct MissingRequiredImport(pub String);
|
||||
);
|
||||
impl AlwaysAutofixableViolation for MissingRequiredImport {
|
||||
#[derive_message_formats]
|
||||
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}`")
|
||||
}
|
||||
}
|
||||
|
||||
// eradicate
|
||||
|
||||
define_violation!(
|
||||
pub struct CommentedOutCode;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for CommentedOutCode {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Found commented-out code")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Remove commented-out code".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
// flake8-bandit
|
||||
|
||||
define_violation!(
|
||||
|
@ -4028,38 +3980,6 @@ impl Violation for SnmpWeakCryptography {
|
|||
}
|
||||
}
|
||||
|
||||
// flake8-boolean-trap
|
||||
|
||||
define_violation!(
|
||||
pub struct BooleanPositionalArgInFunctionDefinition;
|
||||
);
|
||||
impl Violation for BooleanPositionalArgInFunctionDefinition {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Boolean positional arg in function definition")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct BooleanDefaultValueInFunctionDefinition;
|
||||
);
|
||||
impl Violation for BooleanDefaultValueInFunctionDefinition {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Boolean default value in function definition")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct BooleanPositionalValueInFunctionCall;
|
||||
);
|
||||
impl Violation for BooleanPositionalValueInFunctionCall {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Boolean positional value in function call")
|
||||
}
|
||||
}
|
||||
|
||||
// flake8-unused-arguments
|
||||
|
||||
define_violation!(
|
||||
|
@ -4117,19 +4037,6 @@ impl Violation for UnusedLambdaArgument {
|
|||
}
|
||||
}
|
||||
|
||||
// flake8-import-conventions
|
||||
|
||||
define_violation!(
|
||||
pub struct ImportAliasIsNotConventional(pub String, pub String);
|
||||
);
|
||||
impl Violation for ImportAliasIsNotConventional {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let ImportAliasIsNotConventional(name, asname) = self;
|
||||
format!("`{name}` should be imported as `{asname}`")
|
||||
}
|
||||
}
|
||||
|
||||
// flake8-datetimez
|
||||
|
||||
define_violation!(
|
||||
|
@ -4737,138 +4644,6 @@ impl AlwaysAutofixableViolation for UseFixturesWithoutParameters {
|
|||
}
|
||||
}
|
||||
|
||||
// flake8-pie
|
||||
|
||||
define_violation!(
|
||||
pub struct NoUnnecessaryPass;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for NoUnnecessaryPass {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Unnecessary `pass` statement")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Remove unnecessary `pass`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct DupeClassFieldDefinitions(pub String);
|
||||
);
|
||||
impl AlwaysAutofixableViolation for DupeClassFieldDefinitions {
|
||||
#[derive_message_formats]
|
||||
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}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct PreferUniqueEnums {
|
||||
pub value: String,
|
||||
}
|
||||
);
|
||||
impl Violation for PreferUniqueEnums {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let PreferUniqueEnums { value } = self;
|
||||
format!("Enum contains duplicate value: `{value}`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct NoUnnecessarySpread;
|
||||
);
|
||||
impl Violation for NoUnnecessarySpread {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Unnecessary spread `**`")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct NoUnnecessaryDictKwargs;
|
||||
);
|
||||
impl Violation for NoUnnecessaryDictKwargs {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Unnecessary `dict` kwargs")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct PreferListBuiltin;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for PreferListBuiltin {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Prefer `list` over useless lambda")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Replace with `list`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
// flake8-commas
|
||||
|
||||
define_violation!(
|
||||
pub struct TrailingCommaMissing;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for TrailingCommaMissing {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Trailing comma missing")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Add trailing comma".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct TrailingCommaOnBareTupleProhibited;
|
||||
);
|
||||
impl Violation for TrailingCommaOnBareTupleProhibited {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Trailing comma on bare tuple prohibited")
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct TrailingCommaProhibited;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for TrailingCommaProhibited {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Trailing comma prohibited")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Remove trailing comma".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
// flake8-no-pep420
|
||||
|
||||
define_violation!(
|
||||
pub struct ImplicitNamespacePackage(pub String);
|
||||
);
|
||||
impl Violation for ImplicitNamespacePackage {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let ImplicitNamespacePackage(filename) = self;
|
||||
format!("File `{filename}` is part of an implicit namespace package. Add an `__init__.py`.")
|
||||
}
|
||||
}
|
||||
|
||||
// ruff
|
||||
|
||||
define_violation!(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue