From a1515e86300fe5928d9b526c6a104503f88809e6 Mon Sep 17 00:00:00 2001 From: Jonathan Plasse <13716151+JonathanPlasse@users.noreply.github.com> Date: Thu, 4 May 2023 18:40:35 +0200 Subject: [PATCH 1/4] Fix replace_whitespace() tabulation to space --- crates/ruff/src/message/text.rs | 27 ++++++++++++------- ...les__pycodestyle__tests__E101_E101.py.snap | 8 +++--- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/crates/ruff/src/message/text.rs b/crates/ruff/src/message/text.rs index 547cb64e77a3c0..264cad2ad309b3 100644 --- a/crates/ruff/src/message/text.rs +++ b/crates/ruff/src/message/text.rs @@ -12,6 +12,7 @@ use ruff_text_size::{TextRange, TextSize}; use std::borrow::Cow; use std::fmt::{Display, Formatter}; use std::io::Write; +use unicode_width::UnicodeWidthChar; bitflags! { #[derive(Default)] @@ -245,36 +246,42 @@ impl Display for MessageCodeFrame<'_> { } fn replace_whitespace(source: &str, annotation_range: TextRange) -> SourceCode { - static TAB_SIZE: TextSize = TextSize::new(4); + static TAB_SIZE: u32 = 4; // TODO(jonathan): use `pycodestyle.tab-size` let mut result = String::new(); let mut last_end = 0; let mut range = annotation_range; let mut column = 0; + let mut column_offset = 0; - for (index, m) in source.match_indices(['\t', '\n', '\r']) { - match m { - "\t" => { - let tab_width = TAB_SIZE - TextSize::new(column % 4); + for (index, c) in source.chars().enumerate() { + match c { + '\t' => { + let tab_width = TAB_SIZE - (column + column_offset) % TAB_SIZE; + column_offset += tab_width; if index < usize::from(annotation_range.start()) { - range += tab_width - TextSize::new(1); + range += TextSize::new(tab_width - 1); } else if index < usize::from(annotation_range.end()) { - range = range.add_end(tab_width - TextSize::new(1)); + range = range.add_end(TextSize::new(tab_width - 1)); } result.push_str(&source[last_end..index]); - for _ in 0..u32::from(tab_width) { + for _ in 0..tab_width { result.push(' '); } last_end = index + 1; } - "\n" | "\r" => { + '\n' | '\r' => { column = 0; + column_offset = 0; + } + #[allow(clippy::cast_possible_truncation)] + _ => { + column += c.width().unwrap_or(0) as u32; } - _ => unreachable!(), } } diff --git a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E101_E101.py.snap b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E101_E101.py.snap index d1b7d11aee8f32..1333b7fae39d56 100644 --- a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E101_E101.py.snap +++ b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E101_E101.py.snap @@ -15,8 +15,8 @@ E101.py:15:1: E101 Indentation contains mixed spaces and tabs | 15 | def func_mixed_start_with_space(): 16 | # E101 -17 | print("mixed starts with space") - | ^^^^^^^^^^^^^^^^^^^^ E101 +17 | print("mixed starts with space") + | ^^^^^^^^^^^^^^^ E101 18 | 19 | def xyz(): | @@ -25,8 +25,8 @@ E101.py:19:1: E101 Indentation contains mixed spaces and tabs | 19 | def xyz(): 20 | # E101 -21 | print("xyz"); - | ^^^^^^^ E101 +21 | print("xyz"); + | ^^^^ E101 | From 8c820510e1550158b63078c3b65604b1b2c8b04c Mon Sep 17 00:00:00 2001 From: Jonathan Plasse <13716151+JonathanPlasse@users.noreply.github.com> Date: Thu, 4 May 2023 18:47:21 +0200 Subject: [PATCH 2/4] Remove unnecessary column_offset --- crates/ruff/src/message/text.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/ruff/src/message/text.rs b/crates/ruff/src/message/text.rs index 264cad2ad309b3..0f229de4af5ace 100644 --- a/crates/ruff/src/message/text.rs +++ b/crates/ruff/src/message/text.rs @@ -252,13 +252,12 @@ fn replace_whitespace(source: &str, annotation_range: TextRange) -> SourceCode { let mut last_end = 0; let mut range = annotation_range; let mut column = 0; - let mut column_offset = 0; for (index, c) in source.chars().enumerate() { match c { '\t' => { - let tab_width = TAB_SIZE - (column + column_offset) % TAB_SIZE; - column_offset += tab_width; + let tab_width = TAB_SIZE - column % TAB_SIZE; + column += tab_width; if index < usize::from(annotation_range.start()) { range += TextSize::new(tab_width - 1); @@ -276,7 +275,6 @@ fn replace_whitespace(source: &str, annotation_range: TextRange) -> SourceCode { } '\n' | '\r' => { column = 0; - column_offset = 0; } #[allow(clippy::cast_possible_truncation)] _ => { From fe6af22452ac8dcb9722866e99b303e616f8f85a Mon Sep 17 00:00:00 2001 From: Jonathan Plasse <13716151+JonathanPlasse@users.noreply.github.com> Date: Thu, 4 May 2023 18:58:11 +0200 Subject: [PATCH 3/4] Update all snapshots --- ...__rules__pycodestyle__tests__E201_E20.py.snap | 16 ++++++++-------- ...__rules__pycodestyle__tests__E202_E20.py.snap | 16 ++++++++-------- ...__rules__pycodestyle__tests__E203_E20.py.snap | 4 ++-- ...__rules__pycodestyle__tests__E223_E22.py.snap | 2 +- ...__rules__pycodestyle__tests__E271_E27.py.snap | 2 +- ...__rules__pycodestyle__tests__E272_E27.py.snap | 2 +- ...__rules__pycodestyle__tests__E273_E27.py.snap | 14 +++++++------- ...__rules__pycodestyle__tests__E274_E27.py.snap | 12 ++++++------ 8 files changed, 34 insertions(+), 34 deletions(-) diff --git a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E201_E20.py.snap b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E201_E20.py.snap index 198479926f3aa5..2308d508906b44 100644 --- a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E201_E20.py.snap +++ b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E201_E20.py.snap @@ -27,34 +27,34 @@ E20.py:6:15: E201 Whitespace after '(' 8 | spam(ham[1], { eggs: 2}) | E201 9 | #: E201:1:6 -10 | spam( ham[1], {eggs: 2}) +10 | spam( ham[1], {eggs: 2}) | E20.py:8:6: E201 Whitespace after '(' | 8 | spam(ham[1], { eggs: 2}) 9 | #: E201:1:6 -10 | spam( ham[1], {eggs: 2}) +10 | spam( ham[1], {eggs: 2}) | E201 11 | #: E201:1:10 -12 | spam(ham[ 1], {eggs: 2}) +12 | spam(ham[ 1], {eggs: 2}) | E20.py:10:10: E201 Whitespace after '(' | -10 | spam( ham[1], {eggs: 2}) +10 | spam( ham[1], {eggs: 2}) 11 | #: E201:1:10 -12 | spam(ham[ 1], {eggs: 2}) +12 | spam(ham[ 1], {eggs: 2}) | E201 13 | #: E201:1:15 -14 | spam(ham[1], { eggs: 2}) +14 | spam(ham[1], { eggs: 2}) | E20.py:12:15: E201 Whitespace after '(' | -12 | spam(ham[ 1], {eggs: 2}) +12 | spam(ham[ 1], {eggs: 2}) 13 | #: E201:1:15 -14 | spam(ham[1], { eggs: 2}) +14 | spam(ham[1], { eggs: 2}) | E201 15 | #: Okay 16 | spam(ham[1], {eggs: 2}) diff --git a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E202_E20.py.snap b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E202_E20.py.snap index 1215dbb53bb98a..69edd156d116b8 100644 --- a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E202_E20.py.snap +++ b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E202_E20.py.snap @@ -27,34 +27,34 @@ E20.py:23:11: E202 Whitespace before ')' 25 | spam(ham[1 ], {eggs: 2}) | E202 26 | #: E202:1:23 -27 | spam(ham[1], {eggs: 2} ) +27 | spam(ham[1], {eggs: 2} ) | E20.py:25:23: E202 Whitespace before ')' | 25 | spam(ham[1 ], {eggs: 2}) 26 | #: E202:1:23 -27 | spam(ham[1], {eggs: 2} ) +27 | spam(ham[1], {eggs: 2} ) | E202 28 | #: E202:1:22 -29 | spam(ham[1], {eggs: 2 }) +29 | spam(ham[1], {eggs: 2 }) | E20.py:27:22: E202 Whitespace before ')' | -27 | spam(ham[1], {eggs: 2} ) +27 | spam(ham[1], {eggs: 2} ) 28 | #: E202:1:22 -29 | spam(ham[1], {eggs: 2 }) +29 | spam(ham[1], {eggs: 2 }) | E202 30 | #: E202:1:11 -31 | spam(ham[1 ], {eggs: 2}) +31 | spam(ham[1 ], {eggs: 2}) | E20.py:29:11: E202 Whitespace before ')' | -29 | spam(ham[1], {eggs: 2 }) +29 | spam(ham[1], {eggs: 2 }) 30 | #: E202:1:11 -31 | spam(ham[1 ], {eggs: 2}) +31 | spam(ham[1 ], {eggs: 2}) | E202 32 | #: Okay 33 | spam(ham[1], {eggs: 2}) diff --git a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E203_E20.py.snap b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E203_E20.py.snap index b59e240bd7f461..de37bc5aaf6b98 100644 --- a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E203_E20.py.snap +++ b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E203_E20.py.snap @@ -14,7 +14,7 @@ E20.py:55:10: E203 Whitespace before ',', ';', or ':' | 55 | x, y = y, x 56 | #: E203:1:10 -57 | if x == 4 : +57 | if x == 4 : | E203 58 | print x, y 59 | x, y = y, x @@ -34,7 +34,7 @@ E20.py:63:15: E203 Whitespace before ',', ';', or ':' | 63 | #: E203:2:15 E702:2:16 64 | if x == 4: -65 | print x, y ; x, y = y, x +65 | print x, y ; x, y = y, x | E203 66 | #: E203:3:13 67 | if x == 4: diff --git a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E223_E22.py.snap b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E223_E22.py.snap index 0e7405603f814f..0235b13891c239 100644 --- a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E223_E22.py.snap +++ b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E223_E22.py.snap @@ -5,7 +5,7 @@ E22.py:43:2: E223 Tab before operator | 43 | #: E223 44 | foobart = 4 -45 | a = 3 # aligned with tab +45 | a = 3 # aligned with tab | E223 46 | #: | diff --git a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E271_E27.py.snap b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E271_E27.py.snap index af6e1e52f0b063..d4e838c49f9fd4 100644 --- a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E271_E27.py.snap +++ b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E271_E27.py.snap @@ -33,7 +33,7 @@ E27.py:8:3: E271 Multiple spaces after keyword E27.py:14:6: E271 Multiple spaces after keyword | -14 | True and False +14 | True and False 15 | #: E271 16 | a and b | E271 diff --git a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E272_E27.py.snap b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E272_E27.py.snap index 1bc20e60e5be32..d295b4960296cc 100644 --- a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E272_E27.py.snap +++ b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E272_E27.py.snap @@ -28,7 +28,7 @@ E27.py:24:5: E272 Multiple spaces before keyword 26 | this and False | E272 27 | #: E273 -28 | a and b +28 | a and b | diff --git a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E273_E27.py.snap b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E273_E27.py.snap index 87dce5836355a9..ea55c2f8db9658 100644 --- a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E273_E27.py.snap +++ b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E273_E27.py.snap @@ -8,14 +8,14 @@ E27.py:10:9: E273 Tab after keyword 12 | True and False | E273 13 | #: E273 E274 -14 | True and False +14 | True and False | E27.py:12:5: E273 Tab after keyword | 12 | True and False 13 | #: E273 E274 -14 | True and False +14 | True and False | E273 15 | #: E271 16 | a and b @@ -25,7 +25,7 @@ E27.py:12:10: E273 Tab after keyword | 12 | True and False 13 | #: E273 E274 -14 | True and False +14 | True and False | E273 15 | #: E271 16 | a and b @@ -35,17 +35,17 @@ E27.py:26:6: E273 Tab after keyword | 26 | this and False 27 | #: E273 -28 | a and b +28 | a and b | E273 29 | #: E274 -30 | a and b +30 | a and b | E27.py:30:10: E273 Tab after keyword | -30 | a and b +30 | a and b 31 | #: E273 E274 -32 | this and False +32 | this and False | E273 33 | #: Okay 34 | from u import (a, b) diff --git a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E274_E27.py.snap b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E274_E27.py.snap index 1150a45c696c7b..f70b51e63dfb35 100644 --- a/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E274_E27.py.snap +++ b/crates/ruff/src/rules/pycodestyle/snapshots/ruff__rules__pycodestyle__tests__E274_E27.py.snap @@ -3,19 +3,19 @@ source: crates/ruff/src/rules/pycodestyle/mod.rs --- E27.py:28:3: E274 Tab before keyword | -28 | a and b +28 | a and b 29 | #: E274 -30 | a and b - | E274 +30 | a and b + | E274 31 | #: E273 E274 -32 | this and False +32 | this and False | E27.py:30:6: E274 Tab before keyword | -30 | a and b +30 | a and b 31 | #: E273 E274 -32 | this and False +32 | this and False | E274 33 | #: Okay 34 | from u import (a, b) From 7527fcde1bb030746dbe69a3dc49347fff33224e Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Mon, 8 May 2023 13:51:31 +0200 Subject: [PATCH 4/4] Use chars for columns and not char width. --- crates/ruff/src/message/text.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/ruff/src/message/text.rs b/crates/ruff/src/message/text.rs index 0f229de4af5ace..dcfb6f62bc5b6f 100644 --- a/crates/ruff/src/message/text.rs +++ b/crates/ruff/src/message/text.rs @@ -12,7 +12,6 @@ use ruff_text_size::{TextRange, TextSize}; use std::borrow::Cow; use std::fmt::{Display, Formatter}; use std::io::Write; -use unicode_width::UnicodeWidthChar; bitflags! { #[derive(Default)] @@ -276,9 +275,8 @@ fn replace_whitespace(source: &str, annotation_range: TextRange) -> SourceCode { '\n' | '\r' => { column = 0; } - #[allow(clippy::cast_possible_truncation)] _ => { - column += c.width().unwrap_or(0) as u32; + column += 1; } } }