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,
|
||||
SIM401 => violations::DictGetWithDefault,
|
||||
// pyupgrade
|
||||
UP001 => violations::UselessMetaclassType,
|
||||
UP003 => violations::TypeOfPrimitive,
|
||||
UP004 => violations::UselessObjectInheritance,
|
||||
UP005 => violations::DeprecatedUnittestAlias,
|
||||
UP006 => violations::UsePEP585Annotation,
|
||||
UP007 => violations::UsePEP604Annotation,
|
||||
UP008 => violations::SuperCallWithParameters,
|
||||
UP009 => violations::PEP3120UnnecessaryCodingComment,
|
||||
UP010 => violations::UnnecessaryFutureImport,
|
||||
UP011 => violations::LRUCacheWithoutParameters,
|
||||
UP012 => violations::UnnecessaryEncodeUTF8,
|
||||
UP013 => violations::ConvertTypedDictFunctionalToClass,
|
||||
UP014 => violations::ConvertNamedTupleFunctionalToClass,
|
||||
UP015 => violations::RedundantOpenModes,
|
||||
UP017 => violations::DatetimeTimezoneUTC,
|
||||
UP018 => violations::NativeLiterals,
|
||||
UP019 => violations::TypingTextStrAlias,
|
||||
UP020 => violations::OpenAlias,
|
||||
UP021 => violations::ReplaceUniversalNewlines,
|
||||
UP022 => violations::ReplaceStdoutStderr,
|
||||
UP023 => violations::RewriteCElementTree,
|
||||
UP024 => violations::OSErrorAlias,
|
||||
UP025 => violations::RewriteUnicodeLiteral,
|
||||
UP026 => violations::RewriteMockImport,
|
||||
UP027 => violations::RewriteListComprehension,
|
||||
UP028 => violations::RewriteYieldFrom,
|
||||
UP029 => violations::UnnecessaryBuiltinImport,
|
||||
UP030 => violations::FormatLiterals,
|
||||
UP031 => violations::PrintfStringFormatting,
|
||||
UP032 => violations::FString,
|
||||
UP033 => violations::FunctoolsCache,
|
||||
UP034 => violations::ExtraneousParentheses,
|
||||
UP001 => rules::pyupgrade::rules::UselessMetaclassType,
|
||||
UP003 => rules::pyupgrade::rules::TypeOfPrimitive,
|
||||
UP004 => rules::pyupgrade::rules::UselessObjectInheritance,
|
||||
UP005 => rules::pyupgrade::rules::DeprecatedUnittestAlias,
|
||||
UP006 => rules::pyupgrade::rules::UsePEP585Annotation,
|
||||
UP007 => rules::pyupgrade::rules::UsePEP604Annotation,
|
||||
UP008 => rules::pyupgrade::rules::SuperCallWithParameters,
|
||||
UP009 => rules::pyupgrade::rules::PEP3120UnnecessaryCodingComment,
|
||||
UP010 => rules::pyupgrade::rules::UnnecessaryFutureImport,
|
||||
UP011 => rules::pyupgrade::rules::LRUCacheWithoutParameters,
|
||||
UP012 => rules::pyupgrade::rules::UnnecessaryEncodeUTF8,
|
||||
UP013 => rules::pyupgrade::rules::ConvertTypedDictFunctionalToClass,
|
||||
UP014 => rules::pyupgrade::rules::ConvertNamedTupleFunctionalToClass,
|
||||
UP015 => rules::pyupgrade::rules::RedundantOpenModes,
|
||||
UP017 => rules::pyupgrade::rules::DatetimeTimezoneUTC,
|
||||
UP018 => rules::pyupgrade::rules::NativeLiterals,
|
||||
UP019 => rules::pyupgrade::rules::TypingTextStrAlias,
|
||||
UP020 => rules::pyupgrade::rules::OpenAlias,
|
||||
UP021 => rules::pyupgrade::rules::ReplaceUniversalNewlines,
|
||||
UP022 => rules::pyupgrade::rules::ReplaceStdoutStderr,
|
||||
UP023 => rules::pyupgrade::rules::RewriteCElementTree,
|
||||
UP024 => rules::pyupgrade::rules::OSErrorAlias,
|
||||
UP025 => rules::pyupgrade::rules::RewriteUnicodeLiteral,
|
||||
UP026 => rules::pyupgrade::rules::RewriteMockImport,
|
||||
UP027 => rules::pyupgrade::rules::RewriteListComprehension,
|
||||
UP028 => rules::pyupgrade::rules::RewriteYieldFrom,
|
||||
UP029 => rules::pyupgrade::rules::UnnecessaryBuiltinImport,
|
||||
UP030 => rules::pyupgrade::rules::FormatLiterals,
|
||||
UP031 => rules::pyupgrade::rules::PrintfStringFormatting,
|
||||
UP032 => rules::pyupgrade::rules::FString,
|
||||
UP033 => rules::pyupgrade::rules::FunctoolsCache,
|
||||
UP034 => rules::pyupgrade::rules::ExtraneousParentheses,
|
||||
UP035 => rules::pyupgrade::rules::ImportReplacements,
|
||||
UP036 => rules::pyupgrade::rules::OutdatedVersionBlock,
|
||||
// pydocstyle
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use anyhow::{bail, Result};
|
||||
use log::debug;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind};
|
||||
|
||||
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::registry::Diagnostic;
|
||||
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.
|
||||
fn match_named_tuple_assign<'a>(
|
||||
|
|
@ -154,7 +174,7 @@ pub fn convert_named_tuple_functional_to_class(
|
|||
return;
|
||||
};
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::ConvertNamedTupleFunctionalToClass {
|
||||
ConvertNamedTupleFunctionalToClass {
|
||||
name: typename.to_string(),
|
||||
},
|
||||
Range::from_located(stmt),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use anyhow::{bail, Result};
|
||||
use log::debug;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind};
|
||||
|
||||
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::registry::Diagnostic;
|
||||
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`
|
||||
/// assignment.
|
||||
|
|
@ -201,7 +221,7 @@ pub fn convert_typed_dict_functional_to_class(
|
|||
};
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::ConvertTypedDictFunctionalToClass {
|
||||
ConvertTypedDictFunctionalToClass {
|
||||
name: class_name.to_string(),
|
||||
},
|
||||
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 crate::ast::helpers::collect_call_path;
|
||||
|
|
@ -5,7 +8,28 @@ use crate::ast::types::Range;
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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
|
||||
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 mut diagnostic = Diagnostic::new(
|
||||
violations::DatetimeTimezoneUTC { straight_import },
|
||||
DatetimeTimezoneUTC { straight_import },
|
||||
Range::from_located(expr),
|
||||
);
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use once_cell::sync::Lazy;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustpython_ast::{Expr, ExprKind};
|
||||
|
||||
|
|
@ -6,7 +9,25 @@ use crate::ast::types::Range;
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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(|| {
|
||||
FxHashMap::from_iter([
|
||||
|
|
@ -43,7 +64,7 @@ pub fn deprecated_unittest_alias(checker: &mut Checker, expr: &Expr) {
|
|||
return;
|
||||
}
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::DeprecatedUnittestAlias {
|
||||
DeprecatedUnittestAlias {
|
||||
alias: attr.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 crate::ast::types::Range;
|
||||
|
|
@ -5,7 +8,20 @@ use crate::fix::Fix;
|
|||
use crate::registry::{Diagnostic, Rule};
|
||||
use crate::settings::{flags, Settings};
|
||||
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
|
||||
fn match_extraneous_parentheses(tokens: &[LexResult], mut i: usize) -> Option<(usize, usize)> {
|
||||
|
|
@ -120,7 +136,7 @@ pub fn extraneous_parentheses(
|
|||
return diagnostics;
|
||||
};
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(violations::ExtraneousParentheses, Range::new(*start, *end));
|
||||
Diagnostic::new(ExtraneousParentheses, Range::new(*start, *end));
|
||||
if matches!(autofix, flags::Autofix::Enabled)
|
||||
&& 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 rustpython_ast::{Constant, Expr, ExprKind, KeywordData};
|
||||
use rustpython_common::format::{
|
||||
|
|
@ -13,7 +16,20 @@ use crate::registry::Diagnostic;
|
|||
use crate::rules::pydocstyle::helpers::{leading_quote, trailing_quote};
|
||||
use crate::rules::pyflakes::format::FormatSummary;
|
||||
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
|
||||
/// 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;
|
||||
}
|
||||
|
||||
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()) {
|
||||
diagnostic.amend(Fix::replacement(
|
||||
contents,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use libcst_native::{Arg, Codegen, CodegenState, Expression};
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::Expr;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
|
|
@ -11,7 +14,20 @@ use crate::fix::Fix;
|
|||
use crate::registry::Diagnostic;
|
||||
use crate::rules::pyflakes::format::FormatSummary;
|
||||
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,
|
||||
// followed by a closing brace.
|
||||
|
|
@ -112,7 +128,7 @@ pub(crate) fn format_literals(checker: &mut Checker, summary: &FormatSummary, ex
|
|||
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()) {
|
||||
// Currently, the only issue we know of is in LibCST:
|
||||
// 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_parser::ast::Expr;
|
||||
|
||||
|
|
@ -6,7 +9,20 @@ use crate::ast::types::Range;
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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
|
||||
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(
|
||||
violations::FunctoolsCache,
|
||||
FunctoolsCache,
|
||||
Range::new(func.end_location.unwrap(), expr.end_location.unwrap()),
|
||||
);
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use itertools::Itertools;
|
||||
use rustpython_ast::{Alias, AliasData, Stmt};
|
||||
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Alias, AliasData, Stmt};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
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_parser::ast::Expr;
|
||||
|
||||
|
|
@ -6,7 +9,20 @@ use crate::ast::types::Range;
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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
|
||||
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(
|
||||
violations::LRUCacheWithoutParameters,
|
||||
LRUCacheWithoutParameters,
|
||||
Range::new(func.end_location.unwrap(), expr.end_location.unwrap()),
|
||||
);
|
||||
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_typed_dict_functional_to_class::convert_typed_dict_functional_to_class;
|
||||
pub(crate) use datetime_utc_alias::datetime_utc_alias;
|
||||
pub(crate) use deprecated_unittest_alias::deprecated_unittest_alias;
|
||||
pub(crate) use extraneous_parentheses::extraneous_parentheses;
|
||||
pub(crate) use f_strings::f_strings;
|
||||
pub(crate) use format_literals::format_literals;
|
||||
pub(crate) use functools_cache::functools_cache;
|
||||
pub(crate) use convert_named_tuple_functional_to_class::{
|
||||
convert_named_tuple_functional_to_class, ConvertNamedTupleFunctionalToClass,
|
||||
};
|
||||
pub(crate) use convert_typed_dict_functional_to_class::{
|
||||
convert_typed_dict_functional_to_class, ConvertTypedDictFunctionalToClass,
|
||||
};
|
||||
pub(crate) use datetime_utc_alias::{datetime_utc_alias, DatetimeTimezoneUTC};
|
||||
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 lru_cache_without_parameters::lru_cache_without_parameters;
|
||||
pub(crate) use native_literals::native_literals;
|
||||
pub(crate) use open_alias::open_alias;
|
||||
pub(crate) use os_error_alias::os_error_alias;
|
||||
pub(crate) use lru_cache_without_parameters::{
|
||||
lru_cache_without_parameters, LRUCacheWithoutParameters,
|
||||
};
|
||||
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 printf_string_formatting::printf_string_formatting;
|
||||
pub(crate) use redundant_open_modes::redundant_open_modes;
|
||||
pub(crate) use replace_stdout_stderr::replace_stdout_stderr;
|
||||
pub(crate) use replace_universal_newlines::replace_universal_newlines;
|
||||
pub(crate) use rewrite_c_element_tree::replace_c_element_tree;
|
||||
pub(crate) use rewrite_mock_import::{rewrite_mock_attribute, rewrite_mock_import};
|
||||
pub(crate) use rewrite_unicode_literal::rewrite_unicode_literal;
|
||||
pub(crate) use rewrite_yield_from::rewrite_yield_from;
|
||||
pub(crate) use printf_string_formatting::{printf_string_formatting, PrintfStringFormatting};
|
||||
pub(crate) use redundant_open_modes::{redundant_open_modes, RedundantOpenModes};
|
||||
pub(crate) use replace_stdout_stderr::{replace_stdout_stderr, ReplaceStdoutStderr};
|
||||
pub(crate) use replace_universal_newlines::{replace_universal_newlines, ReplaceUniversalNewlines};
|
||||
pub(crate) use rewrite_c_element_tree::{replace_c_element_tree, RewriteCElementTree};
|
||||
pub(crate) use rewrite_mock_import::{
|
||||
rewrite_mock_attribute, rewrite_mock_import, RewriteMockImport,
|
||||
};
|
||||
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_call_with_parameters::super_call_with_parameters;
|
||||
pub(crate) use type_of_primitive::type_of_primitive;
|
||||
pub(crate) use typing_text_str_alias::typing_text_str_alias;
|
||||
pub(crate) use unnecessary_builtin_import::unnecessary_builtin_import;
|
||||
pub(crate) use unnecessary_coding_comment::unnecessary_coding_comment;
|
||||
pub(crate) use unnecessary_encode_utf8::unnecessary_encode_utf8;
|
||||
pub(crate) use unnecessary_future_import::unnecessary_future_import;
|
||||
pub(crate) use unpack_list_comprehension::unpack_list_comprehension;
|
||||
pub(crate) use use_pep585_annotation::use_pep585_annotation;
|
||||
pub(crate) use use_pep604_annotation::use_pep604_annotation;
|
||||
pub(crate) use useless_metaclass_type::useless_metaclass_type;
|
||||
pub(crate) use useless_object_inheritance::useless_object_inheritance;
|
||||
pub(crate) use super_call_with_parameters::{super_call_with_parameters, SuperCallWithParameters};
|
||||
pub(crate) use type_of_primitive::{type_of_primitive, TypeOfPrimitive};
|
||||
pub(crate) use typing_text_str_alias::{typing_text_str_alias, TypingTextStrAlias};
|
||||
pub(crate) use unnecessary_builtin_import::{unnecessary_builtin_import, UnnecessaryBuiltinImport};
|
||||
pub(crate) use unnecessary_coding_comment::{
|
||||
unnecessary_coding_comment, PEP3120UnnecessaryCodingComment,
|
||||
};
|
||||
pub(crate) use unnecessary_encode_utf8::{unnecessary_encode_utf8, UnnecessaryEncodeUTF8};
|
||||
pub(crate) use unnecessary_future_import::{unnecessary_future_import, UnnecessaryFutureImport};
|
||||
pub(crate) use unpack_list_comprehension::{unpack_list_comprehension, RewriteListComprehension};
|
||||
pub(crate) use use_pep585_annotation::{use_pep585_annotation, UsePEP585Annotation};
|
||||
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_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_parser::lexer;
|
||||
use rustpython_parser::lexer::Tok;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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
|
||||
pub fn native_literals(
|
||||
|
|
@ -25,7 +61,7 @@ pub fn native_literals(
|
|||
|
||||
if (id == "str" || id == "bytes") && checker.is_builtin(id) {
|
||||
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
|
||||
} else {
|
||||
LiteralType::Bytes
|
||||
|
|
@ -94,7 +130,7 @@ pub fn native_literals(
|
|||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::NativeLiterals {
|
||||
NativeLiterals {
|
||||
literal_type: if id == "str" {
|
||||
LiteralType::Str
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,26 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::Expr;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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
|
||||
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)
|
||||
.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()) {
|
||||
diagnostic.amend(Fix::replacement(
|
||||
"open".to_string(),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use itertools::Itertools;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Excepthandler, ExcepthandlerKind, Expr, ExprKind, Located};
|
||||
|
||||
use crate::ast::helpers::compose_call_path;
|
||||
|
|
@ -6,7 +9,26 @@ use crate::ast::types::Range;
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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_MODULES: &[&str] = &["mmap", "select", "socket"];
|
||||
|
|
@ -145,7 +167,7 @@ fn handle_making_changes(
|
|||
final_str.push(')');
|
||||
}
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::OSErrorAlias {
|
||||
OSErrorAlias {
|
||||
name: compose_call_path(target),
|
||||
},
|
||||
Range::from_located(target),
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use ruff_macros::derive_message_formats;
|
||||
|
||||
use std::cmp::Ordering;
|
||||
|
||||
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::Tok;
|
||||
|
||||
use ruff_macros::derive_message_formats;
|
||||
|
||||
use crate::ast::types::{Range, RefEquality};
|
||||
use crate::ast::whitespace::indentation;
|
||||
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 rustpython_ast::Location;
|
||||
|
|
@ -17,7 +21,20 @@ use crate::python::keyword::KWLIST;
|
|||
use crate::registry::Diagnostic;
|
||||
use crate::rules::pydocstyle::helpers::{leading_quote, trailing_quote};
|
||||
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 {
|
||||
let mut flag_string = String::new();
|
||||
|
|
@ -406,10 +423,7 @@ pub(crate) fn printf_string_formatting(
|
|||
// Add the `.format` call.
|
||||
contents.push_str(&format!(".format{params_string}"));
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::PrintfStringFormatting,
|
||||
Range::from_located(expr),
|
||||
);
|
||||
let mut diagnostic = Diagnostic::new(PrintfStringFormatting, Range::from_located(expr));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.amend(Fix::replacement(
|
||||
contents,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
|
|
@ -12,7 +16,34 @@ use crate::checkers::ast::Checker;
|
|||
use crate::fix::Fix;
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
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 MODE_KEYWORD_ARGUMENT: &str = "mode";
|
||||
|
|
@ -81,7 +112,7 @@ fn create_check(
|
|||
patch: bool,
|
||||
) -> Diagnostic {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::RedundantOpenModes {
|
||||
RedundantOpenModes {
|
||||
replacement: replacement_value.clone(),
|
||||
},
|
||||
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 crate::ast::helpers::find_keyword;
|
||||
|
|
@ -7,7 +10,20 @@ use crate::checkers::ast::Checker;
|
|||
use crate::fix::Fix;
|
||||
use crate::registry::Diagnostic;
|
||||
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)]
|
||||
struct MiddleContent<'a> {
|
||||
|
|
@ -116,8 +132,7 @@ pub fn replace_stdout_stderr(checker: &mut Checker, expr: &Expr, kwargs: &[Keywo
|
|||
return;
|
||||
}
|
||||
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(violations::ReplaceStdoutStderr, Range::from_located(expr));
|
||||
let mut diagnostic = Diagnostic::new(ReplaceStdoutStderr, Range::from_located(expr));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
if let Some(fix) = generate_fix(checker.stylist, checker.locator, stdout, stderr) {
|
||||
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 crate::ast::helpers::find_keyword;
|
||||
|
|
@ -5,7 +8,20 @@ use crate::ast::types::Range;
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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
|
||||
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(),
|
||||
),
|
||||
);
|
||||
let mut diagnostic = Diagnostic::new(violations::ReplaceUniversalNewlines, range);
|
||||
let mut diagnostic = Diagnostic::new(ReplaceUniversalNewlines, range);
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.amend(Fix::replacement(
|
||||
"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 crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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>) {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(violations::RewriteCElementTree, Range::from_located(node));
|
||||
let mut diagnostic = Diagnostic::new(RewriteCElementTree, Range::from_located(node));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
let contents = checker
|
||||
.locator
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use anyhow::Result;
|
||||
use libcst_native::{
|
||||
AsName, AssignTargetExpression, Attribute, Codegen, CodegenState, Dot, Expression, Import,
|
||||
ImportAlias, ImportFrom, ImportNames, Name, NameOrAttribute, ParenthesizableWhitespace,
|
||||
};
|
||||
use log::error;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Expr, ExprKind, Stmt, StmtKind};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::ast::helpers::collect_call_path;
|
||||
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::registry::{Diagnostic, Rule};
|
||||
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.
|
||||
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 collect_call_path(value).as_slice() == ["mock", "mock"] {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::RewriteMockImport {
|
||||
RewriteMockImport {
|
||||
reference_type: MockReference::Attribute,
|
||||
},
|
||||
Range::from_located(value),
|
||||
|
|
@ -256,7 +284,7 @@ pub fn rewrite_mock_import(checker: &mut Checker, stmt: &Stmt) {
|
|||
for name in names {
|
||||
if name.node.name == "mock" || name.node.name == "mock.mock" {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::RewriteMockImport {
|
||||
RewriteMockImport {
|
||||
reference_type: MockReference::Import,
|
||||
},
|
||||
Range::from_located(name),
|
||||
|
|
@ -284,7 +312,7 @@ pub fn rewrite_mock_import(checker: &mut Checker, stmt: &Stmt) {
|
|||
|
||||
if module == "mock" {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::RewriteMockImport {
|
||||
RewriteMockImport {
|
||||
reference_type: MockReference::Import,
|
||||
},
|
||||
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 crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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
|
||||
pub fn rewrite_unicode_literal(checker: &mut Checker, expr: &Expr, kind: Option<&str>) {
|
||||
if let Some(const_kind) = kind {
|
||||
if const_kind.to_lowercase() == "u" {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(violations::RewriteUnicodeLiteral, Range::from_located(expr));
|
||||
let mut diagnostic = Diagnostic::new(RewriteUnicodeLiteral, Range::from_located(expr));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.amend(Fix::deletion(
|
||||
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 rustpython_ast::{Expr, ExprContext, ExprKind, Stmt, StmtKind};
|
||||
|
||||
|
|
@ -7,7 +10,20 @@ use crate::ast::visitor::Visitor;
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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
|
||||
/// of tuples and names.
|
||||
|
|
@ -157,8 +173,7 @@ pub fn rewrite_yield_from(checker: &mut Checker, stmt: &Stmt) {
|
|||
continue;
|
||||
}
|
||||
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(violations::RewriteYieldFrom, Range::from_located(item.stmt));
|
||||
let mut diagnostic = Diagnostic::new(RewriteYieldFrom, Range::from_located(item.stmt));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
let contents = checker
|
||||
.locator
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
use crate::ast::helpers;
|
||||
use crate::ast::types::{Range, Scope, ScopeKind};
|
||||
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
|
||||
use crate::rules::pyupgrade::rules::SuperCallWithParameters;
|
||||
|
||||
use rustpython_ast::{ArgData, Expr, ExprKind, Stmt, StmtKind};
|
||||
|
||||
/// UP008
|
||||
|
|
@ -68,7 +71,7 @@ pub fn super_args(
|
|||
|
||||
if first_arg_id == parent_name && second_arg_id == parent_arg {
|
||||
return Some(Diagnostic::new(
|
||||
violations::SuperCallWithParameters,
|
||||
SuperCallWithParameters,
|
||||
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 super::super::fixes;
|
||||
use crate::ast::helpers;
|
||||
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
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Expr, ExprKind};
|
||||
|
||||
use super::super::types::Primitive;
|
||||
|
|
@ -5,7 +8,24 @@ use crate::ast::types::Range;
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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
|
||||
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 {
|
||||
return;
|
||||
};
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::TypeOfPrimitive { primitive },
|
||||
Range::from_located(expr),
|
||||
);
|
||||
let mut diagnostic = Diagnostic::new(TypeOfPrimitive { primitive }, Range::from_located(expr));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.amend(Fix::replacement(
|
||||
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 crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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
|
||||
pub fn typing_text_str_alias(checker: &mut Checker, expr: &Expr) {
|
||||
if checker.resolve_call_path(expr).map_or(false, |call_path| {
|
||||
call_path.as_slice() == ["typing", "Text"]
|
||||
}) {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(violations::TypingTextStrAlias, Range::from_located(expr));
|
||||
let mut diagnostic = Diagnostic::new(TypingTextStrAlias, Range::from_located(expr));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.amend(Fix::replacement(
|
||||
"str".to_string(),
|
||||
|
|
|
|||
|
|
@ -1,12 +1,38 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use itertools::Itertools;
|
||||
use log::error;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Alias, AliasData, Located};
|
||||
use rustpython_parser::ast::Stmt;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::autofix;
|
||||
use crate::checkers::ast::Checker;
|
||||
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] = &[
|
||||
"*",
|
||||
|
|
@ -69,7 +95,7 @@ pub fn unnecessary_builtin_import(
|
|||
return;
|
||||
}
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::UnnecessaryBuiltinImport {
|
||||
UnnecessaryBuiltinImport {
|
||||
names: unused_imports
|
||||
.iter()
|
||||
.map(|alias| alias.node.name.to_string())
|
||||
|
|
|
|||
|
|
@ -1,11 +1,28 @@
|
|||
use crate::ast::types::Range;
|
||||
use crate::define_violation;
|
||||
use crate::fix::Fix;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::violations;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use ruff_macros::derive_message_formats;
|
||||
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.
|
||||
static CODING_COMMENT_REGEX: Lazy<Regex> =
|
||||
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.
|
||||
if CODING_COMMENT_REGEX.is_match(line) {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::PEP3120UnnecessaryCodingComment,
|
||||
PEP3120UnnecessaryCodingComment,
|
||||
Range::new(Location::new(lineno + 1, 0), Location::new(lineno + 2, 0)),
|
||||
);
|
||||
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 crate::ast::types::Range;
|
||||
|
|
@ -5,7 +8,20 @@ use crate::checkers::ast::Checker;
|
|||
use crate::fix::Fix;
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
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"];
|
||||
|
||||
|
|
@ -60,15 +76,13 @@ fn delete_default_encode_arg_or_kwarg(
|
|||
patch: bool,
|
||||
) -> Option<Diagnostic> {
|
||||
if let Some(arg) = args.get(0) {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(violations::UnnecessaryEncodeUTF8, Range::from_located(expr));
|
||||
let mut diagnostic = Diagnostic::new(UnnecessaryEncodeUTF8, Range::from_located(expr));
|
||||
if patch {
|
||||
diagnostic.amend(Fix::deletion(arg.location, arg.end_location.unwrap()));
|
||||
}
|
||||
Some(diagnostic)
|
||||
} else if let Some(kwarg) = kwargs.get(0) {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(violations::UnnecessaryEncodeUTF8, Range::from_located(expr));
|
||||
let mut diagnostic = Diagnostic::new(UnnecessaryEncodeUTF8, Range::from_located(expr));
|
||||
if patch {
|
||||
diagnostic.amend(Fix::deletion(kwarg.location, kwarg.end_location.unwrap()));
|
||||
}
|
||||
|
|
@ -85,8 +99,7 @@ fn replace_with_bytes_literal(
|
|||
locator: &Locator,
|
||||
patch: bool,
|
||||
) -> Diagnostic {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(violations::UnnecessaryEncodeUTF8, Range::from_located(expr));
|
||||
let mut diagnostic = Diagnostic::new(UnnecessaryEncodeUTF8, Range::from_located(expr));
|
||||
if patch {
|
||||
let content = locator.slice_source_code_range(&Range::new(
|
||||
constant.location,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,38 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use itertools::Itertools;
|
||||
use log::error;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Alias, AliasData, Located};
|
||||
use rustpython_parser::ast::Stmt;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::autofix;
|
||||
use crate::checkers::ast::Checker;
|
||||
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] = &[
|
||||
"nested_scopes",
|
||||
|
|
@ -49,7 +75,7 @@ pub fn unnecessary_future_import(checker: &mut Checker, stmt: &Stmt, names: &[Lo
|
|||
return;
|
||||
}
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::UnnecessaryFutureImport {
|
||||
UnnecessaryFutureImport {
|
||||
names: unused_imports
|
||||
.iter()
|
||||
.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 crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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`.
|
||||
fn contains_await(expr: &Expr) -> bool {
|
||||
|
|
@ -79,10 +95,8 @@ pub fn unpack_list_comprehension(checker: &mut Checker, targets: &[Expr], value:
|
|||
return;
|
||||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::RewriteListComprehension,
|
||||
Range::from_located(value),
|
||||
);
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(RewriteListComprehension, Range::from_located(value));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
let existing = checker
|
||||
.locator
|
||||
|
|
|
|||
|
|
@ -1,10 +1,34 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::Expr;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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
|
||||
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())
|
||||
{
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
violations::UsePEP585Annotation {
|
||||
UsePEP585Annotation {
|
||||
name: binding.to_string(),
|
||||
},
|
||||
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 crate::ast::helpers::unparse_expr;
|
||||
|
|
@ -5,7 +8,20 @@ use crate::ast::types::Range;
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::Fix;
|
||||
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 {
|
||||
Expr::new(
|
||||
|
|
@ -80,8 +96,7 @@ pub fn use_pep604_annotation(checker: &mut Checker, expr: &Expr, value: &Expr, s
|
|||
|
||||
match typing_member {
|
||||
TypingMember::Optional => {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(violations::UsePEP604Annotation, Range::from_located(expr));
|
||||
let mut diagnostic = Diagnostic::new(UsePEP604Annotation, Range::from_located(expr));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.amend(Fix::replacement(
|
||||
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);
|
||||
}
|
||||
TypingMember::Union => {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(violations::UsePEP604Annotation, Range::from_located(expr));
|
||||
let mut diagnostic = Diagnostic::new(UsePEP604Annotation, Range::from_located(expr));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
match &slice.node {
|
||||
ExprKind::Slice { .. } => {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,27 @@
|
|||
use crate::define_violation;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use log::error;
|
||||
use ruff_macros::derive_message_formats;
|
||||
use rustpython_ast::{Expr, ExprKind, Stmt};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::autofix::helpers;
|
||||
use crate::checkers::ast::Checker;
|
||||
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> {
|
||||
if targets.len() != 1 {
|
||||
|
|
@ -23,7 +39,7 @@ fn rule(targets: &[Expr], value: &Expr, location: Range) -> Option<Diagnostic> {
|
|||
if id != "type" {
|
||||
return None;
|
||||
}
|
||||
Some(Diagnostic::new(violations::UselessMetaclassType, location))
|
||||
Some(Diagnostic::new(UselessMetaclassType, location))
|
||||
}
|
||||
|
||||
/// 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 super::super::fixes;
|
||||
use crate::ast::types::{Binding, BindingKind, Range, Scope};
|
||||
use crate::checkers::ast::Checker;
|
||||
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> {
|
||||
for expr in bases {
|
||||
|
|
@ -27,7 +46,7 @@ fn rule(name: &str, bases: &[Expr], scope: &Scope, bindings: &[Binding]) -> Opti
|
|||
continue;
|
||||
}
|
||||
return Some(Diagnostic::new(
|
||||
violations::UselessObjectInheritance {
|
||||
UselessObjectInheritance {
|
||||
name: name.to_string(),
|
||||
},
|
||||
Range::from_located(expr),
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::define_violation;
|
||||
use crate::rules::flake8_debugger::types::DebuggerUsingType;
|
||||
use crate::rules::pyupgrade::types::Primitive;
|
||||
|
||||
use crate::violation::{AlwaysAutofixableViolation, AutofixKind, Availability, Violation};
|
||||
|
||||
// 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
|
||||
|
||||
define_violation!(
|
||||
|
|
|
|||
Loading…
Reference in New Issue