add auto-fix for E273,274 (#8144)

## Summary

Introduce auto fix for `E273` and `E274`. This partially address #8120.

## Test Plan

Already covered.
This commit is contained in:
Weijie Guo 2023-10-24 00:31:08 +08:00 committed by GitHub
parent 92baa3591d
commit 39e45aa06f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 111 additions and 12 deletions

View file

@ -1,4 +1,4 @@
use ruff_diagnostics::Violation; use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix, Violation};
use ruff_macros::{derive_message_formats, violation}; use ruff_macros::{derive_message_formats, violation};
use ruff_text_size::{Ranged, TextRange}; use ruff_text_size::{Ranged, TextRange};
@ -74,11 +74,15 @@ impl Violation for MultipleSpacesBeforeKeyword {
#[violation] #[violation]
pub struct TabAfterKeyword; pub struct TabAfterKeyword;
impl Violation for TabAfterKeyword { impl AlwaysFixableViolation for TabAfterKeyword {
#[derive_message_formats] #[derive_message_formats]
fn message(&self) -> String { fn message(&self) -> String {
format!("Tab after keyword") format!("Tab after keyword")
} }
fn fix_title(&self) -> String {
format!("Replace with single space")
}
} }
/// ## What it does /// ## What it does
@ -99,11 +103,15 @@ impl Violation for TabAfterKeyword {
#[violation] #[violation]
pub struct TabBeforeKeyword; pub struct TabBeforeKeyword;
impl Violation for TabBeforeKeyword { impl AlwaysFixableViolation for TabBeforeKeyword {
#[derive_message_formats] #[derive_message_formats]
fn message(&self) -> String { fn message(&self) -> String {
format!("Tab before keyword") format!("Tab before keyword")
} }
fn fix_title(&self) -> String {
format!("Replace with single space")
}
} }
/// E271, E272, E273, E274 /// E271, E272, E273, E274
@ -117,7 +125,15 @@ pub(crate) fn whitespace_around_keywords(line: &LogicalLine, context: &mut Logic
match line.leading_whitespace(token) { match line.leading_whitespace(token) {
(Whitespace::Tab, offset) => { (Whitespace::Tab, offset) => {
let start = token.start(); let start = token.start();
context.push(TabBeforeKeyword, TextRange::at(start - offset, offset)); let mut diagnostic = Diagnostic::new(
TabBeforeKeyword,
TextRange::at(start - offset, offset),
);
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
" ".to_string(),
TextRange::at(start - offset, offset),
)));
context.push_diagnostic(diagnostic);
} }
(Whitespace::Many, offset) => { (Whitespace::Many, offset) => {
let start = token.start(); let start = token.start();
@ -132,7 +148,13 @@ pub(crate) fn whitespace_around_keywords(line: &LogicalLine, context: &mut Logic
match line.trailing_whitespace(token) { match line.trailing_whitespace(token) {
(Whitespace::Tab, len) => { (Whitespace::Tab, len) => {
context.push(TabAfterKeyword, TextRange::at(token.end(), len)); let mut diagnostic =
Diagnostic::new(TabAfterKeyword, TextRange::at(token.end(), len));
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
" ".to_string(),
TextRange::at(token.end(), len),
)));
context.push_diagnostic(diagnostic);
} }
(Whitespace::Many, len) => { (Whitespace::Many, len) => {
context.push(MultipleSpacesAfterKeyword, TextRange::at(token.end(), len)); context.push(MultipleSpacesAfterKeyword, TextRange::at(token.end(), len));

View file

@ -1,7 +1,7 @@
--- ---
source: crates/ruff_linter/src/rules/pycodestyle/mod.rs source: crates/ruff_linter/src/rules/pycodestyle/mod.rs
--- ---
E27.py:10:9: E273 Tab after keyword E27.py:10:9: E273 [*] Tab after keyword
| |
8 | if 1: 8 | if 1:
9 | #: E273 9 | #: E273
@ -10,8 +10,19 @@ E27.py:10:9: E273 Tab after keyword
11 | #: E273 E274 11 | #: E273 E274
12 | True and False 12 | True and False
| |
= help: Replace with single space
E27.py:12:5: E273 Tab after keyword Fix
7 7 | #: E271
8 8 | if 1:
9 9 | #: E273
10 |-True and False
10 |+True and False
11 11 | #: E273 E274
12 12 | True and False
13 13 | #: E271
E27.py:12:5: E273 [*] Tab after keyword
| |
10 | True and False 10 | True and False
11 | #: E273 E274 11 | #: E273 E274
@ -20,8 +31,19 @@ E27.py:12:5: E273 Tab after keyword
13 | #: E271 13 | #: E271
14 | a and b 14 | a and b
| |
= help: Replace with single space
E27.py:12:10: E273 Tab after keyword Fix
9 9 | #: E273
10 10 | True and False
11 11 | #: E273 E274
12 |-True and False
12 |+True and False
13 13 | #: E271
14 14 | a and b
15 15 | #: E271
E27.py:12:10: E273 [*] Tab after keyword
| |
10 | True and False 10 | True and False
11 | #: E273 E274 11 | #: E273 E274
@ -30,8 +52,19 @@ E27.py:12:10: E273 Tab after keyword
13 | #: E271 13 | #: E271
14 | a and b 14 | a and b
| |
= help: Replace with single space
E27.py:26:6: E273 Tab after keyword Fix
9 9 | #: E273
10 10 | True and False
11 11 | #: E273 E274
12 |-True and False
12 |+True and False
13 13 | #: E271
14 14 | a and b
15 15 | #: E271
E27.py:26:6: E273 [*] Tab after keyword
| |
24 | this and False 24 | this and False
25 | #: E273 25 | #: E273
@ -40,8 +73,19 @@ E27.py:26:6: E273 Tab after keyword
27 | #: E274 27 | #: E274
28 | a and b 28 | a and b
| |
= help: Replace with single space
E27.py:30:10: E273 Tab after keyword Fix
23 23 | #: E272
24 24 | this and False
25 25 | #: E273
26 |-a and b
26 |+a and b
27 27 | #: E274
28 28 | a and b
29 29 | #: E273 E274
E27.py:30:10: E273 [*] Tab after keyword
| |
28 | a and b 28 | a and b
29 | #: E273 E274 29 | #: E273 E274
@ -50,5 +94,16 @@ E27.py:30:10: E273 Tab after keyword
31 | #: Okay 31 | #: Okay
32 | from u import (a, b) 32 | from u import (a, b)
| |
= help: Replace with single space
Fix
27 27 | #: E274
28 28 | a and b
29 29 | #: E273 E274
30 |-this and False
30 |+this and False
31 31 | #: Okay
32 32 | from u import (a, b)
33 33 | from v import c, d

View file

@ -1,7 +1,7 @@
--- ---
source: crates/ruff_linter/src/rules/pycodestyle/mod.rs source: crates/ruff_linter/src/rules/pycodestyle/mod.rs
--- ---
E27.py:28:2: E274 Tab before keyword E27.py:28:2: E274 [*] Tab before keyword
| |
26 | a and b 26 | a and b
27 | #: E274 27 | #: E274
@ -10,8 +10,19 @@ E27.py:28:2: E274 Tab before keyword
29 | #: E273 E274 29 | #: E273 E274
30 | this and False 30 | this and False
| |
= help: Replace with single space
E27.py:30:5: E274 Tab before keyword Fix
25 25 | #: E273
26 26 | a and b
27 27 | #: E274
28 |-a and b
28 |+a and b
29 29 | #: E273 E274
30 30 | this and False
31 31 | #: Okay
E27.py:30:5: E274 [*] Tab before keyword
| |
28 | a and b 28 | a and b
29 | #: E273 E274 29 | #: E273 E274
@ -20,5 +31,16 @@ E27.py:30:5: E274 Tab before keyword
31 | #: Okay 31 | #: Okay
32 | from u import (a, b) 32 | from u import (a, b)
| |
= help: Replace with single space
Fix
27 27 | #: E274
28 28 | a and b
29 29 | #: E273 E274
30 |-this and False
30 |+this and False
31 31 | #: Okay
32 32 | from u import (a, b)
33 33 | from v import c, d