Remove functor from autofix title (#4245)

This commit is contained in:
Micha Reiser 2023-05-10 09:21:15 +02:00 committed by GitHub
parent 8969ad5879
commit a2b8487ae3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
61 changed files with 234 additions and 305 deletions

View file

@ -65,18 +65,12 @@ impl Violation for UnusedLoopControlVariable {
}
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
let UnusedLoopControlVariable {
certainty, rename, ..
} = self;
if certainty.to_bool() && rename.is_some() {
Some(|UnusedLoopControlVariable { name, rename, .. }| {
let rename = rename.as_ref().unwrap();
format!("Rename unused `{name}` to `{rename}`")
})
} else {
None
}
fn autofix_title(&self) -> Option<String> {
let UnusedLoopControlVariable { rename, name, .. } = self;
rename
.as_ref()
.map(|rename| format!("Rename unused `{name}` to `{rename}`"))
}
}

View file

@ -65,6 +65,7 @@ B007.py:34:10: B007 Loop control variable `bar` may not be used within loop body
36 | if foo:
37 | print(FMT.format(**locals()))
|
= help: Rename unused `bar` to `_bar`
B007.py:38:10: B007 Loop control variable `bar` may not be used within loop body
|
@ -75,6 +76,7 @@ B007.py:38:10: B007 Loop control variable `bar` may not be used within loop body
41 | if foo:
42 | print(FMT.format(**globals()))
|
= help: Rename unused `bar` to `_bar`
B007.py:42:10: B007 Loop control variable `bar` may not be used within loop body
|
@ -85,6 +87,7 @@ B007.py:42:10: B007 Loop control variable `bar` may not be used within loop body
45 | if foo:
46 | print(FMT.format(**vars()))
|
= help: Rename unused `bar` to `_bar`
B007.py:46:10: B007 Loop control variable `bar` may not be used within loop body
|
@ -94,6 +97,7 @@ B007.py:46:10: B007 Loop control variable `bar` may not be used within loop body
| ^^^ B007
49 | print(FMT.format(foo=foo, bar=eval("bar")))
|
= help: Rename unused `bar` to `_bar`
B007.py:52:14: B007 [*] Loop control variable `bar` not used within loop body
|

View file

@ -50,8 +50,8 @@ impl Violation for UnnecessaryComprehensionAnyAll {
format!("Unnecessary list comprehension.")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
Some(|_| "Remove unnecessary list comprehension".to_string())
fn autofix_title(&self) -> Option<String> {
Some("Remove unnecessary list comprehension".to_string())
}
}

View file

