mirror of https://github.com/astral-sh/ruff
Move pyupgrade violations to rule modules (#2490)
This commit is contained in:
parent
5f1bbf0b6b
commit
858af8debb
|
|
@ -224,38 +224,38 @@ ruff_macros::define_rule_mapping!(
|
||||||
SIM300 => violations::YodaConditions,
|
SIM300 => violations::YodaConditions,
|
||||||
SIM401 => violations::DictGetWithDefault,
|
SIM401 => violations::DictGetWithDefault,
|
||||||
// pyupgrade
|
// pyupgrade
|
||||||
UP001 => violations::UselessMetaclassType,
|
UP001 => rules::pyupgrade::rules::UselessMetaclassType,
|
||||||
UP003 => violations::TypeOfPrimitive,
|
UP003 => rules::pyupgrade::rules::TypeOfPrimitive,
|
||||||
UP004 => violations::UselessObjectInheritance,
|
UP004 => rules::pyupgrade::rules::UselessObjectInheritance,
|
||||||
UP005 => violations::DeprecatedUnittestAlias,
|
UP005 => rules::pyupgrade::rules::DeprecatedUnittestAlias,
|
||||||
UP006 => violations::UsePEP585Annotation,
|
UP006 => rules::pyupgrade::rules::UsePEP585Annotation,
|
||||||
UP007 => violations::UsePEP604Annotation,
|
UP007 => rules::pyupgrade::rules::UsePEP604Annotation,
|
||||||
UP008 => violations::SuperCallWithParameters,
|
UP008 => rules::pyupgrade::rules::SuperCallWithParameters,
|
||||||
UP009 => violations::PEP3120UnnecessaryCodingComment,
|
UP009 => rules::pyupgrade::rules::PEP3120UnnecessaryCodingComment,
|
||||||
UP010 => violations::UnnecessaryFutureImport,
|
UP010 => rules::pyupgrade::rules::UnnecessaryFutureImport,
|
||||||
UP011 => violations::LRUCacheWithoutParameters,
|
UP011 => rules::pyupgrade::rules::LRUCacheWithoutParameters,
|
||||||
UP012 => violations::UnnecessaryEncodeUTF8,
|
UP012 => rules::pyupgrade::rules::UnnecessaryEncodeUTF8,
|
||||||
UP013 => violations::ConvertTypedDictFunctionalToClass,
|
UP013 => rules::pyupgrade::rules::ConvertTypedDictFunctionalToClass,
|
||||||
UP014 => violations::ConvertNamedTupleFunctionalToClass,
|
UP014 => rules::pyupgrade::rules::ConvertNamedTupleFunctionalToClass,
|
||||||
UP015 => violations::RedundantOpenModes,
|
UP015 => rules::pyupgrade::rules::RedundantOpenModes,
|
||||||
UP017 => violations::DatetimeTimezoneUTC,
|
UP017 => rules::pyupgrade::rules::DatetimeTimezoneUTC,
|
||||||
UP018 => violations::NativeLiterals,
|
UP018 => rules::pyupgrade::rules::NativeLiterals,
|
||||||
UP019 => violations::TypingTextStrAlias,
|
UP019 => rules::pyupgrade::rules::TypingTextStrAlias,
|
||||||
UP020 => violations::OpenAlias,
|
UP020 => rules::pyupgrade::rules::OpenAlias,
|
||||||
UP021 => violations::ReplaceUniversalNewlines,
|
UP021 => rules::pyupgrade::rules::ReplaceUniversalNewlines,
|
||||||
UP022 => violations::ReplaceStdoutStderr,
|
UP022 => rules::pyupgrade::rules::ReplaceStdoutStderr,
|
||||||
UP023 => violations::RewriteCElementTree,
|
UP023 => rules::pyupgrade::rules::RewriteCElementTree,
|
||||||
UP024 => violations::OSErrorAlias,
|
UP024 => rules::pyupgrade::rules::OSErrorAlias,
|
||||||
UP025 => violations::RewriteUnicodeLiteral,
|
UP025 => rules::pyupgrade::rules::RewriteUnicodeLiteral,
|
||||||
UP026 => violations::RewriteMockImport,
|
UP026 => rules::pyupgrade::rules::RewriteMockImport,
|
||||||
UP027 => violations::RewriteListComprehension,
|
UP027 => rules::pyupgrade::rules::RewriteListComprehension,
|
||||||
UP028 => violations::RewriteYieldFrom,
|
UP028 => rules::pyupgrade::rules::RewriteYieldFrom,
|
||||||
UP029 => violations::UnnecessaryBuiltinImport,
|
UP029 => rules::pyupgrade::rules::UnnecessaryBuiltinImport,
|
||||||
UP030 => violations::FormatLiterals,
|
UP030 => rules::pyupgrade::rules::FormatLiterals,
|
||||||
UP031 => violations::PrintfStringFormatting,
|
UP031 => rules::pyupgrade::rules::PrintfStringFormatting,
|
||||||
UP032 => violations::FString,
|
UP032 => rules::pyupgrade::rules::FString,
|
||||||
UP033 => violations::FunctoolsCache,
|
UP033 => rules::pyupgrade::rules::FunctoolsCache,
|
||||||
UP034 => violations::ExtraneousParentheses,
|
UP034 => rules::pyupgrade::rules::ExtraneousParentheses,
|
||||||
UP035 => rules::pyupgrade::rules::ImportReplacements,
|
UP035 => rules::pyupgrade::rules::ImportReplacements,
|
||||||
UP036 => rules::pyupgrade::rules::OutdatedVersionBlock,
|
UP036 => rules::pyupgrade::rules::OutdatedVersionBlock,
|
||||||
// pydocstyle
|
// pydocstyle
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind};
|
use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind};
|
||||||
|
|
||||||
use crate::ast::helpers::{create_expr, create_stmt, unparse_stmt};
|
use crate::ast::helpers::{create_expr, create_stmt, unparse_stmt};
|
||||||
|
|
@ -10,7 +13,24 @@ use crate::python::identifiers::is_identifier;
|
||||||
use crate::python::keyword::KWLIST;
|
use crate::python::keyword::KWLIST;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::source_code::Stylist;
|
use crate::source_code::Stylist;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct ConvertNamedTupleFunctionalToClass {
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for ConvertNamedTupleFunctionalToClass {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let ConvertNamedTupleFunctionalToClass { name } = self;
|
||||||
|
format!("Convert `{name}` from `NamedTuple` functional to class syntax")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
let ConvertNamedTupleFunctionalToClass { name } = self;
|
||||||
|
format!("Convert `{name}` to class syntax")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the typename, args, keywords, and base class.
|
/// Return the typename, args, keywords, and base class.
|
||||||
fn match_named_tuple_assign<'a>(
|
fn match_named_tuple_assign<'a>(
|
||||||
|
|
@ -154,7 +174,7 @@ pub fn convert_named_tuple_functional_to_class(
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::ConvertNamedTupleFunctionalToClass {
|
ConvertNamedTupleFunctionalToClass {
|
||||||
name: typename.to_string(),
|
name: typename.to_string(),
|
||||||
},
|
},
|
||||||
Range::from_located(stmt),
|
Range::from_located(stmt),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind};
|
use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind};
|
||||||
|
|
||||||
use crate::ast::helpers::{create_expr, create_stmt, unparse_stmt};
|
use crate::ast::helpers::{create_expr, create_stmt, unparse_stmt};
|
||||||
|
|
@ -10,7 +13,24 @@ use crate::python::identifiers::is_identifier;
|
||||||
use crate::python::keyword::KWLIST;
|
use crate::python::keyword::KWLIST;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::source_code::Stylist;
|
use crate::source_code::Stylist;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct ConvertTypedDictFunctionalToClass {
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for ConvertTypedDictFunctionalToClass {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let ConvertTypedDictFunctionalToClass { name } = self;
|
||||||
|
format!("Convert `{name}` from `TypedDict` functional to class syntax")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
let ConvertTypedDictFunctionalToClass { name } = self;
|
||||||
|
format!("Convert `{name}` to class syntax")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the class name, arguments, keywords and base class for a `TypedDict`
|
/// Return the class name, arguments, keywords and base class for a `TypedDict`
|
||||||
/// assignment.
|
/// assignment.
|
||||||
|
|
@ -201,7 +221,7 @@ pub fn convert_typed_dict_functional_to_class(
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::ConvertTypedDictFunctionalToClass {
|
ConvertTypedDictFunctionalToClass {
|
||||||
name: class_name.to_string(),
|
name: class_name.to_string(),
|
||||||
},
|
},
|
||||||
Range::from_located(stmt),
|
Range::from_located(stmt),
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
use crate::violation::{Availability, Violation};
|
||||||
|
use crate::{define_violation, AutofixKind};
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::Expr;
|
use rustpython_ast::Expr;
|
||||||
|
|
||||||
use crate::ast::helpers::collect_call_path;
|
use crate::ast::helpers::collect_call_path;
|
||||||
|
|
@ -5,7 +8,28 @@ use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct DatetimeTimezoneUTC {
|
||||||
|
pub straight_import: bool,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
impl Violation for DatetimeTimezoneUTC {
|
||||||
|
const AUTOFIX: Option<AutofixKind> = Some(AutofixKind::new(Availability::Always));
|
||||||
|
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Use `datetime.UTC` alias")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
|
||||||
|
if self.straight_import {
|
||||||
|
Some(|_| "Convert to `datetime.UTC` alias".to_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// UP017
|
/// UP017
|
||||||
pub fn datetime_utc_alias(checker: &mut Checker, expr: &Expr) {
|
pub fn datetime_utc_alias(checker: &mut Checker, expr: &Expr) {
|
||||||
|
|
@ -14,7 +38,7 @@ pub fn datetime_utc_alias(checker: &mut Checker, expr: &Expr) {
|
||||||
}) {
|
}) {
|
||||||
let straight_import = collect_call_path(expr).as_slice() == ["datetime", "timezone", "utc"];
|
let straight_import = collect_call_path(expr).as_slice() == ["datetime", "timezone", "utc"];
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::DatetimeTimezoneUTC { straight_import },
|
DatetimeTimezoneUTC { straight_import },
|
||||||
Range::from_located(expr),
|
Range::from_located(expr),
|
||||||
);
|
);
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use rustpython_ast::{Expr, ExprKind};
|
use rustpython_ast::{Expr, ExprKind};
|
||||||
|
|
||||||
|
|
@ -6,7 +9,25 @@ use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct DeprecatedUnittestAlias {
|
||||||
|
pub alias: String,
|
||||||
|
pub target: String,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for DeprecatedUnittestAlias {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let DeprecatedUnittestAlias { alias, target } = self;
|
||||||
|
format!("`{alias}` is deprecated, use `{target}`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
let DeprecatedUnittestAlias { alias, target } = self;
|
||||||
|
format!("Replace `{target}` with `{alias}`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static DEPRECATED_ALIASES: Lazy<FxHashMap<&'static str, &'static str>> = Lazy::new(|| {
|
static DEPRECATED_ALIASES: Lazy<FxHashMap<&'static str, &'static str>> = Lazy::new(|| {
|
||||||
FxHashMap::from_iter([
|
FxHashMap::from_iter([
|
||||||
|
|
@ -43,7 +64,7 @@ pub fn deprecated_unittest_alias(checker: &mut Checker, expr: &Expr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::DeprecatedUnittestAlias {
|
DeprecatedUnittestAlias {
|
||||||
alias: attr.to_string(),
|
alias: attr.to_string(),
|
||||||
target: target.to_string(),
|
target: target.to_string(),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_parser::lexer::{LexResult, Tok};
|
use rustpython_parser::lexer::{LexResult, Tok};
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
|
|
@ -5,7 +8,20 @@ use crate::fix::Fix;
|
||||||
use crate::registry::{Diagnostic, Rule};
|
use crate::registry::{Diagnostic, Rule};
|
||||||
use crate::settings::{flags, Settings};
|
use crate::settings::{flags, Settings};
|
||||||
use crate::source_code::Locator;
|
use crate::source_code::Locator;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct ExtraneousParentheses;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for ExtraneousParentheses {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Avoid extraneous parentheses")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Remove extraneous parentheses".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// See: https://github.com/asottile/pyupgrade/blob/97ed6fb3cf2e650d4f762ba231c3f04c41797710/pyupgrade/_main.py#L148
|
// See: https://github.com/asottile/pyupgrade/blob/97ed6fb3cf2e650d4f762ba231c3f04c41797710/pyupgrade/_main.py#L148
|
||||||
fn match_extraneous_parentheses(tokens: &[LexResult], mut i: usize) -> Option<(usize, usize)> {
|
fn match_extraneous_parentheses(tokens: &[LexResult], mut i: usize) -> Option<(usize, usize)> {
|
||||||
|
|
@ -120,7 +136,7 @@ pub fn extraneous_parentheses(
|
||||||
return diagnostics;
|
return diagnostics;
|
||||||
};
|
};
|
||||||
let mut diagnostic =
|
let mut diagnostic =
|
||||||
Diagnostic::new(violations::ExtraneousParentheses, Range::new(*start, *end));
|
Diagnostic::new(ExtraneousParentheses, Range::new(*start, *end));
|
||||||
if matches!(autofix, flags::Autofix::Enabled)
|
if matches!(autofix, flags::Autofix::Enabled)
|
||||||
&& settings.rules.should_fix(&Rule::ExtraneousParentheses)
|
&& settings.rules.should_fix(&Rule::ExtraneousParentheses)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use rustpython_ast::{Constant, Expr, ExprKind, KeywordData};
|
use rustpython_ast::{Constant, Expr, ExprKind, KeywordData};
|
||||||
use rustpython_common::format::{
|
use rustpython_common::format::{
|
||||||
|
|
@ -13,7 +16,20 @@ use crate::registry::Diagnostic;
|
||||||
use crate::rules::pydocstyle::helpers::{leading_quote, trailing_quote};
|
use crate::rules::pydocstyle::helpers::{leading_quote, trailing_quote};
|
||||||
use crate::rules::pyflakes::format::FormatSummary;
|
use crate::rules::pyflakes::format::FormatSummary;
|
||||||
use crate::rules::pyupgrade::helpers::curly_escape;
|
use crate::rules::pyupgrade::helpers::curly_escape;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct FString;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for FString {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Use f-string instead of `format` call")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Convert to f-string".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Like [`FormatSummary`], but maps positional and keyword arguments to their
|
/// Like [`FormatSummary`], but maps positional and keyword arguments to their
|
||||||
/// values. For example, given `{a} {b}".format(a=1, b=2)`, `FormatFunction`
|
/// values. For example, given `{a} {b}".format(a=1, b=2)`, `FormatFunction`
|
||||||
|
|
@ -257,7 +273,7 @@ pub(crate) fn f_strings(checker: &mut Checker, summary: &FormatSummary, expr: &E
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut diagnostic = Diagnostic::new(violations::FString, Range::from_located(expr));
|
let mut diagnostic = Diagnostic::new(FString, Range::from_located(expr));
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
diagnostic.amend(Fix::replacement(
|
diagnostic.amend(Fix::replacement(
|
||||||
contents,
|
contents,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use libcst_native::{Arg, Codegen, CodegenState, Expression};
|
use libcst_native::{Arg, Codegen, CodegenState, Expression};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::Expr;
|
use rustpython_ast::Expr;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
|
|
@ -11,7 +14,20 @@ use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::rules::pyflakes::format::FormatSummary;
|
use crate::rules::pyflakes::format::FormatSummary;
|
||||||
use crate::source_code::{Locator, Stylist};
|
use crate::source_code::{Locator, Stylist};
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct FormatLiterals;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for FormatLiterals {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Use implicit references for positional format fields")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Remove explicit positional indexes".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// An opening curly brace, followed by any integer, followed by any text,
|
// An opening curly brace, followed by any integer, followed by any text,
|
||||||
// followed by a closing brace.
|
// followed by a closing brace.
|
||||||
|
|
@ -112,7 +128,7 @@ pub(crate) fn format_literals(checker: &mut Checker, summary: &FormatSummary, ex
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut diagnostic = Diagnostic::new(violations::FormatLiterals, Range::from_located(expr));
|
let mut diagnostic = Diagnostic::new(FormatLiterals, Range::from_located(expr));
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
// Currently, the only issue we know of is in LibCST:
|
// Currently, the only issue we know of is in LibCST:
|
||||||
// https://github.com/Instagram/LibCST/issues/846
|
// https://github.com/Instagram/LibCST/issues/846
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Constant, ExprKind, KeywordData};
|
use rustpython_ast::{Constant, ExprKind, KeywordData};
|
||||||
use rustpython_parser::ast::Expr;
|
use rustpython_parser::ast::Expr;
|
||||||
|
|
||||||
|
|
@ -6,7 +9,20 @@ use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct FunctoolsCache;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for FunctoolsCache {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Use `@functools.cache` instead of `@functools.lru_cache(maxsize=None)`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Rewrite with `@functools.cache".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// UP033
|
/// UP033
|
||||||
pub fn functools_cache(checker: &mut Checker, decorator_list: &[Expr]) {
|
pub fn functools_cache(checker: &mut Checker, decorator_list: &[Expr]) {
|
||||||
|
|
@ -37,7 +53,7 @@ pub fn functools_cache(checker: &mut Checker, decorator_list: &[Expr]) {
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::FunctoolsCache,
|
FunctoolsCache,
|
||||||
Range::new(func.end_location.unwrap(), expr.end_location.unwrap()),
|
Range::new(func.end_location.unwrap(), expr.end_location.unwrap()),
|
||||||
);
|
);
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustpython_ast::{Alias, AliasData, Stmt};
|
|
||||||
|
|
||||||
use ruff_macros::derive_message_formats;
|
use ruff_macros::derive_message_formats;
|
||||||
|
use rustpython_ast::{Alias, AliasData, Stmt};
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
use crate::ast::whitespace::indentation;
|
use crate::ast::whitespace::indentation;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::ExprKind;
|
use rustpython_ast::ExprKind;
|
||||||
use rustpython_parser::ast::Expr;
|
use rustpython_parser::ast::Expr;
|
||||||
|
|
||||||
|
|
@ -6,7 +9,20 @@ use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct LRUCacheWithoutParameters;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for LRUCacheWithoutParameters {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Unnecessary parameters to `functools.lru_cache`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Remove unnecessary parameters".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// UP011
|
/// UP011
|
||||||
pub fn lru_cache_without_parameters(checker: &mut Checker, decorator_list: &[Expr]) {
|
pub fn lru_cache_without_parameters(checker: &mut Checker, decorator_list: &[Expr]) {
|
||||||
|
|
@ -27,7 +43,7 @@ pub fn lru_cache_without_parameters(checker: &mut Checker, decorator_list: &[Exp
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::LRUCacheWithoutParameters,
|
LRUCacheWithoutParameters,
|
||||||
Range::new(func.end_location.unwrap(), expr.end_location.unwrap()),
|
Range::new(func.end_location.unwrap(), expr.end_location.unwrap()),
|
||||||
);
|
);
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,48 @@
|
||||||
pub(crate) use convert_named_tuple_functional_to_class::convert_named_tuple_functional_to_class;
|
pub(crate) use convert_named_tuple_functional_to_class::{
|
||||||
pub(crate) use convert_typed_dict_functional_to_class::convert_typed_dict_functional_to_class;
|
convert_named_tuple_functional_to_class, ConvertNamedTupleFunctionalToClass,
|
||||||
pub(crate) use datetime_utc_alias::datetime_utc_alias;
|
};
|
||||||
pub(crate) use deprecated_unittest_alias::deprecated_unittest_alias;
|
pub(crate) use convert_typed_dict_functional_to_class::{
|
||||||
pub(crate) use extraneous_parentheses::extraneous_parentheses;
|
convert_typed_dict_functional_to_class, ConvertTypedDictFunctionalToClass,
|
||||||
pub(crate) use f_strings::f_strings;
|
};
|
||||||
pub(crate) use format_literals::format_literals;
|
pub(crate) use datetime_utc_alias::{datetime_utc_alias, DatetimeTimezoneUTC};
|
||||||
pub(crate) use functools_cache::functools_cache;
|
pub(crate) use deprecated_unittest_alias::{deprecated_unittest_alias, DeprecatedUnittestAlias};
|
||||||
|
pub(crate) use extraneous_parentheses::{extraneous_parentheses, ExtraneousParentheses};
|
||||||
|
pub(crate) use f_strings::{f_strings, FString};
|
||||||
|
pub(crate) use format_literals::{format_literals, FormatLiterals};
|
||||||
|
pub(crate) use functools_cache::{functools_cache, FunctoolsCache};
|
||||||
pub(crate) use import_replacements::{import_replacements, ImportReplacements};
|
pub(crate) use import_replacements::{import_replacements, ImportReplacements};
|
||||||
pub(crate) use lru_cache_without_parameters::lru_cache_without_parameters;
|
pub(crate) use lru_cache_without_parameters::{
|
||||||
pub(crate) use native_literals::native_literals;
|
lru_cache_without_parameters, LRUCacheWithoutParameters,
|
||||||
pub(crate) use open_alias::open_alias;
|
};
|
||||||
pub(crate) use os_error_alias::os_error_alias;
|
pub(crate) use native_literals::{native_literals, NativeLiterals};
|
||||||
|
pub(crate) use open_alias::{open_alias, OpenAlias};
|
||||||
|
pub(crate) use os_error_alias::{os_error_alias, OSErrorAlias};
|
||||||
pub(crate) use outdated_version_block::{outdated_version_block, OutdatedVersionBlock};
|
pub(crate) use outdated_version_block::{outdated_version_block, OutdatedVersionBlock};
|
||||||
pub(crate) use printf_string_formatting::printf_string_formatting;
|
pub(crate) use printf_string_formatting::{printf_string_formatting, PrintfStringFormatting};
|
||||||
pub(crate) use redundant_open_modes::redundant_open_modes;
|
pub(crate) use redundant_open_modes::{redundant_open_modes, RedundantOpenModes};
|
||||||
pub(crate) use replace_stdout_stderr::replace_stdout_stderr;
|
pub(crate) use replace_stdout_stderr::{replace_stdout_stderr, ReplaceStdoutStderr};
|
||||||
pub(crate) use replace_universal_newlines::replace_universal_newlines;
|
pub(crate) use replace_universal_newlines::{replace_universal_newlines, ReplaceUniversalNewlines};
|
||||||
pub(crate) use rewrite_c_element_tree::replace_c_element_tree;
|
pub(crate) use rewrite_c_element_tree::{replace_c_element_tree, RewriteCElementTree};
|
||||||
pub(crate) use rewrite_mock_import::{rewrite_mock_attribute, rewrite_mock_import};
|
pub(crate) use rewrite_mock_import::{
|
||||||
pub(crate) use rewrite_unicode_literal::rewrite_unicode_literal;
|
rewrite_mock_attribute, rewrite_mock_import, RewriteMockImport,
|
||||||
pub(crate) use rewrite_yield_from::rewrite_yield_from;
|
};
|
||||||
|
pub(crate) use rewrite_unicode_literal::{rewrite_unicode_literal, RewriteUnicodeLiteral};
|
||||||
|
pub(crate) use rewrite_yield_from::{rewrite_yield_from, RewriteYieldFrom};
|
||||||
pub(crate) use super_args::super_args;
|
pub(crate) use super_args::super_args;
|
||||||
pub(crate) use super_call_with_parameters::super_call_with_parameters;
|
pub(crate) use super_call_with_parameters::{super_call_with_parameters, SuperCallWithParameters};
|
||||||
pub(crate) use type_of_primitive::type_of_primitive;
|
pub(crate) use type_of_primitive::{type_of_primitive, TypeOfPrimitive};
|
||||||
pub(crate) use typing_text_str_alias::typing_text_str_alias;
|
pub(crate) use typing_text_str_alias::{typing_text_str_alias, TypingTextStrAlias};
|
||||||
pub(crate) use unnecessary_builtin_import::unnecessary_builtin_import;
|
pub(crate) use unnecessary_builtin_import::{unnecessary_builtin_import, UnnecessaryBuiltinImport};
|
||||||
pub(crate) use unnecessary_coding_comment::unnecessary_coding_comment;
|
pub(crate) use unnecessary_coding_comment::{
|
||||||
pub(crate) use unnecessary_encode_utf8::unnecessary_encode_utf8;
|
unnecessary_coding_comment, PEP3120UnnecessaryCodingComment,
|
||||||
pub(crate) use unnecessary_future_import::unnecessary_future_import;
|
};
|
||||||
pub(crate) use unpack_list_comprehension::unpack_list_comprehension;
|
pub(crate) use unnecessary_encode_utf8::{unnecessary_encode_utf8, UnnecessaryEncodeUTF8};
|
||||||
pub(crate) use use_pep585_annotation::use_pep585_annotation;
|
pub(crate) use unnecessary_future_import::{unnecessary_future_import, UnnecessaryFutureImport};
|
||||||
pub(crate) use use_pep604_annotation::use_pep604_annotation;
|
pub(crate) use unpack_list_comprehension::{unpack_list_comprehension, RewriteListComprehension};
|
||||||
pub(crate) use useless_metaclass_type::useless_metaclass_type;
|
pub(crate) use use_pep585_annotation::{use_pep585_annotation, UsePEP585Annotation};
|
||||||
pub(crate) use useless_object_inheritance::useless_object_inheritance;
|
pub(crate) use use_pep604_annotation::{use_pep604_annotation, UsePEP604Annotation};
|
||||||
|
pub(crate) use useless_metaclass_type::{useless_metaclass_type, UselessMetaclassType};
|
||||||
|
pub(crate) use useless_object_inheritance::{useless_object_inheritance, UselessObjectInheritance};
|
||||||
|
|
||||||
mod convert_named_tuple_functional_to_class;
|
mod convert_named_tuple_functional_to_class;
|
||||||
mod convert_typed_dict_functional_to_class;
|
mod convert_typed_dict_functional_to_class;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,49 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Constant, Expr, ExprKind, Keyword};
|
use rustpython_ast::{Constant, Expr, ExprKind, Keyword};
|
||||||
use rustpython_parser::lexer;
|
use rustpython_parser::lexer;
|
||||||
use rustpython_parser::lexer::Tok;
|
use rustpython_parser::lexer::Tok;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
use crate::violations::LiteralType;
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub enum LiteralType {
|
||||||
|
Str,
|
||||||
|
Bytes,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for LiteralType {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
LiteralType::Str => fmt.write_str("str"),
|
||||||
|
LiteralType::Bytes => fmt.write_str("bytes"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct NativeLiterals {
|
||||||
|
pub literal_type: LiteralType,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for NativeLiterals {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let NativeLiterals { literal_type } = self;
|
||||||
|
format!("Unnecessary call to `{literal_type}`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
let NativeLiterals { literal_type } = self;
|
||||||
|
format!("Replace with `{literal_type}`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// UP018
|
/// UP018
|
||||||
pub fn native_literals(
|
pub fn native_literals(
|
||||||
|
|
@ -25,7 +61,7 @@ pub fn native_literals(
|
||||||
|
|
||||||
if (id == "str" || id == "bytes") && checker.is_builtin(id) {
|
if (id == "str" || id == "bytes") && checker.is_builtin(id) {
|
||||||
let Some(arg) = args.get(0) else {
|
let Some(arg) = args.get(0) else {
|
||||||
let mut diagnostic = Diagnostic::new(violations::NativeLiterals{literal_type:if id == "str" {
|
let mut diagnostic = Diagnostic::new(NativeLiterals{literal_type:if id == "str" {
|
||||||
LiteralType::Str
|
LiteralType::Str
|
||||||
} else {
|
} else {
|
||||||
LiteralType::Bytes
|
LiteralType::Bytes
|
||||||
|
|
@ -94,7 +130,7 @@ pub fn native_literals(
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::NativeLiterals {
|
NativeLiterals {
|
||||||
literal_type: if id == "str" {
|
literal_type: if id == "str" {
|
||||||
LiteralType::Str
|
LiteralType::Str
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,26 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::Expr;
|
use rustpython_ast::Expr;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct OpenAlias;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for OpenAlias {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Use builtin `open`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Replace with builtin `open`".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// UP020
|
/// UP020
|
||||||
pub fn open_alias(checker: &mut Checker, expr: &Expr, func: &Expr) {
|
pub fn open_alias(checker: &mut Checker, expr: &Expr, func: &Expr) {
|
||||||
|
|
@ -12,7 +28,7 @@ pub fn open_alias(checker: &mut Checker, expr: &Expr, func: &Expr) {
|
||||||
.resolve_call_path(func)
|
.resolve_call_path(func)
|
||||||
.map_or(false, |call_path| call_path.as_slice() == ["io", "open"])
|
.map_or(false, |call_path| call_path.as_slice() == ["io", "open"])
|
||||||
{
|
{
|
||||||
let mut diagnostic = Diagnostic::new(violations::OpenAlias, Range::from_located(expr));
|
let mut diagnostic = Diagnostic::new(OpenAlias, Range::from_located(expr));
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
diagnostic.amend(Fix::replacement(
|
diagnostic.amend(Fix::replacement(
|
||||||
"open".to_string(),
|
"open".to_string(),
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Excepthandler, ExcepthandlerKind, Expr, ExprKind, Located};
|
use rustpython_ast::{Excepthandler, ExcepthandlerKind, Expr, ExprKind, Located};
|
||||||
|
|
||||||
use crate::ast::helpers::compose_call_path;
|
use crate::ast::helpers::compose_call_path;
|
||||||
|
|
@ -6,7 +9,26 @@ use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct OSErrorAlias {
|
||||||
|
pub name: Option<String>,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for OSErrorAlias {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Replace aliased errors with `OSError`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
let OSErrorAlias { name } = self;
|
||||||
|
match name {
|
||||||
|
None => "Replace with builtin `OSError`".to_string(),
|
||||||
|
Some(name) => format!("Replace `{name}` with builtin `OSError`"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const ERROR_NAMES: &[&str] = &["EnvironmentError", "IOError", "WindowsError"];
|
const ERROR_NAMES: &[&str] = &["EnvironmentError", "IOError", "WindowsError"];
|
||||||
const ERROR_MODULES: &[&str] = &["mmap", "select", "socket"];
|
const ERROR_MODULES: &[&str] = &["mmap", "select", "socket"];
|
||||||
|
|
@ -145,7 +167,7 @@ fn handle_making_changes(
|
||||||
final_str.push(')');
|
final_str.push(')');
|
||||||
}
|
}
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::OSErrorAlias {
|
OSErrorAlias {
|
||||||
name: compose_call_path(target),
|
name: compose_call_path(target),
|
||||||
},
|
},
|
||||||
Range::from_located(target),
|
Range::from_located(target),
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use log::error;
|
use log::error;
|
||||||
|
|
@ -7,8 +9,6 @@ use rustpython_parser::ast::{Cmpop, Constant, Expr, ExprKind, Located, Stmt};
|
||||||
use rustpython_parser::lexer;
|
use rustpython_parser::lexer;
|
||||||
use rustpython_parser::lexer::Tok;
|
use rustpython_parser::lexer::Tok;
|
||||||
|
|
||||||
use ruff_macros::derive_message_formats;
|
|
||||||
|
|
||||||
use crate::ast::types::{Range, RefEquality};
|
use crate::ast::types::{Range, RefEquality};
|
||||||
use crate::ast::whitespace::indentation;
|
use crate::ast::whitespace::indentation;
|
||||||
use crate::autofix::helpers::delete_stmt;
|
use crate::autofix::helpers::delete_stmt;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use rustpython_ast::Location;
|
use rustpython_ast::Location;
|
||||||
|
|
@ -17,7 +21,20 @@ use crate::python::keyword::KWLIST;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::rules::pydocstyle::helpers::{leading_quote, trailing_quote};
|
use crate::rules::pydocstyle::helpers::{leading_quote, trailing_quote};
|
||||||
use crate::rules::pyupgrade::helpers::curly_escape;
|
use crate::rules::pyupgrade::helpers::curly_escape;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct PrintfStringFormatting;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for PrintfStringFormatting {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Use format specifiers instead of percent format")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Replace with format specifiers".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn simplify_conversion_flag(flags: CConversionFlags) -> String {
|
fn simplify_conversion_flag(flags: CConversionFlags) -> String {
|
||||||
let mut flag_string = String::new();
|
let mut flag_string = String::new();
|
||||||
|
|
@ -406,10 +423,7 @@ pub(crate) fn printf_string_formatting(
|
||||||
// Add the `.format` call.
|
// Add the `.format` call.
|
||||||
contents.push_str(&format!(".format{params_string}"));
|
contents.push_str(&format!(".format{params_string}"));
|
||||||
|
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(PrintfStringFormatting, Range::from_located(expr));
|
||||||
violations::PrintfStringFormatting,
|
|
||||||
Range::from_located(expr),
|
|
||||||
);
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
diagnostic.amend(Fix::replacement(
|
diagnostic.amend(Fix::replacement(
|
||||||
contents,
|
contents,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
|
@ -12,7 +16,34 @@ use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::{Diagnostic, Rule};
|
use crate::registry::{Diagnostic, Rule};
|
||||||
use crate::source_code::Locator;
|
use crate::source_code::Locator;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct RedundantOpenModes {
|
||||||
|
pub replacement: Option<String>,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for RedundantOpenModes {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let RedundantOpenModes { replacement } = self;
|
||||||
|
match replacement {
|
||||||
|
None => format!("Unnecessary open mode parameters"),
|
||||||
|
Some(replacement) => {
|
||||||
|
format!("Unnecessary open mode parameters, use \"{replacement}\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
let RedundantOpenModes { replacement } = self;
|
||||||
|
match replacement {
|
||||||
|
None => "Remove open mode parameters".to_string(),
|
||||||
|
Some(replacement) => {
|
||||||
|
format!("Replace with \"{replacement}\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const OPEN_FUNC_NAME: &str = "open";
|
const OPEN_FUNC_NAME: &str = "open";
|
||||||
const MODE_KEYWORD_ARGUMENT: &str = "mode";
|
const MODE_KEYWORD_ARGUMENT: &str = "mode";
|
||||||
|
|
@ -81,7 +112,7 @@ fn create_check(
|
||||||
patch: bool,
|
patch: bool,
|
||||||
) -> Diagnostic {
|
) -> Diagnostic {
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::RedundantOpenModes {
|
RedundantOpenModes {
|
||||||
replacement: replacement_value.clone(),
|
replacement: replacement_value.clone(),
|
||||||
},
|
},
|
||||||
Range::from_located(expr),
|
Range::from_located(expr),
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Expr, Keyword};
|
use rustpython_ast::{Expr, Keyword};
|
||||||
|
|
||||||
use crate::ast::helpers::find_keyword;
|
use crate::ast::helpers::find_keyword;
|
||||||
|
|
@ -7,7 +10,20 @@ use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::source_code::{Locator, Stylist};
|
use crate::source_code::{Locator, Stylist};
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct ReplaceStdoutStderr;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for ReplaceStdoutStderr {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Sending stdout and stderr to pipe is deprecated, use `capture_output`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Replace with `capture_output` keyword argument".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct MiddleContent<'a> {
|
struct MiddleContent<'a> {
|
||||||
|
|
@ -116,8 +132,7 @@ pub fn replace_stdout_stderr(checker: &mut Checker, expr: &Expr, kwargs: &[Keywo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut diagnostic =
|
let mut diagnostic = Diagnostic::new(ReplaceStdoutStderr, Range::from_located(expr));
|
||||||
Diagnostic::new(violations::ReplaceStdoutStderr, Range::from_located(expr));
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
if let Some(fix) = generate_fix(checker.stylist, checker.locator, stdout, stderr) {
|
if let Some(fix) = generate_fix(checker.stylist, checker.locator, stdout, stderr) {
|
||||||
diagnostic.amend(fix);
|
diagnostic.amend(fix);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Expr, Keyword, Location};
|
use rustpython_ast::{Expr, Keyword, Location};
|
||||||
|
|
||||||
use crate::ast::helpers::find_keyword;
|
use crate::ast::helpers::find_keyword;
|
||||||
|
|
@ -5,7 +8,20 @@ use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct ReplaceUniversalNewlines;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for ReplaceUniversalNewlines {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("`universal_newlines` is deprecated, use `text`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Replace with `text` keyword argument".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// UP021
|
/// UP021
|
||||||
pub fn replace_universal_newlines(checker: &mut Checker, expr: &Expr, kwargs: &[Keyword]) {
|
pub fn replace_universal_newlines(checker: &mut Checker, expr: &Expr, kwargs: &[Keyword]) {
|
||||||
|
|
@ -20,7 +36,7 @@ pub fn replace_universal_newlines(checker: &mut Checker, expr: &Expr, kwargs: &[
|
||||||
kwarg.location.column() + "universal_newlines".len(),
|
kwarg.location.column() + "universal_newlines".len(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
let mut diagnostic = Diagnostic::new(violations::ReplaceUniversalNewlines, range);
|
let mut diagnostic = Diagnostic::new(ReplaceUniversalNewlines, range);
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
diagnostic.amend(Fix::replacement(
|
diagnostic.amend(Fix::replacement(
|
||||||
"text".to_string(),
|
"text".to_string(),
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,29 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Located, Stmt, StmtKind};
|
use rustpython_ast::{Located, Stmt, StmtKind};
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct RewriteCElementTree;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for RewriteCElementTree {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("`cElementTree` is deprecated, use `ElementTree`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Replace with `ElementTree`".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn add_check_for_node<T>(checker: &mut Checker, node: &Located<T>) {
|
fn add_check_for_node<T>(checker: &mut Checker, node: &Located<T>) {
|
||||||
let mut diagnostic =
|
let mut diagnostic = Diagnostic::new(RewriteCElementTree, Range::from_located(node));
|
||||||
Diagnostic::new(violations::RewriteCElementTree, Range::from_located(node));
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
let contents = checker
|
let contents = checker
|
||||||
.locator
|
.locator
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,14 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use libcst_native::{
|
use libcst_native::{
|
||||||
AsName, AssignTargetExpression, Attribute, Codegen, CodegenState, Dot, Expression, Import,
|
AsName, AssignTargetExpression, Attribute, Codegen, CodegenState, Dot, Expression, Import,
|
||||||
ImportAlias, ImportFrom, ImportNames, Name, NameOrAttribute, ParenthesizableWhitespace,
|
ImportAlias, ImportFrom, ImportNames, Name, NameOrAttribute, ParenthesizableWhitespace,
|
||||||
};
|
};
|
||||||
use log::error;
|
use log::error;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Expr, ExprKind, Stmt, StmtKind};
|
use rustpython_ast::{Expr, ExprKind, Stmt, StmtKind};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::ast::helpers::collect_call_path;
|
use crate::ast::helpers::collect_call_path;
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
|
|
@ -14,8 +18,32 @@ use crate::cst::matchers::{match_import, match_import_from, match_module};
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::{Diagnostic, Rule};
|
use crate::registry::{Diagnostic, Rule};
|
||||||
use crate::source_code::{Locator, Stylist};
|
use crate::source_code::{Locator, Stylist};
|
||||||
use crate::violations;
|
|
||||||
use crate::violations::MockReference;
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub enum MockReference {
|
||||||
|
Import,
|
||||||
|
Attribute,
|
||||||
|
}
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct RewriteMockImport {
|
||||||
|
pub reference_type: MockReference,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for RewriteMockImport {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("`mock` is deprecated, use `unittest.mock`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
let RewriteMockImport { reference_type } = self;
|
||||||
|
match reference_type {
|
||||||
|
MockReference::Import => "Import from `unittest.mock` instead".to_string(),
|
||||||
|
MockReference::Attribute => "Replace `mock.mock` with `mock`".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Return a vector of all non-`mock` imports.
|
/// Return a vector of all non-`mock` imports.
|
||||||
fn clean_import_aliases(aliases: Vec<ImportAlias>) -> (Vec<ImportAlias>, Vec<Option<AsName>>) {
|
fn clean_import_aliases(aliases: Vec<ImportAlias>) -> (Vec<ImportAlias>, Vec<Option<AsName>>) {
|
||||||
|
|
@ -209,7 +237,7 @@ pub fn rewrite_mock_attribute(checker: &mut Checker, expr: &Expr) {
|
||||||
if let ExprKind::Attribute { value, .. } = &expr.node {
|
if let ExprKind::Attribute { value, .. } = &expr.node {
|
||||||
if collect_call_path(value).as_slice() == ["mock", "mock"] {
|
if collect_call_path(value).as_slice() == ["mock", "mock"] {
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::RewriteMockImport {
|
RewriteMockImport {
|
||||||
reference_type: MockReference::Attribute,
|
reference_type: MockReference::Attribute,
|
||||||
},
|
},
|
||||||
Range::from_located(value),
|
Range::from_located(value),
|
||||||
|
|
@ -256,7 +284,7 @@ pub fn rewrite_mock_import(checker: &mut Checker, stmt: &Stmt) {
|
||||||
for name in names {
|
for name in names {
|
||||||
if name.node.name == "mock" || name.node.name == "mock.mock" {
|
if name.node.name == "mock" || name.node.name == "mock.mock" {
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::RewriteMockImport {
|
RewriteMockImport {
|
||||||
reference_type: MockReference::Import,
|
reference_type: MockReference::Import,
|
||||||
},
|
},
|
||||||
Range::from_located(name),
|
Range::from_located(name),
|
||||||
|
|
@ -284,7 +312,7 @@ pub fn rewrite_mock_import(checker: &mut Checker, stmt: &Stmt) {
|
||||||
|
|
||||||
if module == "mock" {
|
if module == "mock" {
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::RewriteMockImport {
|
RewriteMockImport {
|
||||||
reference_type: MockReference::Import,
|
reference_type: MockReference::Import,
|
||||||
},
|
},
|
||||||
Range::from_located(stmt),
|
Range::from_located(stmt),
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,32 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Expr, Location};
|
use rustpython_ast::{Expr, Location};
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct RewriteUnicodeLiteral;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for RewriteUnicodeLiteral {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Remove unicode literals from strings")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Remove unicode prefix".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// UP025
|
/// UP025
|
||||||
pub fn rewrite_unicode_literal(checker: &mut Checker, expr: &Expr, kind: Option<&str>) {
|
pub fn rewrite_unicode_literal(checker: &mut Checker, expr: &Expr, kind: Option<&str>) {
|
||||||
if let Some(const_kind) = kind {
|
if let Some(const_kind) = kind {
|
||||||
if const_kind.to_lowercase() == "u" {
|
if const_kind.to_lowercase() == "u" {
|
||||||
let mut diagnostic =
|
let mut diagnostic = Diagnostic::new(RewriteUnicodeLiteral, Range::from_located(expr));
|
||||||
Diagnostic::new(violations::RewriteUnicodeLiteral, Range::from_located(expr));
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
diagnostic.amend(Fix::deletion(
|
diagnostic.amend(Fix::deletion(
|
||||||
expr.location,
|
expr.location,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use rustpython_ast::{Expr, ExprContext, ExprKind, Stmt, StmtKind};
|
use rustpython_ast::{Expr, ExprContext, ExprKind, Stmt, StmtKind};
|
||||||
|
|
||||||
|
|
@ -7,7 +10,20 @@ use crate::ast::visitor::Visitor;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct RewriteYieldFrom;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for RewriteYieldFrom {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Replace `yield` over `for` loop with `yield from`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Replace with `yield from`".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Return `true` if the two expressions are equivalent, and consistent solely
|
/// Return `true` if the two expressions are equivalent, and consistent solely
|
||||||
/// of tuples and names.
|
/// of tuples and names.
|
||||||
|
|
@ -157,8 +173,7 @@ pub fn rewrite_yield_from(checker: &mut Checker, stmt: &Stmt) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut diagnostic =
|
let mut diagnostic = Diagnostic::new(RewriteYieldFrom, Range::from_located(item.stmt));
|
||||||
Diagnostic::new(violations::RewriteYieldFrom, Range::from_located(item.stmt));
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
let contents = checker
|
let contents = checker
|
||||||
.locator
|
.locator
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
use crate::ast::helpers;
|
use crate::ast::helpers;
|
||||||
use crate::ast::types::{Range, Scope, ScopeKind};
|
use crate::ast::types::{Range, Scope, ScopeKind};
|
||||||
|
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
use crate::rules::pyupgrade::rules::SuperCallWithParameters;
|
||||||
|
|
||||||
use rustpython_ast::{ArgData, Expr, ExprKind, Stmt, StmtKind};
|
use rustpython_ast::{ArgData, Expr, ExprKind, Stmt, StmtKind};
|
||||||
|
|
||||||
/// UP008
|
/// UP008
|
||||||
|
|
@ -68,7 +71,7 @@ pub fn super_args(
|
||||||
|
|
||||||
if first_arg_id == parent_name && second_arg_id == parent_arg {
|
if first_arg_id == parent_name && second_arg_id == parent_arg {
|
||||||
return Some(Diagnostic::new(
|
return Some(Diagnostic::new(
|
||||||
violations::SuperCallWithParameters,
|
SuperCallWithParameters,
|
||||||
Range::from_located(expr),
|
Range::from_located(expr),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,26 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Expr, Stmt};
|
use rustpython_ast::{Expr, Stmt};
|
||||||
|
|
||||||
use super::super::fixes;
|
use super::super::fixes;
|
||||||
use crate::ast::helpers;
|
use crate::ast::helpers;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct SuperCallWithParameters;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for SuperCallWithParameters {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Use `super()` instead of `super(__class__, self)`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Remove `__super__` parameters".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// UP008
|
/// UP008
|
||||||
pub fn super_call_with_parameters(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) {
|
pub fn super_call_with_parameters(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) {
|
||||||
// Only bother going through the super check at all if we're in a `super` call.
|
// Only bother going through the super check at all if we're in a `super` call.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Expr, ExprKind};
|
use rustpython_ast::{Expr, ExprKind};
|
||||||
|
|
||||||
use super::super::types::Primitive;
|
use super::super::types::Primitive;
|
||||||
|
|
@ -5,7 +8,24 @@ use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct TypeOfPrimitive {
|
||||||
|
pub primitive: Primitive,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for TypeOfPrimitive {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let TypeOfPrimitive { primitive } = self;
|
||||||
|
format!("Use `{}` instead of `type(...)`", primitive.builtin())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
let TypeOfPrimitive { primitive } = self;
|
||||||
|
format!("Replace `type(...)` with `{}`", primitive.builtin())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// UP003
|
/// UP003
|
||||||
pub fn type_of_primitive(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) {
|
pub fn type_of_primitive(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) {
|
||||||
|
|
@ -24,10 +44,7 @@ pub fn type_of_primitive(checker: &mut Checker, expr: &Expr, func: &Expr, args:
|
||||||
let Some(primitive) = Primitive::from_constant(value) else {
|
let Some(primitive) = Primitive::from_constant(value) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(TypeOfPrimitive { primitive }, Range::from_located(expr));
|
||||||
violations::TypeOfPrimitive { primitive },
|
|
||||||
Range::from_located(expr),
|
|
||||||
);
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
diagnostic.amend(Fix::replacement(
|
diagnostic.amend(Fix::replacement(
|
||||||
primitive.builtin(),
|
primitive.builtin(),
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,33 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::Expr;
|
use rustpython_ast::Expr;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct TypingTextStrAlias;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for TypingTextStrAlias {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("`typing.Text` is deprecated, use `str`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Replace with `str`".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// UP019
|
/// UP019
|
||||||
pub fn typing_text_str_alias(checker: &mut Checker, expr: &Expr) {
|
pub fn typing_text_str_alias(checker: &mut Checker, expr: &Expr) {
|
||||||
if checker.resolve_call_path(expr).map_or(false, |call_path| {
|
if checker.resolve_call_path(expr).map_or(false, |call_path| {
|
||||||
call_path.as_slice() == ["typing", "Text"]
|
call_path.as_slice() == ["typing", "Text"]
|
||||||
}) {
|
}) {
|
||||||
let mut diagnostic =
|
let mut diagnostic = Diagnostic::new(TypingTextStrAlias, Range::from_located(expr));
|
||||||
Diagnostic::new(violations::TypingTextStrAlias, Range::from_located(expr));
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
diagnostic.amend(Fix::replacement(
|
diagnostic.amend(Fix::replacement(
|
||||||
"str".to_string(),
|
"str".to_string(),
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,38 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use log::error;
|
use log::error;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Alias, AliasData, Located};
|
use rustpython_ast::{Alias, AliasData, Located};
|
||||||
use rustpython_parser::ast::Stmt;
|
use rustpython_parser::ast::Stmt;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
|
use crate::autofix;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::{autofix, violations};
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct UnnecessaryBuiltinImport {
|
||||||
|
pub names: Vec<String>,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for UnnecessaryBuiltinImport {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let UnnecessaryBuiltinImport { names } = self;
|
||||||
|
if names.len() == 1 {
|
||||||
|
let import = &names[0];
|
||||||
|
format!("Unnecessary builtin import: `{import}`")
|
||||||
|
} else {
|
||||||
|
let imports = names.iter().map(|name| format!("`{name}`")).join(", ");
|
||||||
|
format!("Unnecessary builtin imports: {imports}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Remove unnecessary builtin import".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const BUILTINS: &[&str] = &[
|
const BUILTINS: &[&str] = &[
|
||||||
"*",
|
"*",
|
||||||
|
|
@ -69,7 +95,7 @@ pub fn unnecessary_builtin_import(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::UnnecessaryBuiltinImport {
|
UnnecessaryBuiltinImport {
|
||||||
names: unused_imports
|
names: unused_imports
|
||||||
.iter()
|
.iter()
|
||||||
.map(|alias| alias.node.name.to_string())
|
.map(|alias| alias.node.name.to_string())
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,28 @@
|
||||||
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::violations;
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::Location;
|
use rustpython_ast::Location;
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct PEP3120UnnecessaryCodingComment;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for PEP3120UnnecessaryCodingComment {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("UTF-8 encoding declaration is unnecessary")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Remove unnecessary coding comment".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Regex from PEP263.
|
// Regex from PEP263.
|
||||||
static CODING_COMMENT_REGEX: Lazy<Regex> =
|
static CODING_COMMENT_REGEX: Lazy<Regex> =
|
||||||
Lazy::new(|| Regex::new(r"^[ \t\f]*#.*?coding[:=][ \t]*utf-?8").unwrap());
|
Lazy::new(|| Regex::new(r"^[ \t\f]*#.*?coding[:=][ \t]*utf-?8").unwrap());
|
||||||
|
|
@ -15,7 +32,7 @@ pub fn unnecessary_coding_comment(lineno: usize, line: &str, autofix: bool) -> O
|
||||||
// PEP3120 makes utf-8 the default encoding.
|
// PEP3120 makes utf-8 the default encoding.
|
||||||
if CODING_COMMENT_REGEX.is_match(line) {
|
if CODING_COMMENT_REGEX.is_match(line) {
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::PEP3120UnnecessaryCodingComment,
|
PEP3120UnnecessaryCodingComment,
|
||||||
Range::new(Location::new(lineno + 1, 0), Location::new(lineno + 2, 0)),
|
Range::new(Location::new(lineno + 1, 0), Location::new(lineno + 2, 0)),
|
||||||
);
|
);
|
||||||
if autofix {
|
if autofix {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Constant, Expr, ExprKind, Keyword};
|
use rustpython_ast::{Constant, Expr, ExprKind, Keyword};
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
|
|
@ -5,7 +8,20 @@ use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::{Diagnostic, Rule};
|
use crate::registry::{Diagnostic, Rule};
|
||||||
use crate::source_code::Locator;
|
use crate::source_code::Locator;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct UnnecessaryEncodeUTF8;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for UnnecessaryEncodeUTF8 {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Unnecessary call to `encode` as UTF-8")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Remove unnecessary `encode`".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const UTF8_LITERALS: &[&str] = &["utf-8", "utf8", "utf_8", "u8", "utf", "cp65001"];
|
const UTF8_LITERALS: &[&str] = &["utf-8", "utf8", "utf_8", "u8", "utf", "cp65001"];
|
||||||
|
|
||||||
|
|
@ -60,15 +76,13 @@ fn delete_default_encode_arg_or_kwarg(
|
||||||
patch: bool,
|
patch: bool,
|
||||||
) -> Option<Diagnostic> {
|
) -> Option<Diagnostic> {
|
||||||
if let Some(arg) = args.get(0) {
|
if let Some(arg) = args.get(0) {
|
||||||
let mut diagnostic =
|
let mut diagnostic = Diagnostic::new(UnnecessaryEncodeUTF8, Range::from_located(expr));
|
||||||
Diagnostic::new(violations::UnnecessaryEncodeUTF8, Range::from_located(expr));
|
|
||||||
if patch {
|
if patch {
|
||||||
diagnostic.amend(Fix::deletion(arg.location, arg.end_location.unwrap()));
|
diagnostic.amend(Fix::deletion(arg.location, arg.end_location.unwrap()));
|
||||||
}
|
}
|
||||||
Some(diagnostic)
|
Some(diagnostic)
|
||||||
} else if let Some(kwarg) = kwargs.get(0) {
|
} else if let Some(kwarg) = kwargs.get(0) {
|
||||||
let mut diagnostic =
|
let mut diagnostic = Diagnostic::new(UnnecessaryEncodeUTF8, Range::from_located(expr));
|
||||||
Diagnostic::new(violations::UnnecessaryEncodeUTF8, Range::from_located(expr));
|
|
||||||
if patch {
|
if patch {
|
||||||
diagnostic.amend(Fix::deletion(kwarg.location, kwarg.end_location.unwrap()));
|
diagnostic.amend(Fix::deletion(kwarg.location, kwarg.end_location.unwrap()));
|
||||||
}
|
}
|
||||||
|
|
@ -85,8 +99,7 @@ fn replace_with_bytes_literal(
|
||||||
locator: &Locator,
|
locator: &Locator,
|
||||||
patch: bool,
|
patch: bool,
|
||||||
) -> Diagnostic {
|
) -> Diagnostic {
|
||||||
let mut diagnostic =
|
let mut diagnostic = Diagnostic::new(UnnecessaryEncodeUTF8, Range::from_located(expr));
|
||||||
Diagnostic::new(violations::UnnecessaryEncodeUTF8, Range::from_located(expr));
|
|
||||||
if patch {
|
if patch {
|
||||||
let content = locator.slice_source_code_range(&Range::new(
|
let content = locator.slice_source_code_range(&Range::new(
|
||||||
constant.location,
|
constant.location,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,38 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use log::error;
|
use log::error;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Alias, AliasData, Located};
|
use rustpython_ast::{Alias, AliasData, Located};
|
||||||
use rustpython_parser::ast::Stmt;
|
use rustpython_parser::ast::Stmt;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
|
use crate::autofix;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::{autofix, violations};
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct UnnecessaryFutureImport {
|
||||||
|
pub names: Vec<String>,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for UnnecessaryFutureImport {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let UnnecessaryFutureImport { names } = self;
|
||||||
|
if names.len() == 1 {
|
||||||
|
let import = &names[0];
|
||||||
|
format!("Unnecessary `__future__` import `{import}` for target Python version")
|
||||||
|
} else {
|
||||||
|
let imports = names.iter().map(|name| format!("`{name}`")).join(", ");
|
||||||
|
format!("Unnecessary `__future__` imports {imports} for target Python version")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Remove unnecessary `__future__` import".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const PY33_PLUS_REMOVE_FUTURES: &[&str] = &[
|
const PY33_PLUS_REMOVE_FUTURES: &[&str] = &[
|
||||||
"nested_scopes",
|
"nested_scopes",
|
||||||
|
|
@ -49,7 +75,7 @@ pub fn unnecessary_future_import(checker: &mut Checker, stmt: &Stmt, names: &[Lo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::UnnecessaryFutureImport {
|
UnnecessaryFutureImport {
|
||||||
names: unused_imports
|
names: unused_imports
|
||||||
.iter()
|
.iter()
|
||||||
.map(|alias| alias.node.name.to_string())
|
.map(|alias| alias.node.name.to_string())
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,26 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Expr, ExprKind};
|
use rustpython_ast::{Expr, ExprKind};
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct RewriteListComprehension;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for RewriteListComprehension {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Replace unpacked list comprehension with a generator expression")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Replace with generator expression".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if `expr` contains an `ExprKind::Await`.
|
/// Returns `true` if `expr` contains an `ExprKind::Await`.
|
||||||
fn contains_await(expr: &Expr) -> bool {
|
fn contains_await(expr: &Expr) -> bool {
|
||||||
|
|
@ -79,10 +95,8 @@ pub fn unpack_list_comprehension(checker: &mut Checker, targets: &[Expr], value:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic =
|
||||||
violations::RewriteListComprehension,
|
Diagnostic::new(RewriteListComprehension, Range::from_located(value));
|
||||||
Range::from_located(value),
|
|
||||||
);
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
let existing = checker
|
let existing = checker
|
||||||
.locator
|
.locator
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,34 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::Expr;
|
use rustpython_ast::Expr;
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct UsePEP585Annotation {
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for UsePEP585Annotation {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let UsePEP585Annotation { name } = self;
|
||||||
|
format!(
|
||||||
|
"Use `{}` instead of `{}` for type annotations",
|
||||||
|
name.to_lowercase(),
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
let UsePEP585Annotation { name } = self;
|
||||||
|
format!("Replace `{name}` with `{}`", name.to_lowercase(),)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// UP006
|
/// UP006
|
||||||
pub fn use_pep585_annotation(checker: &mut Checker, expr: &Expr) {
|
pub fn use_pep585_annotation(checker: &mut Checker, expr: &Expr) {
|
||||||
|
|
@ -13,7 +37,7 @@ pub fn use_pep585_annotation(checker: &mut Checker, expr: &Expr) {
|
||||||
.and_then(|call_path| call_path.last().copied())
|
.and_then(|call_path| call_path.last().copied())
|
||||||
{
|
{
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
violations::UsePEP585Annotation {
|
UsePEP585Annotation {
|
||||||
name: binding.to_string(),
|
name: binding.to_string(),
|
||||||
},
|
},
|
||||||
Range::from_located(expr),
|
Range::from_located(expr),
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Constant, Expr, ExprKind, Location, Operator};
|
use rustpython_ast::{Constant, Expr, ExprKind, Location, Operator};
|
||||||
|
|
||||||
use crate::ast::helpers::unparse_expr;
|
use crate::ast::helpers::unparse_expr;
|
||||||
|
|
@ -5,7 +8,20 @@ use crate::ast::types::Range;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::fix::Fix;
|
use crate::fix::Fix;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct UsePEP604Annotation;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for UsePEP604Annotation {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("Use `X | Y` for type annotations")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Convert to `X | Y`".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn optional(expr: &Expr) -> Expr {
|
fn optional(expr: &Expr) -> Expr {
|
||||||
Expr::new(
|
Expr::new(
|
||||||
|
|
@ -80,8 +96,7 @@ pub fn use_pep604_annotation(checker: &mut Checker, expr: &Expr, value: &Expr, s
|
||||||
|
|
||||||
match typing_member {
|
match typing_member {
|
||||||
TypingMember::Optional => {
|
TypingMember::Optional => {
|
||||||
let mut diagnostic =
|
let mut diagnostic = Diagnostic::new(UsePEP604Annotation, Range::from_located(expr));
|
||||||
Diagnostic::new(violations::UsePEP604Annotation, Range::from_located(expr));
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
diagnostic.amend(Fix::replacement(
|
diagnostic.amend(Fix::replacement(
|
||||||
unparse_expr(&optional(slice), checker.stylist),
|
unparse_expr(&optional(slice), checker.stylist),
|
||||||
|
|
@ -92,8 +107,7 @@ pub fn use_pep604_annotation(checker: &mut Checker, expr: &Expr, value: &Expr, s
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
TypingMember::Union => {
|
TypingMember::Union => {
|
||||||
let mut diagnostic =
|
let mut diagnostic = Diagnostic::new(UsePEP604Annotation, Range::from_located(expr));
|
||||||
Diagnostic::new(violations::UsePEP604Annotation, Range::from_located(expr));
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
match &slice.node {
|
match &slice.node {
|
||||||
ExprKind::Slice { .. } => {
|
ExprKind::Slice { .. } => {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,27 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
use log::error;
|
use log::error;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Expr, ExprKind, Stmt};
|
use rustpython_ast::{Expr, ExprKind, Stmt};
|
||||||
|
|
||||||
use crate::ast::types::Range;
|
use crate::ast::types::Range;
|
||||||
use crate::autofix::helpers;
|
use crate::autofix::helpers;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct UselessMetaclassType;
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for UselessMetaclassType {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("`__metaclass__ = type` is implied")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Remove `__metaclass__ = type`".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn rule(targets: &[Expr], value: &Expr, location: Range) -> Option<Diagnostic> {
|
fn rule(targets: &[Expr], value: &Expr, location: Range) -> Option<Diagnostic> {
|
||||||
if targets.len() != 1 {
|
if targets.len() != 1 {
|
||||||
|
|
@ -23,7 +39,7 @@ fn rule(targets: &[Expr], value: &Expr, location: Range) -> Option<Diagnostic> {
|
||||||
if id != "type" {
|
if id != "type" {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Some(Diagnostic::new(violations::UselessMetaclassType, location))
|
Some(Diagnostic::new(UselessMetaclassType, location))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// UP001
|
/// UP001
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,29 @@
|
||||||
|
use crate::define_violation;
|
||||||
|
use crate::violation::AlwaysAutofixableViolation;
|
||||||
|
use ruff_macros::derive_message_formats;
|
||||||
use rustpython_ast::{Expr, ExprKind, Keyword, Stmt};
|
use rustpython_ast::{Expr, ExprKind, Keyword, Stmt};
|
||||||
|
|
||||||
use super::super::fixes;
|
use super::super::fixes;
|
||||||
use crate::ast::types::{Binding, BindingKind, Range, Scope};
|
use crate::ast::types::{Binding, BindingKind, Range, Scope};
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::registry::Diagnostic;
|
use crate::registry::Diagnostic;
|
||||||
use crate::violations;
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct UselessObjectInheritance {
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
impl AlwaysAutofixableViolation for UselessObjectInheritance {
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let UselessObjectInheritance { name } = self;
|
||||||
|
format!("Class `{name}` inherits from `object`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn autofix_title(&self) -> String {
|
||||||
|
"Remove `object` inheritance".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn rule(name: &str, bases: &[Expr], scope: &Scope, bindings: &[Binding]) -> Option<Diagnostic> {
|
fn rule(name: &str, bases: &[Expr], scope: &Scope, bindings: &[Binding]) -> Option<Diagnostic> {
|
||||||
for expr in bases {
|
for expr in bases {
|
||||||
|
|
@ -27,7 +46,7 @@ fn rule(name: &str, bases: &[Expr], scope: &Scope, bindings: &[Binding]) -> Opti
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return Some(Diagnostic::new(
|
return Some(Diagnostic::new(
|
||||||
violations::UselessObjectInheritance {
|
UselessObjectInheritance {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
},
|
},
|
||||||
Range::from_located(expr),
|
Range::from_located(expr),
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::define_violation;
|
use crate::define_violation;
|
||||||
use crate::rules::flake8_debugger::types::DebuggerUsingType;
|
use crate::rules::flake8_debugger::types::DebuggerUsingType;
|
||||||
use crate::rules::pyupgrade::types::Primitive;
|
|
||||||
use crate::violation::{AlwaysAutofixableViolation, AutofixKind, Availability, Violation};
|
use crate::violation::{AlwaysAutofixableViolation, AutofixKind, Availability, Violation};
|
||||||
|
|
||||||
// pylint
|
// pylint
|
||||||
|
|
@ -1176,561 +1176,6 @@ impl Violation for UnpackInsteadOfConcatenatingToCollectionLiteral {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pyupgrade
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct UselessMetaclassType;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for UselessMetaclassType {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("`__metaclass__ = type` is implied")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Remove `__metaclass__ = type`".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct TypeOfPrimitive {
|
|
||||||
pub primitive: Primitive,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for TypeOfPrimitive {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let TypeOfPrimitive { primitive } = self;
|
|
||||||
format!("Use `{}` instead of `type(...)`", primitive.builtin())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
let TypeOfPrimitive { primitive } = self;
|
|
||||||
format!("Replace `type(...)` with `{}`", primitive.builtin())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct UselessObjectInheritance {
|
|
||||||
pub name: String,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for UselessObjectInheritance {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let UselessObjectInheritance { name } = self;
|
|
||||||
format!("Class `{name}` inherits from `object`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Remove `object` inheritance".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct DeprecatedUnittestAlias {
|
|
||||||
pub alias: String,
|
|
||||||
pub target: String,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for DeprecatedUnittestAlias {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let DeprecatedUnittestAlias { alias, target } = self;
|
|
||||||
format!("`{alias}` is deprecated, use `{target}`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
let DeprecatedUnittestAlias { alias, target } = self;
|
|
||||||
format!("Replace `{target}` with `{alias}`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct UsePEP585Annotation {
|
|
||||||
pub name: String,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for UsePEP585Annotation {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let UsePEP585Annotation { name } = self;
|
|
||||||
format!(
|
|
||||||
"Use `{}` instead of `{}` for type annotations",
|
|
||||||
name.to_lowercase(),
|
|
||||||
name,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
let UsePEP585Annotation { name } = self;
|
|
||||||
format!("Replace `{name}` with `{}`", name.to_lowercase(),)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct UsePEP604Annotation;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for UsePEP604Annotation {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Use `X | Y` for type annotations")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Convert to `X | Y`".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct SuperCallWithParameters;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for SuperCallWithParameters {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Use `super()` instead of `super(__class__, self)`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Remove `__super__` parameters".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct PEP3120UnnecessaryCodingComment;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for PEP3120UnnecessaryCodingComment {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("UTF-8 encoding declaration is unnecessary")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Remove unnecessary coding comment".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct UnnecessaryFutureImport {
|
|
||||||
pub names: Vec<String>,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for UnnecessaryFutureImport {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let UnnecessaryFutureImport { names } = self;
|
|
||||||
if names.len() == 1 {
|
|
||||||
let import = &names[0];
|
|
||||||
format!("Unnecessary `__future__` import `{import}` for target Python version")
|
|
||||||
} else {
|
|
||||||
let imports = names.iter().map(|name| format!("`{name}`")).join(", ");
|
|
||||||
format!("Unnecessary `__future__` imports {imports} for target Python version")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Remove unnecessary `__future__` import".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct LRUCacheWithoutParameters;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for LRUCacheWithoutParameters {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Unnecessary parameters to `functools.lru_cache`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Remove unnecessary parameters".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct UnnecessaryEncodeUTF8;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for UnnecessaryEncodeUTF8 {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Unnecessary call to `encode` as UTF-8")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Remove unnecessary `encode`".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct ConvertTypedDictFunctionalToClass {
|
|
||||||
pub name: String,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for ConvertTypedDictFunctionalToClass {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let ConvertTypedDictFunctionalToClass { name } = self;
|
|
||||||
format!("Convert `{name}` from `TypedDict` functional to class syntax")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
let ConvertTypedDictFunctionalToClass { name } = self;
|
|
||||||
format!("Convert `{name}` to class syntax")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct ConvertNamedTupleFunctionalToClass {
|
|
||||||
pub name: String,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for ConvertNamedTupleFunctionalToClass {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let ConvertNamedTupleFunctionalToClass { name } = self;
|
|
||||||
format!("Convert `{name}` from `NamedTuple` functional to class syntax")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
let ConvertNamedTupleFunctionalToClass { name } = self;
|
|
||||||
format!("Convert `{name}` to class syntax")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct RedundantOpenModes {
|
|
||||||
pub replacement: Option<String>,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for RedundantOpenModes {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let RedundantOpenModes { replacement } = self;
|
|
||||||
match replacement {
|
|
||||||
None => format!("Unnecessary open mode parameters"),
|
|
||||||
Some(replacement) => {
|
|
||||||
format!("Unnecessary open mode parameters, use \"{replacement}\"")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
let RedundantOpenModes { replacement } = self;
|
|
||||||
match replacement {
|
|
||||||
None => "Remove open mode parameters".to_string(),
|
|
||||||
Some(replacement) => {
|
|
||||||
format!("Replace with \"{replacement}\"")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct DatetimeTimezoneUTC {
|
|
||||||
pub straight_import: bool,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
impl Violation for DatetimeTimezoneUTC {
|
|
||||||
const AUTOFIX: Option<AutofixKind> = Some(AutofixKind::new(Availability::Always));
|
|
||||||
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Use `datetime.UTC` alias")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
|
|
||||||
if self.straight_import {
|
|
||||||
Some(|_| "Convert to `datetime.UTC` alias".to_string())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
pub enum LiteralType {
|
|
||||||
Str,
|
|
||||||
Bytes,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for LiteralType {
|
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
LiteralType::Str => fmt.write_str("str"),
|
|
||||||
LiteralType::Bytes => fmt.write_str("bytes"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct NativeLiterals {
|
|
||||||
pub literal_type: LiteralType,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for NativeLiterals {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let NativeLiterals { literal_type } = self;
|
|
||||||
format!("Unnecessary call to `{literal_type}`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
let NativeLiterals { literal_type } = self;
|
|
||||||
format!("Replace with `{literal_type}`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct TypingTextStrAlias;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for TypingTextStrAlias {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("`typing.Text` is deprecated, use `str`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Replace with `str`".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct OpenAlias;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for OpenAlias {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Use builtin `open`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Replace with builtin `open`".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct ReplaceUniversalNewlines;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for ReplaceUniversalNewlines {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("`universal_newlines` is deprecated, use `text`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Replace with `text` keyword argument".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct PrintfStringFormatting;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for PrintfStringFormatting {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Use format specifiers instead of percent format")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Replace with format specifiers".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct ReplaceStdoutStderr;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for ReplaceStdoutStderr {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Sending stdout and stderr to pipe is deprecated, use `capture_output`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Replace with `capture_output` keyword argument".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct RewriteCElementTree;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for RewriteCElementTree {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("`cElementTree` is deprecated, use `ElementTree`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Replace with `ElementTree`".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct OSErrorAlias {
|
|
||||||
pub name: Option<String>,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for OSErrorAlias {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Replace aliased errors with `OSError`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
let OSErrorAlias { name } = self;
|
|
||||||
match name {
|
|
||||||
None => "Replace with builtin `OSError`".to_string(),
|
|
||||||
Some(name) => format!("Replace `{name}` with builtin `OSError`"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct RewriteUnicodeLiteral;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for RewriteUnicodeLiteral {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Remove unicode literals from strings")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Remove unicode prefix".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
pub enum MockReference {
|
|
||||||
Import,
|
|
||||||
Attribute,
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct RewriteMockImport {
|
|
||||||
pub reference_type: MockReference,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for RewriteMockImport {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("`mock` is deprecated, use `unittest.mock`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
let RewriteMockImport { reference_type } = self;
|
|
||||||
match reference_type {
|
|
||||||
MockReference::Import => "Import from `unittest.mock` instead".to_string(),
|
|
||||||
MockReference::Attribute => "Replace `mock.mock` with `mock`".to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct RewriteListComprehension;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for RewriteListComprehension {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Replace unpacked list comprehension with a generator expression")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Replace with generator expression".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct RewriteYieldFrom;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for RewriteYieldFrom {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Replace `yield` over `for` loop with `yield from`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Replace with `yield from`".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct UnnecessaryBuiltinImport {
|
|
||||||
pub names: Vec<String>,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for UnnecessaryBuiltinImport {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
let UnnecessaryBuiltinImport { names } = self;
|
|
||||||
if names.len() == 1 {
|
|
||||||
let import = &names[0];
|
|
||||||
format!("Unnecessary builtin import: `{import}`")
|
|
||||||
} else {
|
|
||||||
let imports = names.iter().map(|name| format!("`{name}`")).join(", ");
|
|
||||||
format!("Unnecessary builtin imports: {imports}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Remove unnecessary builtin import".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct FormatLiterals;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for FormatLiterals {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Use implicit references for positional format fields")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Remove explicit positional indexes".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct ExtraneousParentheses;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for ExtraneousParentheses {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Avoid extraneous parentheses")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Remove extraneous parentheses".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct FString;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for FString {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Use f-string instead of `format` call")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Convert to f-string".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_violation!(
|
|
||||||
pub struct FunctoolsCache;
|
|
||||||
);
|
|
||||||
impl AlwaysAutofixableViolation for FunctoolsCache {
|
|
||||||
#[derive_message_formats]
|
|
||||||
fn message(&self) -> String {
|
|
||||||
format!("Use `@functools.cache` instead of `@functools.lru_cache(maxsize=None)`")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
|
||||||
"Rewrite with `@functools.cache".to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// pydocstyle
|
// pydocstyle
|
||||||
|
|
||||||
define_violation!(
|
define_violation!(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue