mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:16 +00:00
Remove functor from autofix title (#4245)
This commit is contained in:
parent
8969ad5879
commit
a2b8487ae3
61 changed files with 234 additions and 305 deletions
|
@ -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}`"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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(|| {
|
||||
|
|
|
@ -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"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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`
|
||||
|
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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(),
|
||||
);
|
||||
|
|
|
@ -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}`"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),
|
||||
);
|
||||
|
|
|
@ -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}"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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}`"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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})`"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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}`"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -144,5 +144,6 @@ SIM101.py:22:4: SIM101 Multiple `isinstance` calls for expression, merge into a
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SIM101
|
||||
25 | pass
|
||||
|
|
||||
= help: Merge `isinstance` calls
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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`
|
||||
|
||||
|
||||
|
|
|
@ -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)`
|
||||
|
||||
|
||||
|
|
|
@ -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`
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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(),
|
||||
);
|
||||
|
|
|
@ -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`
|
||||
|
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
||||
|
|
|
@ -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}`")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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}`"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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(),
|
||||
);
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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()`"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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`
|
||||
|
||||
|
||||
|
|
|
@ -192,5 +192,6 @@ nested_min_max.py:18:1: PLW3301 Nested `min` calls can be flattened
|
|||
22 | | )
|
||||
| |_^ PLW3301
|
||||
|
|
||||
= help: Flatten nested `min` calls
|
||||
|
||||
|
||||
|
|
|
@ -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(),
|
||||
);
|
||||
|
|
|
@ -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"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(),
|
||||
);
|
||||
|
|
|
@ -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 { .. } => {
|
||||
|
|
|
@ -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`
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -28,5 +28,6 @@ UP020.py:8:6: UP020 Use builtin `open`
|
|||
| ^^^^^^^^^^^^^ UP020
|
||||
11 | print(f.read())
|
||||
|
|
||||
= help: Replace with builtin `open`
|
||||
|
||||
|
||||
|
|
|
@ -418,5 +418,6 @@ UP035.py:46:10: UP035 Import from `collections.abc` instead: `Mapping`
|
|||
50 |
|
||||
51 | # OK
|
||||
|
|
||||
= help: Import from `collections.abc`
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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(),
|
||||
);
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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] {
|
||||
|
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue