Add E201, E202, E203 auto-fix (#4723)

This commit is contained in:
Jonathan Plasse 2023-05-31 18:53:47 +02:00 committed by GitHub
parent 0b471197dc
commit 01470d9045
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 292 additions and 34 deletions

View file

@ -39,9 +39,15 @@ pub(crate) fn check_logical_lines(
let mut context = LogicalLinesContext::new(settings);
let should_fix_missing_whitespace = settings.rules.should_fix(Rule::MissingWhitespace);
let should_fix_whitespace_before_parameters =
settings.rules.should_fix(Rule::WhitespaceBeforeParameters);
let should_fix_whitespace_after_open_bracket =
settings.rules.should_fix(Rule::WhitespaceAfterOpenBracket);
let should_fix_whitespace_before_close_bracket = settings
.rules
.should_fix(Rule::WhitespaceBeforeCloseBracket);
let should_fix_whitespace_before_punctuation =
settings.rules.should_fix(Rule::WhitespaceBeforePunctuation);
let mut prev_line = None;
let mut prev_indent_level = None;
@ -59,7 +65,13 @@ pub(crate) fn check_logical_lines(
.flags()
.intersects(TokenFlags::OPERATOR | TokenFlags::BRACKET | TokenFlags::PUNCTUATION)
{
extraneous_whitespace(&line, &mut context);
extraneous_whitespace(
&line,
&mut context,
should_fix_whitespace_after_open_bracket,
should_fix_whitespace_before_close_bracket,
should_fix_whitespace_before_punctuation,
);
}
if line.flags().contains(TokenFlags::KEYWORD) {

View file

@ -1,9 +1,10 @@
use ruff_text_size::TextRange;
use ruff_diagnostics::DiagnosticKind;
use ruff_diagnostics::Violation;
use ruff_diagnostics::AlwaysAutofixableViolation;
use ruff_diagnostics::Diagnostic;
use ruff_diagnostics::Edit;
use ruff_diagnostics::Fix;
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::token_kind::TokenKind;
use ruff_text_size::TextRange;
use crate::checkers::logical_lines::LogicalLinesContext;
@ -36,12 +37,17 @@ pub struct WhitespaceAfterOpenBracket {
symbol: char,
}
impl Violation for WhitespaceAfterOpenBracket {
impl AlwaysAutofixableViolation for WhitespaceAfterOpenBracket {
#[derive_message_formats]
fn message(&self) -> String {
let WhitespaceAfterOpenBracket { symbol } = self;
format!("Whitespace after '{symbol}'")
}
fn autofix_title(&self) -> String {
let WhitespaceAfterOpenBracket { symbol } = self;
format!("Remove whitespace before '{symbol}'")
}
}
/// ## What it does
@ -71,12 +77,17 @@ pub struct WhitespaceBeforeCloseBracket {
symbol: char,
}
impl Violation for WhitespaceBeforeCloseBracket {
impl AlwaysAutofixableViolation for WhitespaceBeforeCloseBracket {
#[derive_message_formats]
fn message(&self) -> String {
let WhitespaceBeforeCloseBracket { symbol } = self;
format!("Whitespace before '{symbol}'")
}
fn autofix_title(&self) -> String {
let WhitespaceBeforeCloseBracket { symbol } = self;
format!("Remove whitespace before '{symbol}'")
}
}
/// ## What it does
@ -104,16 +115,27 @@ pub struct WhitespaceBeforePunctuation {
symbol: char,
}
impl Violation for WhitespaceBeforePunctuation {
impl AlwaysAutofixableViolation for WhitespaceBeforePunctuation {
#[derive_message_formats]
fn message(&self) -> String {
let WhitespaceBeforePunctuation { symbol } = self;
format!("Whitespace before '{symbol}'")
}
fn autofix_title(&self) -> String {
let WhitespaceBeforePunctuation { symbol } = self;
format!("Remove whitespace before '{symbol}'")
}
}
/// E201, E202, E203
pub(crate) fn extraneous_whitespace(line: &LogicalLine, context: &mut LogicalLinesContext) {
pub(crate) fn extraneous_whitespace(
line: &LogicalLine,
context: &mut LogicalLinesContext,
autofix_after_open_bracket: bool,
autofix_before_close_bracket: bool,
autofix_before_punctuation: bool,
) {
let mut prev_token = None;
for token in line.tokens() {
@ -123,10 +145,15 @@ pub(crate) fn extraneous_whitespace(line: &LogicalLine, context: &mut LogicalLin
BracketOrPunctuation::OpenBracket(symbol) => {
let (trailing, trailing_len) = line.trailing_whitespace(token);
if !matches!(trailing, Whitespace::None) {
context.push(
let mut diagnostic = Diagnostic::new(
WhitespaceAfterOpenBracket { symbol },
TextRange::at(token.end(), trailing_len),
);
if autofix_after_open_bracket {
diagnostic
.set_fix(Fix::automatic(Edit::range_deletion(diagnostic.range())));
}
context.push_diagnostic(diagnostic);
}
}
BracketOrPunctuation::CloseBracket(symbol) => {
@ -134,10 +161,16 @@ pub(crate) fn extraneous_whitespace(line: &LogicalLine, context: &mut LogicalLin
if let (Whitespace::Single | Whitespace::Many | Whitespace::Tab, offset) =
line.leading_whitespace(token)
{
context.push(
DiagnosticKind::from(WhitespaceBeforeCloseBracket { symbol }),
let mut diagnostic = Diagnostic::new(
WhitespaceBeforeCloseBracket { symbol },
TextRange::at(token.start() - offset, offset),
);
if autofix_before_close_bracket {
diagnostic.set_fix(Fix::automatic(Edit::range_deletion(
diagnostic.range(),
)));
}
context.push_diagnostic(diagnostic);
}
}
}
@ -146,10 +179,16 @@ pub(crate) fn extraneous_whitespace(line: &LogicalLine, context: &mut LogicalLin
if let (Whitespace::Single | Whitespace::Many | Whitespace::Tab, offset) =
line.leading_whitespace(token)
{
context.push(
DiagnosticKind::from(WhitespaceBeforePunctuation { symbol }),
let mut diagnostic = Diagnostic::new(
WhitespaceBeforePunctuation { symbol },
TextRange::at(token.start() - offset, offset),
);
if autofix_before_punctuation {
diagnostic.set_fix(Fix::automatic(Edit::range_deletion(
diagnostic.range(),
)));
}
context.push_diagnostic(diagnostic);
}
}
}

View file

@ -1,7 +1,7 @@
---
source: crates/ruff/src/rules/pycodestyle/mod.rs
---
E20.py:2:6: E201 Whitespace after '('
E20.py:2:6: E201 [*] Whitespace after '('
|
2 | #: E201:1:6
3 | spam( ham[1], {eggs: 2})
@ -9,8 +9,17 @@ E20.py:2:6: E201 Whitespace after '('
4 | #: E201:1:10
5 | spam(ham[ 1], {eggs: 2})
|
= help: Remove whitespace before '('
E20.py:4:10: E201 Whitespace after '['
Fix
1 1 | #: E201:1:6
2 |-spam( ham[1], {eggs: 2})
2 |+spam(ham[1], {eggs: 2})
3 3 | #: E201:1:10
4 4 | spam(ham[ 1], {eggs: 2})
5 5 | #: E201:1:15
E20.py:4:10: E201 [*] Whitespace after '['
|
4 | spam( ham[1], {eggs: 2})
5 | #: E201:1:10
@ -19,8 +28,19 @@ E20.py:4:10: E201 Whitespace after '['
7 | #: E201:1:15
8 | spam(ham[1], { eggs: 2})
|
= help: Remove whitespace before '['
E20.py:6:15: E201 Whitespace after '{'
Fix
1 1 | #: E201:1:6
2 2 | spam( ham[1], {eggs: 2})
3 3 | #: E201:1:10
4 |-spam(ham[ 1], {eggs: 2})
4 |+spam(ham[1], {eggs: 2})
5 5 | #: E201:1:15
6 6 | spam(ham[1], { eggs: 2})
7 7 | #: E201:1:6
E20.py:6:15: E201 [*] Whitespace after '{'
|
6 | spam(ham[ 1], {eggs: 2})
7 | #: E201:1:15
@ -29,8 +49,19 @@ E20.py:6:15: E201 Whitespace after '{'
9 | #: E201:1:6
10 | spam( ham[1], {eggs: 2})
|
= help: Remove whitespace before '{'
E20.py:8:6: E201 Whitespace after '('
Fix
3 3 | #: E201:1:10
4 4 | spam(ham[ 1], {eggs: 2})
5 5 | #: E201:1:15
6 |-spam(ham[1], { eggs: 2})
6 |+spam(ham[1], {eggs: 2})
7 7 | #: E201:1:6
8 8 | spam( ham[1], {eggs: 2})
9 9 | #: E201:1:10
E20.py:8:6: E201 [*] Whitespace after '('
|
8 | spam(ham[1], { eggs: 2})
9 | #: E201:1:6
@ -39,8 +70,19 @@ E20.py:8:6: E201 Whitespace after '('
11 | #: E201:1:10
12 | spam(ham[ 1], {eggs: 2})
|
= help: Remove whitespace before '('
E20.py:10:10: E201 Whitespace after '['
Fix
5 5 | #: E201:1:15
6 6 | spam(ham[1], { eggs: 2})
7 7 | #: E201:1:6
8 |-spam( ham[1], {eggs: 2})
8 |+spam(ham[1], {eggs: 2})
9 9 | #: E201:1:10
10 10 | spam(ham[ 1], {eggs: 2})
11 11 | #: E201:1:15
E20.py:10:10: E201 [*] Whitespace after '['
|
10 | spam( ham[1], {eggs: 2})
11 | #: E201:1:10
@ -49,8 +91,19 @@ E20.py:10:10: E201 Whitespace after '['
13 | #: E201:1:15
14 | spam(ham[1], { eggs: 2})
|
= help: Remove whitespace before '['
E20.py:12:15: E201 Whitespace after '{'
Fix
7 7 | #: E201:1:6
8 8 | spam( ham[1], {eggs: 2})
9 9 | #: E201:1:10
10 |-spam(ham[ 1], {eggs: 2})
10 |+spam(ham[1], {eggs: 2})
11 11 | #: E201:1:15
12 12 | spam(ham[1], { eggs: 2})
13 13 | #: Okay
E20.py:12:15: E201 [*] Whitespace after '{'
|
12 | spam(ham[ 1], {eggs: 2})
13 | #: E201:1:15
@ -59,8 +112,19 @@ E20.py:12:15: E201 Whitespace after '{'
15 | #: Okay
16 | spam(ham[1], {eggs: 2})
|
= help: Remove whitespace before '{'
E20.py:81:6: E201 Whitespace after '['
Fix
9 9 | #: E201:1:10
10 10 | spam(ham[ 1], {eggs: 2})
11 11 | #: E201:1:15
12 |-spam(ham[1], { eggs: 2})
12 |+spam(ham[1], {eggs: 2})
13 13 | #: Okay
14 14 | spam(ham[1], {eggs: 2})
15 15 | #:
E20.py:81:6: E201 [*] Whitespace after '['
|
81 | #: E201:1:6
82 | spam[ ~ham]
@ -68,5 +132,16 @@ E20.py:81:6: E201 Whitespace after '['
83 |
84 | #: Okay
|
= help: Remove whitespace before '['
Fix
78 78 | #:
79 79 |
80 80 | #: E201:1:6
81 |-spam[ ~ham]
81 |+spam[~ham]
82 82 |
83 83 | #: Okay
84 84 | x = [ #

View file

@ -1,7 +1,7 @@
---
source: crates/ruff/src/rules/pycodestyle/mod.rs
---
E20.py:19:23: E202 Whitespace before ')'
E20.py:19:23: E202 [*] Whitespace before ')'
|
19 | #: E202:1:23
20 | spam(ham[1], {eggs: 2} )
@ -9,8 +9,19 @@ E20.py:19:23: E202 Whitespace before ')'
21 | #: E202:1:22
22 | spam(ham[1], {eggs: 2 })
|
= help: Remove whitespace before ')'
E20.py:21:22: E202 Whitespace before '}'
Fix
16 16 |
17 17 |
18 18 | #: E202:1:23
19 |-spam(ham[1], {eggs: 2} )
19 |+spam(ham[1], {eggs: 2})
20 20 | #: E202:1:22
21 21 | spam(ham[1], {eggs: 2 })
22 22 | #: E202:1:11
E20.py:21:22: E202 [*] Whitespace before '}'
|
21 | spam(ham[1], {eggs: 2} )
22 | #: E202:1:22
@ -19,8 +30,19 @@ E20.py:21:22: E202 Whitespace before '}'
24 | #: E202:1:11
25 | spam(ham[1 ], {eggs: 2})
|
= help: Remove whitespace before '}'
E20.py:23:11: E202 Whitespace before ']'
Fix
18 18 | #: E202:1:23
19 19 | spam(ham[1], {eggs: 2} )
20 20 | #: E202:1:22
21 |-spam(ham[1], {eggs: 2 })
21 |+spam(ham[1], {eggs: 2})
22 22 | #: E202:1:11
23 23 | spam(ham[1 ], {eggs: 2})
24 24 | #: E202:1:23
E20.py:23:11: E202 [*] Whitespace before ']'
|
23 | spam(ham[1], {eggs: 2 })
24 | #: E202:1:11
@ -29,8 +51,19 @@ E20.py:23:11: E202 Whitespace before ']'
26 | #: E202:1:23
27 | spam(ham[1], {eggs: 2} )
|
= help: Remove whitespace before ']'
E20.py:25:23: E202 Whitespace before ')'
Fix
20 20 | #: E202:1:22
21 21 | spam(ham[1], {eggs: 2 })
22 22 | #: E202:1:11
23 |-spam(ham[1 ], {eggs: 2})
23 |+spam(ham[1], {eggs: 2})
24 24 | #: E202:1:23
25 25 | spam(ham[1], {eggs: 2} )
26 26 | #: E202:1:22
E20.py:25:23: E202 [*] Whitespace before ')'
|
25 | spam(ham[1 ], {eggs: 2})
26 | #: E202:1:23
@ -39,8 +72,19 @@ E20.py:25:23: E202 Whitespace before ')'
28 | #: E202:1:22
29 | spam(ham[1], {eggs: 2 })
|
= help: Remove whitespace before ')'
E20.py:27:22: E202 Whitespace before '}'
Fix
22 22 | #: E202:1:11
23 23 | spam(ham[1 ], {eggs: 2})
24 24 | #: E202:1:23
25 |-spam(ham[1], {eggs: 2} )
25 |+spam(ham[1], {eggs: 2})
26 26 | #: E202:1:22
27 27 | spam(ham[1], {eggs: 2 })
28 28 | #: E202:1:11
E20.py:27:22: E202 [*] Whitespace before '}'
|
27 | spam(ham[1], {eggs: 2} )
28 | #: E202:1:22
@ -49,8 +93,19 @@ E20.py:27:22: E202 Whitespace before '}'
30 | #: E202:1:11
31 | spam(ham[1 ], {eggs: 2})
|
= help: Remove whitespace before '}'
E20.py:29:11: E202 Whitespace before ']'
Fix
24 24 | #: E202:1:23
25 25 | spam(ham[1], {eggs: 2} )
26 26 | #: E202:1:22
27 |-spam(ham[1], {eggs: 2 })
27 |+spam(ham[1], {eggs: 2})
28 28 | #: E202:1:11
29 29 | spam(ham[1 ], {eggs: 2})
30 30 | #: Okay
E20.py:29:11: E202 [*] Whitespace before ']'
|
29 | spam(ham[1], {eggs: 2 })
30 | #: E202:1:11
@ -59,5 +114,16 @@ E20.py:29:11: E202 Whitespace before ']'
32 | #: Okay
33 | spam(ham[1], {eggs: 2})
|
= help: Remove whitespace before ']'
Fix
26 26 | #: E202:1:22
27 27 | spam(ham[1], {eggs: 2 })
28 28 | #: E202:1:11
29 |-spam(ham[1 ], {eggs: 2})
29 |+spam(ham[1], {eggs: 2})
30 30 | #: Okay
31 31 | spam(ham[1], {eggs: 2})
32 32 |

View file

@ -1,7 +1,7 @@
---
source: crates/ruff/src/rules/pycodestyle/mod.rs
---
E20.py:51:10: E203 Whitespace before ':'
E20.py:51:10: E203 [*] Whitespace before ':'
|
51 | #: E203:1:10
52 | if x == 4 :
@ -9,8 +9,19 @@ E20.py:51:10: E203 Whitespace before ':'
53 | print x, y
54 | x, y = y, x
|
= help: Remove whitespace before ':'
E20.py:55:10: E203 Whitespace before ':'
Fix
48 48 |
49 49 |
50 50 | #: E203:1:10
51 |-if x == 4 :
51 |+if x == 4:
52 52 | print x, y
53 53 | x, y = y, x
54 54 | #: E203:1:10
E20.py:55:10: E203 [*] Whitespace before ':'
|
55 | x, y = y, x
56 | #: E203:1:10
@ -19,8 +30,19 @@ E20.py:55:10: E203 Whitespace before ':'
58 | print x, y
59 | x, y = y, x
|
= help: Remove whitespace before ':'
E20.py:60:15: E203 Whitespace before ';'
Fix
52 52 | print x, y
53 53 | x, y = y, x
54 54 | #: E203:1:10
55 |-if x == 4 :
55 |+if x == 4:
56 56 | print x, y
57 57 | x, y = y, x
58 58 | #: E203:2:15 E702:2:16
E20.py:60:15: E203 [*] Whitespace before ';'
|
60 | #: E203:2:15 E702:2:16
61 | if x == 4:
@ -29,8 +51,19 @@ E20.py:60:15: E203 Whitespace before ';'
63 | #: E203:2:15 E702:2:16
64 | if x == 4:
|
= help: Remove whitespace before ';'
E20.py:63:15: E203 Whitespace before ';'
Fix
57 57 | x, y = y, x
58 58 | #: E203:2:15 E702:2:16
59 59 | if x == 4:
60 |- print x, y ; x, y = y, x
60 |+ print x, y; x, y = y, x
61 61 | #: E203:2:15 E702:2:16
62 62 | if x == 4:
63 63 | print x, y ; x, y = y, x
E20.py:63:15: E203 [*] Whitespace before ';'
|
63 | #: E203:2:15 E702:2:16
64 | if x == 4:
@ -39,8 +72,19 @@ E20.py:63:15: E203 Whitespace before ';'
66 | #: E203:3:13
67 | if x == 4:
|
= help: Remove whitespace before ';'
E20.py:67:13: E203 Whitespace before ','
Fix
60 60 | print x, y ; x, y = y, x
61 61 | #: E203:2:15 E702:2:16
62 62 | if x == 4:
63 |- print x, y ; x, y = y, x
63 |+ print x, y; x, y = y, x
64 64 | #: E203:3:13
65 65 | if x == 4:
66 66 | print x, y
E20.py:67:13: E203 [*] Whitespace before ','
|
67 | if x == 4:
68 | print x, y
@ -49,8 +93,19 @@ E20.py:67:13: E203 Whitespace before ','
70 | #: E203:3:13
71 | if x == 4:
|
= help: Remove whitespace before ','
E20.py:71:13: E203 Whitespace before ','
Fix
64 64 | #: E203:3:13
65 65 | if x == 4:
66 66 | print x, y
67 |- x, y = y , x
67 |+ x, y = y, x
68 68 | #: E203:3:13
69 69 | if x == 4:
70 70 | print x, y
E20.py:71:13: E203 [*] Whitespace before ','
|
71 | if x == 4:
72 | print x, y
@ -59,5 +114,16 @@ E20.py:71:13: E203 Whitespace before ','
74 | #: Okay
75 | if x == 4:
|
= help: Remove whitespace before ','
Fix
68 68 | #: E203:3:13
69 69 | if x == 4:
70 70 | print x, y
71 |- x, y = y , x
71 |+ x, y = y, x
72 72 | #: Okay
73 73 | if x == 4:
74 74 | print x, y