@ -56,13 +56,12 @@ impl Violation for UnnecessaryMap {
}
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
Some(|UnnecessaryMap { obj_type }| {
if obj_type == "generator" {
fn autofix_title(&self) -> Option<String> {
let UnnecessaryMap { obj_type } = self;
Some(if obj_type == "generator" {
format!("Replace `map` using a generator expression")
} else {
format!("Replace `map` using a `{obj_type}` comprehension")
}
})
}
}

View file

@ -47,9 +47,7 @@ use crate::registry::{AsRule, Rule};
/// RuntimeError: 'Some value' is incorrect
/// ```
#[violation]
pub struct RawStringInException {
fixable: bool,
}
pub struct RawStringInException;
impl Violation for RawStringInException {
const AUTOFIX: AutofixKind = AutofixKind::Sometimes;
@ -59,9 +57,8 @@ impl Violation for RawStringInException {
format!("Exception must not use a string literal, assign to variable first")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|_| format!("Assign to variable; remove string literal"))
fn autofix_title(&self) -> Option<String> {
Some("Assign to variable; remove string literal".to_string())
}
}
@ -104,9 +101,7 @@ impl Violation for RawStringInException {
/// RuntimeError: 'Some value' is incorrect
/// ```
#[violation]
pub struct FStringInException {
fixable: bool,
}
pub struct FStringInException;
impl Violation for FStringInException {
const AUTOFIX: AutofixKind = AutofixKind::Sometimes;
@ -116,9 +111,8 @@ impl Violation for FStringInException {
format!("Exception must not use an f-string literal, assign to variable first")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|_| format!("Assign to variable; remove f-string literal"))
fn autofix_title(&self) -> Option<String> {
Some("Assign to variable; remove f-string literal".to_string())
}
}
@ -163,9 +157,7 @@ impl Violation for FStringInException {
/// RuntimeError: 'Some value' is incorrect
/// ```
#[violation]
pub struct DotFormatInException {
fixable: bool,
}
pub struct DotFormatInException;
impl Violation for DotFormatInException {
const AUTOFIX: AutofixKind = AutofixKind::Sometimes;
@ -175,9 +167,8 @@ impl Violation for DotFormatInException {
format!("Exception must not use a `.format()` string directly, assign to variable first")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|_| format!("Assign to variable; remove `.format()` string"))
fn autofix_title(&self) -> Option<String> {
Some("Assign to variable; remove `.format()` string".to_string())
}
}
@ -241,12 +232,8 @@ pub fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr) {
None
}
});
let mut diagnostic = Diagnostic::new(
RawStringInException {
fixable: indentation.is_some(),
},
first.range(),
);
let mut diagnostic =
Diagnostic::new(RawStringInException, first.range());
if let Some(indentation) = indentation {
if checker.patch(diagnostic.kind.rule()) {
diagnostic.set_fix(generate_fix(
@ -273,12 +260,7 @@ pub fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr) {
}
},
);
let mut diagnostic = Diagnostic::new(
FStringInException {
fixable: indentation.is_some(),
},
first.range(),
);
let mut diagnostic = Diagnostic::new(FStringInException, first.range());
if let Some(indentation) = indentation {
if checker.patch(diagnostic.kind.rule()) {
diagnostic.set_fix(generate_fix(
@ -305,12 +287,8 @@ pub fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr) {
None
}
});
let mut diagnostic = Diagnostic::new(
DotFormatInException {
fixable: indentation.is_some(),
},
first.range(),
);
let mut diagnostic =
Diagnostic::new(DotFormatInException, first.range());
if let Some(indentation) = indentation {
if checker.patch(diagnostic.kind.rule()) {
diagnostic.set_fix(generate_fix(

View file

@ -66,6 +66,7 @@ EM.py:28:24: EM101 Exception must not use a string literal, assign to variable f
30 | raise RuntimeError("This is an example exception")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ EM101
|
= help: Assign to variable; remove string literal
EM.py:35:24: EM101 [*] Exception must not use a string literal, assign to variable first
|
@ -93,6 +94,7 @@ EM.py:42:28: EM101 Exception must not use a string literal, assign to variable f
43 | raise RuntimeError("This is an example exception")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ EM101
|
= help: Assign to variable; remove string literal
EM.py:47:28: EM101 [*] Exception must not use a string literal, assign to variable first
|
@ -164,6 +166,7 @@ EM.py:55:28: EM101 Exception must not use a string literal, assign to variable f
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ EM101
57 | if foo: x = 1; raise RuntimeError("This is an example exception")
|
= help: Assign to variable; remove string literal
EM.py:56:35: EM101 Exception must not use a string literal, assign to variable first
|
@ -172,5 +175,6 @@ EM.py:56:35: EM101 Exception must not use a string literal, assign to variable f
58 | if foo: x = 1; raise RuntimeError("This is an example exception")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ EM101
|
= help: Assign to variable; remove string literal

View file

@ -85,6 +85,7 @@ EM.py:28:24: EM101 Exception must not use a string literal, assign to variable f
30 | raise RuntimeError("This is an example exception")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ EM101
|
= help: Assign to variable; remove string literal
EM.py:35:24: EM101 [*] Exception must not use a string literal, assign to variable first
|
@ -112,6 +113,7 @@ EM.py:42:28: EM101 Exception must not use a string literal, assign to variable f
43 | raise RuntimeError("This is an example exception")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ EM101
|
= help: Assign to variable; remove string literal
EM.py:47:28: EM101 [*] Exception must not use a string literal, assign to variable first
|
@ -183,6 +185,7 @@ EM.py:55:28: EM101 Exception must not use a string literal, assign to variable f
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ EM101
57 | if foo: x = 1; raise RuntimeError("This is an example exception")
|
= help: Assign to variable; remove string literal
EM.py:56:35: EM101 Exception must not use a string literal, assign to variable first
|
@ -191,5 +194,6 @@ EM.py:56:35: EM101 Exception must not use a string literal, assign to variable f
58 | if foo: x = 1; raise RuntimeError("This is an example exception")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ EM101
|
= help: Assign to variable; remove string literal

View file

@ -51,9 +51,7 @@ use super::unittest_assert::UnittestAssert;
/// assert not something_else
/// ```
#[violation]
pub struct PytestCompositeAssertion {
fixable: bool,
}
pub struct PytestCompositeAssertion;
impl Violation for PytestCompositeAssertion {
const AUTOFIX: AutofixKind = AutofixKind::Sometimes;
@ -63,9 +61,8 @@ impl Violation for PytestCompositeAssertion {
format!("Assertion should be broken down into multiple parts")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|_| format!("Break down assertion into multiple parts"))
fn autofix_title(&self) -> Option<String> {
Some("Break down assertion into multiple parts".to_string())
}
}
@ -97,7 +94,6 @@ impl Violation for PytestAssertAlwaysFalse {
#[violation]
pub struct PytestUnittestAssertion {
assertion: String,
fixable: bool,
}
impl Violation for PytestUnittestAssertion {
@ -105,15 +101,13 @@ impl Violation for PytestUnittestAssertion {
#[derive_message_formats]
fn message(&self) -> String {
let PytestUnittestAssertion { assertion, .. } = self;
let PytestUnittestAssertion { assertion } = self;
format!("Use a regular `assert` instead of unittest-style `{assertion}`")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|PytestUnittestAssertion { assertion, .. }| {
format!("Replace `{assertion}(...)` with `assert ...`")
})
fn autofix_title(&self) -> Option<String> {
let PytestUnittestAssertion { assertion } = self;
Some(format!("Replace `{assertion}(...)` with `assert ...`"))
}
}
@ -198,7 +192,6 @@ pub fn unittest_assertion(
let mut diagnostic = Diagnostic::new(
PytestUnittestAssertion {
assertion: unittest_assert.to_string(),
fixable,
},
func.range(),
);
@ -426,7 +419,7 @@ pub fn composite_condition(checker: &mut Checker, stmt: &Stmt, test: &Expr, msg:
let fixable = matches!(composite, CompositionKind::Simple)
&& msg.is_none()
&& !has_comments_in(stmt.range(), checker.locator);
let mut diagnostic = Diagnostic::new(PytestCompositeAssertion { fixable }, stmt.range());
let mut diagnostic = Diagnostic::new(PytestCompositeAssertion, stmt.range());
if fixable && checker.patch(diagnostic.kind.rule()) {
#[allow(deprecated)]
diagnostic.try_set_fix_from_edit(|| {

View file

@ -26,11 +26,9 @@ impl Violation for PytestParametrizeNamesWrongType {
format!("Wrong name(s) type in `@pytest.mark.parametrize`, expected `{expected}`")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
Some(|violation| {
let PytestParametrizeNamesWrongType { expected } = violation;
format!("Use a `{expected}` for parameter names")
})
fn autofix_title(&self) -> Option<String> {
let PytestParametrizeNamesWrongType { expected } = self;
Some(format!("Use a `{expected}` for parameter names"))
}
}

View file

@ -159,6 +159,7 @@ PT009.py:21:13: PT009 Use a regular `assert` instead of unittest-style `assertIs
24 | if expect_condition
25 | else self.assertIsNone(value) # Error, unfixable
|
= help: Replace `assertIsNotNone(...)` with `assert ...`
PT009.py:23:18: PT009 Use a regular `assert` instead of unittest-style `assertIsNone`
|
@ -169,6 +170,7 @@ PT009.py:23:18: PT009 Use a regular `assert` instead of unittest-style `assertIs
26 | )
27 | return self.assertEqual(True, False) # Error, unfixable
|
= help: Replace `assertIsNone(...)` with `assert ...`
PT009.py:25:16: PT009 Use a regular `assert` instead of unittest-style `assertEqual`
|
@ -179,6 +181,7 @@ PT009.py:25:16: PT009 Use a regular `assert` instead of unittest-style `assertEq
28 |
29 | def test_assert_false(self):
|
= help: Replace `assertEqual(...)` with `assert ...`
PT009.py:28:9: PT009 [*] Use a regular `assert` instead of unittest-style `assertFalse`
|

View file

@ -229,6 +229,7 @@ PT018.py:30:5: PT018 Assertion should be broken down into multiple parts
32 | assert not (something or something_else and something_third), "with message"
33 | # detected, but no autofix for mixed conditions (e.g. `a or b and c`)
|
= help: Break down assertion into multiple parts
PT018.py:31:5: PT018 Assertion should be broken down into multiple parts
|
@ -239,6 +240,7 @@ PT018.py:31:5: PT018 Assertion should be broken down into multiple parts
34 | # detected, but no autofix for mixed conditions (e.g. `a or b and c`)
35 | assert not (something or something_else and something_third)
|
= help: Break down assertion into multiple parts
PT018.py:33:5: PT018 Assertion should be broken down into multiple parts
|
@ -249,6 +251,7 @@ PT018.py:33:5: PT018 Assertion should be broken down into multiple parts
36 | # detected, but no autofix for parenthesized conditions
37 | assert (
|
= help: Break down assertion into multiple parts
PT018.py:35:5: PT018 Assertion should be broken down into multiple parts
|

View file

@ -47,8 +47,7 @@ use crate::registry::AsRule;
/// - [Python: "isinstance"](https://docs.python.org/3/library/functions.html#isinstance)
#[violation]
pub struct DuplicateIsinstanceCall {
pub name: Option<String>,
fixable: bool,
name: Option<String>,
}
impl Violation for DuplicateIsinstanceCall {
@ -56,7 +55,7 @@ impl Violation for DuplicateIsinstanceCall {
#[derive_message_formats]
fn message(&self) -> String {
let DuplicateIsinstanceCall { name, .. } = self;
let DuplicateIsinstanceCall { name } = self;
if let Some(name) = name {
format!("Multiple `isinstance` calls for `{name}`, merge into a single call")
} else {
@ -64,14 +63,13 @@ impl Violation for DuplicateIsinstanceCall {
}
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|DuplicateIsinstanceCall { name, .. }| {
if let Some(name) = name {
fn autofix_title(&self) -> Option<String> {
let DuplicateIsinstanceCall { name } = self;
Some(if let Some(name) = name {
format!("Merge `isinstance` calls for `{name}`")
} else {
format!("Merge `isinstance` calls")
}
"Merge `isinstance` calls".to_string()
})
}
}
@ -305,7 +303,6 @@ pub fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
} else {
None
},
fixable,
},
expr.range(),
);

View file

@ -22,11 +22,9 @@ impl Violation for UncapitalizedEnvironmentVariables {
format!("Use capitalized environment variable `{expected}` instead of `{original}`")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
Some(|violation| {
let UncapitalizedEnvironmentVariables { expected, original } = violation;
format!("Replace `{original}` with `{expected}`")
})
fn autofix_title(&self) -> Option<String> {
let UncapitalizedEnvironmentVariables { expected, original } = self;
Some(format!("Replace `{original}` with `{expected}`"))
}
}

View file

@ -37,9 +37,7 @@ fn compare_body(body1: &[Stmt], body2: &[Stmt]) -> bool {
}
#[violation]
pub struct CollapsibleIf {
fixable: bool,
}
pub struct CollapsibleIf;
impl Violation for CollapsibleIf {
const AUTOFIX: AutofixKind = AutofixKind::Sometimes;
@ -49,16 +47,14 @@ impl Violation for CollapsibleIf {
format!("Use a single `if` statement instead of nested `if` statements")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|_| format!("Combine `if` statements using `and`"))
fn autofix_title(&self) -> Option<String> {
Some("Combine `if` statements using `and`".to_string())
}
}
#[violation]
pub struct NeedlessBool {
condition: String,
fixable: bool,
}
impl Violation for NeedlessBool {
@ -66,14 +62,13 @@ impl Violation for NeedlessBool {
#[derive_message_formats]
fn message(&self) -> String {
let NeedlessBool { condition, .. } = self;
let NeedlessBool { condition } = self;
format!("Return the condition `{condition}` directly")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable.then_some(|NeedlessBool { condition, .. }| {
format!("Replace with `return {condition}`")
})
fn autofix_title(&self) -> Option<String> {
let NeedlessBool { condition } = self;
Some(format!("Replace with `return {condition}`"))
}
}
@ -110,7 +105,6 @@ impl Violation for IfElseBlockInsteadOfDictLookup {
#[violation]
pub struct IfElseBlockInsteadOfIfExp {
contents: String,
fixable: bool,
}
impl Violation for IfElseBlockInsteadOfIfExp {
@ -118,15 +112,13 @@ impl Violation for IfElseBlockInsteadOfIfExp {
#[derive_message_formats]
fn message(&self) -> String {
let IfElseBlockInsteadOfIfExp { contents, .. } = self;
let IfElseBlockInsteadOfIfExp { contents } = self;
format!("Use ternary operator `{contents}` instead of `if`-`else`-block")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|IfElseBlockInsteadOfIfExp { contents, .. }| {
format!("Replace `if`-`else`-block with `{contents}`")
})
fn autofix_title(&self) -> Option<String> {
let IfElseBlockInsteadOfIfExp { contents } = self;
Some(format!("Replace `if`-`else`-block with `{contents}`"))
}
}
@ -163,7 +155,6 @@ impl Violation for IfWithSameArms {
#[violation]
pub struct IfElseBlockInsteadOfDictGet {
contents: String,
fixable: bool,
}
impl Violation for IfElseBlockInsteadOfDictGet {
@ -171,15 +162,13 @@ impl Violation for IfElseBlockInsteadOfDictGet {
#[derive_message_formats]
fn message(&self) -> String {
let IfElseBlockInsteadOfDictGet { contents, .. } = self;
let IfElseBlockInsteadOfDictGet { contents } = self;
format!("Use `{contents}` instead of an `if` block")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|IfElseBlockInsteadOfDictGet { contents, .. }| {
format!("Replace with `{contents}`")
})
fn autofix_title(&self) -> Option<String> {
let IfElseBlockInsteadOfDictGet { contents } = self;
Some(format!("Replace with `{contents}`"))
}
}
@ -289,7 +278,7 @@ pub fn nested_if_statements(
);
let mut diagnostic = Diagnostic::new(
CollapsibleIf { fixable },
CollapsibleIf,
colon.map_or_else(
|| stmt.range(),
|colon| TextRange::new(stmt.start(), colon.end()),
@ -367,7 +356,7 @@ pub fn needless_bool(checker: &mut Checker, stmt: &Stmt) {
&& !has_comments(stmt, checker.locator)
&& (matches!(test.node, ExprKind::Compare { .. }) || checker.ctx.is_builtin("bool"));
let mut diagnostic = Diagnostic::new(NeedlessBool { condition, fixable }, stmt.range());
let mut diagnostic = Diagnostic::new(NeedlessBool { condition }, stmt.range());
if fixable && checker.patch(diagnostic.kind.rule()) {
if matches!(test.node, ExprKind::Compare { .. }) {
// If the condition is a comparison, we can replace it with the condition.
@ -526,7 +515,6 @@ pub fn use_ternary_operator(checker: &mut Checker, stmt: &Stmt, parent: Option<&
let mut diagnostic = Diagnostic::new(
IfElseBlockInsteadOfIfExp {
contents: contents.clone(),
fixable,
},
stmt.range(),
);
@ -877,7 +865,6 @@ pub fn use_dict_get_with_default(
let mut diagnostic = Diagnostic::new(
IfElseBlockInsteadOfDictGet {
contents: contents.clone(),
fixable,
},
stmt.range(),
);

View file

@ -21,11 +21,9 @@ impl Violation for IfExprWithTrueFalse {
format!("Use `bool({expr})` instead of `True if {expr} else False`")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
Some(|violation| {
let IfExprWithTrueFalse { expr } = violation;
format!("Replace with `not {expr}")
})
fn autofix_title(&self) -> Option<String> {
let IfExprWithTrueFalse { expr } = self;
Some(format!("Replace with `not {expr}"))
}
}

View file

@ -42,9 +42,7 @@ use super::fix_with;
/// ## References
/// - [Python: "The with statement"](https://docs.python.org/3/reference/compound_stmts.html#the-with-statement)
#[violation]
pub struct MultipleWithStatements {
fixable: bool,
}
pub struct MultipleWithStatements;
impl Violation for MultipleWithStatements {
const AUTOFIX: AutofixKind = AutofixKind::Sometimes;
@ -57,9 +55,8 @@ impl Violation for MultipleWithStatements {
)
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|_| format!("Combine `with` statements"))
fn autofix_title(&self) -> Option<String> {
Some("Combine `with` statements".to_string())
}
}
@ -99,7 +96,7 @@ pub fn multiple_with_statements(
checker.locator,
);
let mut diagnostic = Diagnostic::new(
MultipleWithStatements { fixable },
MultipleWithStatements,
colon.map_or_else(
|| with_stmt.range(),
|colon| TextRange::new(with_stmt.start(), colon.end()),

View file

@ -26,11 +26,9 @@ impl Violation for ReimplementedBuiltin {
format!("Use `{repl}` instead of `for` loop")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
Some(|violation| {
let ReimplementedBuiltin { repl } = violation;
format!("Replace with `{repl}`")
})
fn autofix_title(&self) -> Option<String> {
let ReimplementedBuiltin { repl } = self;
Some(format!("Replace with `{repl}`"))
}
}

View file

@ -28,11 +28,9 @@ impl Violation for SuppressibleException {
format!("Use `contextlib.suppress({exception})` instead of `try`-`except`-`pass`")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|SuppressibleException { exception, .. }| {
format!("Replace with `contextlib.suppress({exception})`")
})
fn autofix_title(&self) -> Option<String> {
let SuppressibleException { exception, .. } = self;
Some(format!("Replace with `contextlib.suppress({exception})`"))
}
}

View file

@ -29,16 +29,11 @@ impl Violation for YodaConditions {
}
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
fn autofix_title(&self) -> Option<String> {
let YodaConditions { suggestion } = self;
if suggestion.is_some() {
Some(|YodaConditions { suggestion }| {
let suggestion = suggestion.as_ref().unwrap();
format!("Replace Yoda condition with `{suggestion}`")
})
} else {
None
}
suggestion
.as_ref()
.map(|suggestion| format!("Replace Yoda condition with `{suggestion}`"))
}
}

View file

@ -144,5 +144,6 @@ SIM101.py:22:4: SIM101 Multiple `isinstance` calls for expression, merge into a
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM101
25 | pass
|
= help: Merge `isinstance` calls

View file

@ -81,6 +81,7 @@ SIM102.py:20:1: SIM102 Use a single `if` statement instead of nested `if` statem
| |_________^ SIM102
24 | c
|
= help: Combine `if` statements using `and`
SIM102.py:26:1: SIM102 [*] Use a single `if` statement instead of nested `if` statements
|

View file

@ -115,6 +115,7 @@ SIM103.py:57:5: SIM103 Return the condition `a` directly
62 | | return True
| |___________________^ SIM103
|
= help: Replace with `return a`
SIM103.py:83:5: SIM103 Return the condition `a` directly
|
@ -127,5 +128,6 @@ SIM103.py:83:5: SIM103 Return the condition `a` directly
88 | | return False
| |____________________^ SIM103
|
= help: Replace with `return a`

View file

@ -175,5 +175,6 @@ SIM105_0.py:93:5: SIM105 Use `contextlib.suppress(ValueError, OSError)` instead
97 | | pass # Trailing comment.
| |____________^ SIM105
|
= help: Replace with `contextlib.suppress(ValueError, OSError)`

View file

@ -36,6 +36,7 @@ SIM108.py:58:1: SIM108 Use ternary operator `abc = x if x > 0 else -x` instead o
64 | | abc = -x
| |____________^ SIM108
|
= help: Replace `if`-`else`-block with `abc = x if x > 0 else -x`
SIM108.py:82:1: SIM108 [*] Use ternary operator `b = cccccccccccccccccccccccccccccccccccc if a else ddddddddddddddddddddddddddddddddddddd` instead of `if`-`else`-block
|
@ -70,6 +71,7 @@ SIM108.py:97:1: SIM108 Use ternary operator `exitcode = 0 if True else 1` instea
101 | | exitcode = 1 # Trailing comment
| |________________^ SIM108
|
= help: Replace `if`-`else`-block with `exitcode = 0 if True else 1`
SIM108.py:104:1: SIM108 Use ternary operator `x = 3 if True else 5` instead of `if`-`else`-block
|
@ -78,6 +80,7 @@ SIM108.py:104:1: SIM108 Use ternary operator `x = 3 if True else 5` instead of `
106 | | else: x = 5
| |___________^ SIM108
|
= help: Replace `if`-`else`-block with `x = 3 if True else 5`
SIM108.py:109:1: SIM108 Use ternary operator `x = 3 if True else 5` instead of `if`-`else`-block
|
@ -88,5 +91,6 @@ SIM108.py:109:1: SIM108 Use ternary operator `x = 3 if True else 5` instead of `
113 | | x = 5
| |_________^ SIM108
|
= help: Replace `if`-`else`-block with `x = 3 if True else 5`

View file

@ -57,6 +57,7 @@ SIM117.py:13:1: SIM117 Use a single `with` statement with multiple contexts inst
| |__________________^ SIM117
17 | print("hello")
|
= help: Combine `with` statements
SIM117.py:19:1: SIM117 [*] Use a single `with` statement with multiple contexts instead of nested `with` statements
|

View file

@ -73,12 +73,13 @@ impl Violation for RelativeImports {
}
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
Some(|RelativeImports { strictness }| match strictness {
fn autofix_title(&self) -> Option<String> {
let RelativeImports { strictness } = self;
Some(match strictness {
Strictness::Parents => {
format!("Replace relative imports from parent modules with absolute imports")
"Replace relative imports from parent modules with absolute imports".to_string()
}
Strictness::All => format!("Replace relative imports with absolute imports"),
Strictness::All => "Replace relative imports with absolute imports".to_string(),
})
}
}

View file

@ -48,8 +48,8 @@ impl Violation for UnsortedImports {
format!("Import block is un-sorted or un-formatted")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
Some(|_| "Organize imports".to_string())
fn autofix_title(&self) -> Option<String> {
Some("Organize imports".to_string())
}
}

View file

@ -32,9 +32,7 @@ use crate::rules::pandas_vet::fixes::convert_inplace_argument_to_assignment;
/// ## References
/// - [_Why You Should Probably Never Use pandas inplace=True_](https://towardsdatascience.com/why-you-should-probably-never-use-pandas-inplace-true-9f9f211849e4)
#[violation]
pub struct PandasUseOfInplaceArgument {
fixable: bool,
}
pub struct PandasUseOfInplaceArgument;
impl Violation for PandasUseOfInplaceArgument {
const AUTOFIX: AutofixKind = AutofixKind::Sometimes;
@ -44,9 +42,8 @@ impl Violation for PandasUseOfInplaceArgument {
format!("`inplace=True` should be avoided; it has inconsistent behavior")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|_| format!("Assign to variable; remove `inplace` arg"))
fn autofix_title(&self) -> Option<String> {
Some("Assign to variable; remove `inplace` arg".to_string())
}
}
@ -85,8 +82,7 @@ pub fn inplace_argument(
&& matches!(checker.ctx.stmt().node, StmtKind::Expr { .. })
&& checker.ctx.expr_parent().is_none()
&& !checker.ctx.scope().kind.is_lambda();
let mut diagnostic =
Diagnostic::new(PandasUseOfInplaceArgument { fixable }, keyword.range());
let mut diagnostic = Diagnostic::new(PandasUseOfInplaceArgument, keyword.range());
if fixable && checker.patch(diagnostic.kind.rule()) {
if let Some(fix) = convert_inplace_argument_to_assignment(
checker.locator,

View file

@ -114,6 +114,7 @@ PD002.py:23:23: PD002 `inplace=True` should be avoided; it has inconsistent beha
| ^^^^^^^^^^^^ PD002
25 | f(x.drop(["a"], axis=1, inplace=True))
|
= help: Assign to variable; remove `inplace` arg
PD002.py:24:25: PD002 `inplace=True` should be avoided; it has inconsistent behavior
|
@ -124,6 +125,7 @@ PD002.py:24:25: PD002 `inplace=True` should be avoided; it has inconsistent beha
27 |
28 | x.apply(lambda x: x.sort_values('a', inplace=True))
|
= help: Assign to variable; remove `inplace` arg
PD002.py:26:38: PD002 `inplace=True` should be avoided; it has inconsistent behavior
|
@ -132,5 +134,6 @@ PD002.py:26:38: PD002 `inplace=True` should be avoided; it has inconsistent beha
28 | x.apply(lambda x: x.sort_values('a', inplace=True))
| ^^^^^^^^^^^^ PD002
|
= help: Assign to variable; remove `inplace` arg

View file

@ -39,7 +39,6 @@ use crate::registry::AsRule;
#[violation]
pub struct LambdaAssignment {
name: String,
fixable: bool,
}
impl Violation for LambdaAssignment {
@ -50,9 +49,9 @@ impl Violation for LambdaAssignment {
format!("Do not assign a `lambda` expression, use a `def`")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|LambdaAssignment { name, .. }| format!("Rewrite `{name}` as a `def`"))
fn autofix_title(&self) -> Option<String> {
let LambdaAssignment { name } = self;
Some(format!("Rewrite `{name}` as a `def`"))
}
}
@ -77,7 +76,6 @@ pub fn lambda_assignment(
let mut diagnostic = Diagnostic::new(
LambdaAssignment {
name: id.to_string(),
fixable,
},
stmt.range(),
);

View file

@ -115,6 +115,7 @@ E731.py:14:5: E731 Do not assign a `lambda` expression, use a `def`
16 | f = lambda x: 2 * x
| ^^^^^^^^^^^^^^^^^^^ E731
|
= help: Rewrite `f` as a `def`
E731.py:32:1: E731 [*] Do not assign a `lambda` expression, use a `def`
|

View file

@ -11,9 +11,6 @@ pub struct BlankLineAfterSummary {
num_lines: usize,
}
fn fmt_blank_line_after_summary_autofix_msg(_: &BlankLineAfterSummary) -> String {
"Insert single blank line".to_string()
}
impl Violation for BlankLineAfterSummary {
const AUTOFIX: AutofixKind = AutofixKind::Sometimes;
@ -29,12 +26,8 @@ impl Violation for BlankLineAfterSummary {
}
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
let BlankLineAfterSummary { num_lines } = self;
if *num_lines > 0 {
return Some(fmt_blank_line_after_summary_autofix_msg);
}
None
fn autofix_title(&self) -> Option<String> {
Some("Insert single blank line".to_string())
}
}

View file

@ -19,8 +19,8 @@ impl Violation for SurroundingWhitespace {
format!("No whitespaces allowed surrounding docstring text")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
Some(|_| "Trim surrounding whitespace".to_string())
fn autofix_title(&self) -> Option<String> {
Some("Trim surrounding whitespace".to_string())
}
}

View file

@ -18,8 +18,8 @@ impl Violation for FitsOnOneLine {
format!("One-line docstring should fit on one line")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
Some(|_| "Reformat to one line".to_string())
fn autofix_title(&self) -> Option<String> {
Some("Reformat to one line".to_string())
}
}

View file

@ -12,6 +12,7 @@ D.py:200:5: D205 1 blank line required between summary line and description
205 | | """
| |_______^ D205
|
= help: Insert single blank line
D.py:210:5: D205 [*] 1 blank line required between summary line and description (found 2)
|

View file

@ -44,16 +44,13 @@ impl Violation for UnusedImport {
}
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
let UnusedImport { context, .. } = self;
context
.is_none()
.then_some(|UnusedImport { name, multiple, .. }| {
if *multiple {
fn autofix_title(&self) -> Option<String> {
let UnusedImport { name, multiple, .. } = self;
Some(if *multiple {
"Remove unused import".to_string()
} else {
format!("Remove unused import: `{name}`")
}
})
}
}

View file

@ -26,12 +26,13 @@ impl Violation for MultiValueRepeatedKeyLiteral {
format!("Dictionary key literal `{name}` repeated")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
let MultiValueRepeatedKeyLiteral { repeated_value, .. } = self;
fn autofix_title(&self) -> Option<String> {
let MultiValueRepeatedKeyLiteral {
repeated_value,
name,
} = self;
if *repeated_value {
Some(|MultiValueRepeatedKeyLiteral { name, .. }| {
format!("Remove repeated key literal `{name}`")
})
Some(format!("Remove repeated key literal `{name}`"))
} else {
None
}
@ -52,12 +53,13 @@ impl Violation for MultiValueRepeatedKeyVariable {
format!("Dictionary key `{name}` repeated")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
let MultiValueRepeatedKeyVariable { repeated_value, .. } = self;
fn autofix_title(&self) -> Option<String> {
let MultiValueRepeatedKeyVariable {
repeated_value,
name,
} = self;
if *repeated_value {
Some(|MultiValueRepeatedKeyVariable { name, .. }| {
format!("Remove repeated key `{name}`")
})
Some(format!("Remove repeated key `{name}`"))
} else {
None
}

View file

@ -57,11 +57,9 @@ impl Violation for UnusedVariable {
format!("Local variable `{name}` is assigned to but never used")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
Some(|violation| {
let UnusedVariable { name } = violation;
format!("Remove assignment to unused variable `{name}`")
})
fn autofix_title(&self) -> Option<String> {
let UnusedVariable { name } = self;
Some(format!("Remove assignment to unused variable `{name}`"))
}
}

View file

@ -10,6 +10,7 @@ F401_10.py:6:16: F401 `orjson` imported but unused; consider using `importlib.ut
9 |
10 | return True
|
= help: Remove unused import: `orjson`
F401_10.py:15:16: F401 [*] `orjson` imported but unused
|

View file

@ -11,7 +11,6 @@ use crate::registry::AsRule;
pub struct ManualFromImport {
module: String,
name: String,
fixable: bool,
}
impl Violation for ManualFromImport {
@ -19,15 +18,13 @@ impl Violation for ManualFromImport {
#[derive_message_formats]
fn message(&self) -> String {
let ManualFromImport { module, name, .. } = self;
let ManualFromImport { module, name } = self;
format!("Use `from {module} import {name}` in lieu of alias")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|ManualFromImport { module, name, .. }| {
format!("Replace with `from {module} import {name}`")
})
fn autofix_title(&self) -> Option<String> {
let ManualFromImport { module, name } = self;
Some(format!("Replace with `from {module} import {name}`"))
}
}
@ -48,7 +45,6 @@ pub fn manual_from_import(checker: &mut Checker, stmt: &Stmt, alias: &Alias, nam
ManualFromImport {
module: module.to_string(),
name: name.to_string(),
fixable,
},
alias.range(),
);

View file

@ -1,4 +1,4 @@
use ruff_text_size::TextSize;
use ruff_text_size::TextRange;
use rustpython_parser::ast::{Expr, ExprKind, Keyword};
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
@ -17,7 +17,6 @@ pub enum MinMax {
#[violation]
pub struct NestedMinMax {
func: MinMax,
fixable: bool,
}
impl Violation for NestedMinMax {
@ -28,9 +27,9 @@ impl Violation for NestedMinMax {
format!("Nested `{}` calls can be flattened", self.func)
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|NestedMinMax { func, .. }| format!("Flatten nested `{func}` calls"))
fn autofix_title(&self) -> Option<String> {
let NestedMinMax { func } = self;
Some(format!("Flatten nested `{func}` calls"))
}
}
@ -106,22 +105,15 @@ pub fn nested_min_max(
MinMax::try_from_call(func, keywords, &checker.ctx) == Some(min_max)
}) {
let fixable = !has_comments(expr, checker.locator);
let mut diagnostic = Diagnostic::new(
NestedMinMax {
func: min_max,
fixable,
},
expr.range(),
);
let mut diagnostic = Diagnostic::new(NestedMinMax { func: min_max }, expr.range());
if fixable && checker.patch(diagnostic.kind.rule()) {
let flattened_expr = Expr::new(
TextSize::default(),
TextSize::default(),
let flattened_expr = Expr::with_range(
ExprKind::Call {
func: Box::new(func.clone()),
args: collect_nested_args(&checker.ctx, min_max, args),
keywords: keywords.to_owned(),
},
TextRange::default(),
);
#[allow(deprecated)]
diagnostic.set_fix(Fix::unspecified(Edit::range_replacement(

View file

@ -21,8 +21,9 @@ impl Violation for SysExitAlias {
format!("Use `sys.exit()` instead of `{name}`")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
Some(|SysExitAlias { name }| format!("Replace `{name}` with `sys.exit()`"))
fn autofix_title(&self) -> Option<String> {
let SysExitAlias { name } = self;
Some(format!("Replace `{name}` with `sys.exit()`"))
}
}

View file

@ -52,5 +52,6 @@ import_aliasing.py:12:8: PLR0402 Use `from foo.bar import foobar` in lieu of ali
15 | import os
16 | import os as OS
|
= help: Replace with `from foo.bar import foobar`

View file

@ -192,5 +192,6 @@ nested_min_max.py:18:1: PLW3301 Nested `min` calls can be flattened
22 | | )
| |_^ PLW3301
|
= help: Flatten nested `min` calls

View file

@ -14,7 +14,6 @@ use crate::registry::AsRule;
#[violation]
pub struct ConvertNamedTupleFunctionalToClass {
name: String,
fixable: bool,
}
impl Violation for ConvertNamedTupleFunctionalToClass {
@ -22,15 +21,14 @@ impl Violation for ConvertNamedTupleFunctionalToClass {
#[derive_message_formats]
fn message(&self) -> String {
let ConvertNamedTupleFunctionalToClass { name, .. } = self;
let ConvertNamedTupleFunctionalToClass { name } = self;
format!("Convert `{name}` from `NamedTuple` functional to class syntax")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|ConvertNamedTupleFunctionalToClass { name, .. }| {
format!("Convert `{name}` to class syntax")
})
fn autofix_title(&self) -> Option<String> {
let ConvertNamedTupleFunctionalToClass { name } = self;
Some(format!("Convert `{name}` to class syntax"))
}
}
@ -197,7 +195,6 @@ pub fn convert_named_tuple_functional_to_class(
let mut diagnostic = Diagnostic::new(
ConvertNamedTupleFunctionalToClass {
name: typename.to_string(),
fixable,
},
stmt.range(),
);

View file

@ -26,11 +26,9 @@ impl Violation for ConvertTypedDictFunctionalToClass {
format!("Convert `{name}` from `TypedDict` functional to class syntax")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|ConvertTypedDictFunctionalToClass { name, .. }| {
format!("Convert `{name}` to class syntax")
})
fn autofix_title(&self) -> Option<String> {
let ConvertTypedDictFunctionalToClass { name, .. } = self;
Some(format!("Convert `{name}` to class syntax"))
}
}

View file

@ -20,12 +20,8 @@ impl Violation for DatetimeTimezoneUTC {
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
}
fn autofix_title(&self) -> Option<String> {
Some("Convert to `datetime.UTC` alias".to_string())
}
}

View file

@ -62,14 +62,9 @@ impl Violation for DeprecatedImport {
}
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
if let Deprecation::WithoutRename(WithoutRename { fixable, .. }) = self.deprecation {
fixable.then_some(|DeprecatedImport { deprecation }| {
let Deprecation::WithoutRename(WithoutRename { target, .. }) = deprecation else {
unreachable!();
};
format!("Import from `{target}`")
})
fn autofix_title(&self) -> Option<String> {
if let Deprecation::WithoutRename(WithoutRename { target, .. }) = &self.deprecation {
Some(format!("Import from `{target}`"))
} else {
None
}

View file

@ -24,8 +24,8 @@ impl Violation for FormatLiterals {
format!("Use implicit references for positional format fields")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
Some(|_| "Remove explicit positional indices".to_string())
fn autofix_title(&self) -> Option<String> {
Some("Remove explicit positional indices".to_string())
}
}

View file

@ -7,9 +7,7 @@ use crate::checkers::ast::Checker;
use crate::registry::AsRule;
#[violation]
pub struct OpenAlias {
fixable: bool,
}
pub struct OpenAlias;
impl Violation for OpenAlias {
const AUTOFIX: AutofixKind = AutofixKind::Sometimes;
@ -19,9 +17,8 @@ impl Violation for OpenAlias {
format!("Use builtin `open`")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|_| format!("Replace with builtin `open`"))
fn autofix_title(&self) -> Option<String> {
Some("Replace with builtin `open`".to_string())
}
}
@ -36,7 +33,7 @@ pub fn open_alias(checker: &mut Checker, expr: &Expr, func: &Expr) {
.ctx
.find_binding("open")
.map_or(true, |binding| binding.kind.is_builtin());
let mut diagnostic = Diagnostic::new(OpenAlias { fixable }, expr.range());
let mut diagnostic = Diagnostic::new(OpenAlias, expr.range());
if fixable && checker.patch(diagnostic.kind.rule()) {
#[allow(deprecated)]
diagnostic.set_fix(Fix::unspecified(Edit::range_replacement(

View file

@ -10,7 +10,6 @@ use crate::registry::AsRule;
#[violation]
pub struct NonPEP585Annotation {
name: String,
fixable: bool,
}
impl Violation for NonPEP585Annotation {
@ -18,7 +17,7 @@ impl Violation for NonPEP585Annotation {
#[derive_message_formats]
fn message(&self) -> String {
let NonPEP585Annotation { name, .. } = self;
let NonPEP585Annotation { name } = self;
format!(
"Use `{}` instead of `{}` for type annotations",
name.to_lowercase(),
@ -26,10 +25,9 @@ impl Violation for NonPEP585Annotation {
)
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable.then_some(|NonPEP585Annotation { name, .. }| {
format!("Replace `{name}` with `{}`", name.to_lowercase())
})
fn autofix_title(&self) -> Option<String> {
let NonPEP585Annotation { name } = self;
Some(format!("Replace `{name}` with `{}`", name.to_lowercase()))
}
}
@ -48,7 +46,6 @@ pub fn use_pep585_annotation(checker: &mut Checker, expr: &Expr) {
let mut diagnostic = Diagnostic::new(
NonPEP585Annotation {
name: binding.to_string(),
fixable,
},
expr.range(),
);

View file

@ -10,9 +10,7 @@ use crate::checkers::ast::Checker;
use crate::registry::AsRule;
#[violation]
pub struct NonPEP604Annotation {
fixable: bool,
}
pub struct NonPEP604Annotation;
impl Violation for NonPEP604Annotation {
const AUTOFIX: AutofixKind = AutofixKind::Sometimes;
@ -22,8 +20,8 @@ impl Violation for NonPEP604Annotation {
format!("Use `X | Y` for type annotations")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable.then_some(|_| format!("Convert to `X | Y`"))
fn autofix_title(&self) -> Option<String> {
Some("Convert to `X | Y`".to_string())
}
}
@ -110,7 +108,7 @@ pub fn use_pep604_annotation(checker: &mut Checker, expr: &Expr, value: &Expr, s
match typing_member {
TypingMember::Optional => {
let mut diagnostic = Diagnostic::new(NonPEP604Annotation { fixable }, expr.range());
let mut diagnostic = Diagnostic::new(NonPEP604Annotation, expr.range());
if fixable && checker.patch(diagnostic.kind.rule()) {
#[allow(deprecated)]
diagnostic.set_fix(Fix::unspecified(Edit::range_replacement(
@ -121,7 +119,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(NonPEP604Annotation { fixable }, expr.range());
let mut diagnostic = Diagnostic::new(NonPEP604Annotation, expr.range());
if fixable && checker.patch(diagnostic.kind.rule()) {
match &slice.node {
ExprKind::Slice { .. } => {

View file

@ -151,6 +151,7 @@ UP006.py:45:10: UP006 Use `list` instead of `List` for type annotations
| ^^^^^^^^^^^^^^ UP006
46 | ...
|
= help: Replace `List` with `list`
UP006.py:49:11: UP006 [*] Use `list` instead of `List` for type annotations
|
@ -212,6 +213,7 @@ UP006.py:53:16: UP006 Use `list` instead of `List` for type annotations
| ^^^^^^^^^^^^^^ UP006
54 | ...
|
= help: Replace `List` with `list`
UP006.py:57:10: UP006 Use `list` instead of `List` for type annotations
|
@ -219,6 +221,7 @@ UP006.py:57:10: UP006 Use `list` instead of `List` for type annotations
| ^^^^^^^^^^^^^^^^^^^^^^ UP006
58 | ...
|
= help: Replace `List` with `list`
UP006.py:57:10: UP006 Use `list` instead of `List` for type annotations
|
@ -226,5 +229,6 @@ UP006.py:57:10: UP006 Use `list` instead of `List` for type annotations
| ^^^^^^^^^^^^^^^^^^^^^^ UP006
58 | ...
|
= help: Replace `List` with `list`

View file

@ -209,6 +209,7 @@ UP007.py:48:9: UP007 Use `X | Y` for type annotations
51 |
52 | x = Union[str, int]
|
= help: Convert to `X | Y`
UP007.py:50:9: UP007 Use `X | Y` for type annotations
|
@ -219,6 +220,7 @@ UP007.py:50:9: UP007 Use `X | Y` for type annotations
53 | x = Union["str", "int"]
54 | x: Union[str, int]
|
= help: Convert to `X | Y`
UP007.py:52:8: UP007 [*] Use `X | Y` for type annotations
|

View file

@ -28,5 +28,6 @@ UP020.py:8:6: UP020 Use builtin `open`
| ^^^^^^^^^^^^^ UP020
11 | print(f.read())
|
= help: Replace with builtin `open`

View file

@ -418,5 +418,6 @@ UP035.py:46:10: UP035 Import from `collections.abc` instead: `Mapping`
50 |
51 | # OK
|
= help: Import from `collections.abc`

View file

@ -8,6 +8,7 @@ UP017.py:7:7: UP017 Use `datetime.UTC` alias
| ^^^^^^^^^^^^ UP017
9 | print(tz.utc)
|
= help: Convert to `datetime.UTC` alias
UP017.py:8:7: UP017 Use `datetime.UTC` alias
|
@ -18,6 +19,7 @@ UP017.py:8:7: UP017 Use `datetime.UTC` alias
11 |
12 | print(datetime.timezone.utc)
|
= help: Convert to `datetime.UTC` alias
UP017.py:10:7: UP017 [*] Use `datetime.UTC` alias
|
@ -43,5 +45,6 @@ UP017.py:11:7: UP017 Use `datetime.UTC` alias
12 | print(dt.timezone.utc)
| ^^^^^^^^^^^^^^^ UP017
|
= help: Convert to `datetime.UTC` alias

View file

@ -10,7 +10,6 @@ use crate::registry::AsRule;
#[violation]
pub struct CollectionLiteralConcatenation {
expr: String,
fixable: bool,
}
impl Violation for CollectionLiteralConcatenation {
@ -18,15 +17,13 @@ impl Violation for CollectionLiteralConcatenation {
#[derive_message_formats]
fn message(&self) -> String {
let CollectionLiteralConcatenation { expr, .. } = self;
let CollectionLiteralConcatenation { expr } = self;
format!("Consider `{expr}` instead of concatenation")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
self.fixable
.then_some(|CollectionLiteralConcatenation { expr, .. }| {
format!("Replace with `{expr}`")
})
fn autofix_title(&self) -> Option<String> {
let CollectionLiteralConcatenation { expr } = self;
Some(format!("Replace with `{expr}`"))
}
}
@ -102,7 +99,6 @@ pub fn collection_literal_concatenation(checker: &mut Checker, expr: &Expr) {
let mut diagnostic = Diagnostic::new(
CollectionLiteralConcatenation {
expr: contents.clone(),
fixable,
},
expr.range(),
);

View file

@ -226,6 +226,7 @@ RUF005.py:32:10: RUF005 Consider `[*first, 4, 5, 6]` instead of concatenation
42 |
43 | [] + foo + [
|
= help: Replace with `[*first, 4, 5, 6]`
RUF005.py:41:1: RUF005 [*] Consider `[*foo]` instead of concatenation
|

View file

@ -30,10 +30,13 @@ pub trait Violation: Debug + PartialEq + Eq {
None
}
/// If autofix is (potentially) available for this violation returns another
/// function that in turn can be used to obtain a string describing the
/// autofix.
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
// TODO micha: Move `autofix_title` to `Fix`, add new `advice` method that is shown as an advice.
// Change the `Diagnostic` renderer to show the advice, and render the fix message after the `Suggested fix: <here>`
/// Returns the title for the autofix. The message is also shown as an advice as part of the diagnostics.
///
/// Required for rules that have autofixes.
fn autofix_title(&self) -> Option<String> {
None
}
@ -72,8 +75,8 @@ impl<VA: AlwaysAutofixableViolation> Violation for VA {
<Self as AlwaysAutofixableViolation>::explanation()
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
Some(Self::autofix_title)
fn autofix_title(&self) -> Option<String> {
Some(<Self as AlwaysAutofixableViolation>::autofix_title(self))
}
fn message_formats() -> &'static [&'static str] {

View file

@ -59,7 +59,7 @@ pub fn violation(violation: &ItemStruct) -> Result<TokenStream> {
Self {
body: Violation::message(&value),
suggestion: value.autofix_title_formatter().map(|f| f(&value)),
suggestion: Violation::autofix_title(&value),
name: stringify!(#ident).to_string(),
}
}
@ -82,7 +82,7 @@ pub fn violation(violation: &ItemStruct) -> Result<TokenStream> {
Self {
body: Violation::message(&value),
suggestion: value.autofix_title_formatter().map(|f| f(&value)),
suggestion: Violation::autofix_title(&value),
name: stringify!(#ident).to_string(),
}
}