diff --git a/crates/ruff/src/rules/pycodestyle/rules/logical_lines/mod.rs b/crates/ruff/src/rules/pycodestyle/rules/logical_lines/mod.rs index 52965ff8f85610..94d07ed9ff002f 100644 --- a/crates/ruff/src/rules/pycodestyle/rules/logical_lines/mod.rs +++ b/crates/ruff/src/rules/pycodestyle/rules/logical_lines/mod.rs @@ -361,10 +361,12 @@ impl Whitespace { fn leading(content: &str) -> (Self, TextSize) { let mut count = 0u32; let mut len = TextSize::default(); + let mut has_tabs = false; for c in content.chars() { if c == '\t' { - return (Self::Tab, len + c.text_len()); + has_tabs = true; + len += c.text_len(); } else if matches!(c, '\n' | '\r') { break; } else if c.is_whitespace() { @@ -375,20 +377,26 @@ impl Whitespace { } } - match count { - 0 => (Whitespace::None, len), - 1 => (Whitespace::Single, len), - _ => (Whitespace::Many, len), + if has_tabs { + (Whitespace::Tab, len) + } else { + match count { + 0 => (Whitespace::None, len), + 1 => (Whitespace::Single, len), + _ => (Whitespace::Many, len), + } } } fn trailing(content: &str) -> (Self, TextSize) { let mut len = TextSize::default(); let mut count = 0usize; + let mut has_tabs = false; for c in content.chars().rev() { if c == '\t' { - return (Self::Tab, len + c.text_len()); + has_tabs = true; + len += c.text_len(); } else if matches!(c, '\n' | '\r') { // Indent return (Self::None, TextSize::default()); @@ -400,15 +408,19 @@ impl Whitespace { } } - match count { - 0 => (Self::None, TextSize::default()), - 1 => (Self::Single, len), - _ => { - if len == content.text_len() { - // All whitespace up to the start of the line -> Indent - (Self::None, TextSize::default()) - } else { - (Self::Many, len) + if has_tabs { + (Self::Tab, len) + } else { + match count { + 0 => (Self::None, TextSize::default()), + 1 => (Self::Single, len), + _ => { + if len == content.text_len() { + // All whitespace up to the start of the line -> Indent + (Self::None, TextSize::default()) + } else { + (Self::Many, len) + } } } } 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 35cb722185caf6..cbb6516a49944c 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 @@ -6,7 +6,7 @@ E27.py:10:9: E273 Tab after keyword 10 | if 1: 11 | #: E273 12 | True and False - | ^^^^ E273 + | ^^^^^^^^ E273 13 | #: E273 E274 14 | True and False | @@ -16,7 +16,7 @@ E27.py:12:5: E273 Tab after keyword 12 | True and False 13 | #: E273 E274 14 | True and False - | ^^^^ E273 + | ^^^^^^^^ E273 15 | #: E271 16 | a and 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 e276c751274980..35dbb7428b46d3 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 @@ -1,22 +1,22 @@ --- source: crates/ruff/src/rules/pycodestyle/mod.rs --- -E27.py:28:3: E274 Tab before keyword +E27.py:28:2: E274 Tab before keyword | 28 | a and b 29 | #: E274 30 | a and b - | ^^^^ E274 + | ^^^^^^^^ E274 31 | #: E273 E274 32 | this and False | -E27.py:30:6: E274 Tab before keyword +E27.py:30:5: E274 Tab before keyword | 30 | a and b 31 | #: E273 E274 32 | this and False - | ^^^^ E274 + | ^^^^^^^^ E274 33 | #: Okay 34 | from u import (a, b) |