From f446cd43a62374e05966b9606f260287a5fbd349 Mon Sep 17 00:00:00 2001 From: augustelalande Date: Tue, 19 Mar 2024 00:48:14 -0400 Subject: [PATCH] fix bug --- .../test/fixtures/pycodestyle/E23.py | 30 ++- .../rules/logical_lines/missing_whitespace.rs | 19 +- ...__pycodestyle__tests__E231_E23.py.snap.new | 226 ++++++++++++++++++ 3 files changed, 264 insertions(+), 11 deletions(-) create mode 100644 crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E231_E23.py.snap.new diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E23.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E23.py index 2d7e70e99d4acc..0530428791e574 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/E23.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/E23.py @@ -47,4 +47,32 @@ def foo() -> None: {len(f's3://{self.s3_bucket_name}/'):1} #: Okay -a = (1, +a = (1,) + + +# https://github.com/astral-sh/ruff/issues/10113 +"""Minimal repo.""" + +def main() -> None: + """Primary function.""" + results = { + "k1": [1], + "k2":[2], + } + results_in_tuple = ( + { + "k1": [1], + "k2":[2], + }, + ) + results_in_list = [ + { + "k1": [1], + "k2":[2], + } + ] + results_in_list_first = [ + { + "k2":[2], + } + ] diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace.rs index 2da0664dc7eadc..9490ffdf8a9225 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/logical_lines/missing_whitespace.rs @@ -53,10 +53,9 @@ impl AlwaysFixableViolation for MissingWhitespace { /// E231 pub(crate) fn missing_whitespace(line: &LogicalLine, context: &mut LogicalLinesContext) { - let mut open_parentheses = 0u32; let mut fstrings = 0u32; - let mut prev_lsqb = TextSize::default(); - let mut prev_lbrace = TextSize::default(); + let mut lsqb_stack = vec![TextSize::default()]; + let mut lbrace_stack = vec![TextSize::default()]; let mut iter = line.tokens().iter().peekable(); while let Some(token) = iter.next() { @@ -65,14 +64,16 @@ pub(crate) fn missing_whitespace(line: &LogicalLine, context: &mut LogicalLinesC TokenKind::FStringStart => fstrings += 1, TokenKind::FStringEnd => fstrings = fstrings.saturating_sub(1), TokenKind::Lsqb if fstrings == 0 => { - open_parentheses = open_parentheses.saturating_add(1); - prev_lsqb = token.start(); + lsqb_stack.push(token.start()); } TokenKind::Rsqb if fstrings == 0 => { - open_parentheses = open_parentheses.saturating_sub(1); + lsqb_stack.pop(); } TokenKind::Lbrace if fstrings == 0 => { - prev_lbrace = token.start(); + lbrace_stack.push(token.start()); + } + TokenKind::Rbrace if fstrings == 0 => { + lbrace_stack.pop(); } TokenKind::Colon if fstrings > 0 => { // Colon in f-string, no space required. This will yield false @@ -96,9 +97,7 @@ pub(crate) fn missing_whitespace(line: &LogicalLine, context: &mut LogicalLinesC { if let Some(next_token) = iter.peek() { match (kind, next_token.kind()) { - (TokenKind::Colon, _) - if open_parentheses > 0 && prev_lsqb > prev_lbrace => - { + (TokenKind::Colon, _) if lsqb_stack.last() >= lbrace_stack.last() => { continue; // Slice syntax, no space required } (TokenKind::Comma, TokenKind::Rpar | TokenKind::Rsqb) => { diff --git a/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E231_E23.py.snap.new b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E231_E23.py.snap.new new file mode 100644 index 00000000000000..8d47cdc511d8bf --- /dev/null +++ b/crates/ruff_linter/src/rules/pycodestyle/snapshots/ruff_linter__rules__pycodestyle__tests__E231_E23.py.snap.new @@ -0,0 +1,226 @@ +--- +source: crates/ruff_linter/src/rules/pycodestyle/mod.rs +assertion_line: 153 +--- +E23.py:2:7: E231 [*] Missing whitespace after ',' + | +1 | #: E231 +2 | a = (1,2) + | ^ E231 +3 | #: E231 +4 | a[b1,:] + | + = help: Add missing whitespace + +ℹ Safe fix +1 1 | #: E231 +2 |-a = (1,2) + 2 |+a = (1, 2) +3 3 | #: E231 +4 4 | a[b1,:] +5 5 | #: E231 + +E23.py:4:5: E231 [*] Missing whitespace after ',' + | +2 | a = (1,2) +3 | #: E231 +4 | a[b1,:] + | ^ E231 +5 | #: E231 +6 | a = [{'a':''}] + | + = help: Add missing whitespace + +ℹ Safe fix +1 1 | #: E231 +2 2 | a = (1,2) +3 3 | #: E231 +4 |-a[b1,:] + 4 |+a[b1, :] +5 5 | #: E231 +6 6 | a = [{'a':''}] +7 7 | #: Okay + +E23.py:6:10: E231 [*] Missing whitespace after ':' + | +4 | a[b1,:] +5 | #: E231 +6 | a = [{'a':''}] + | ^ E231 +7 | #: Okay +8 | a = (4,) + | + = help: Add missing whitespace + +ℹ Safe fix +3 3 | #: E231 +4 4 | a[b1,:] +5 5 | #: E231 +6 |-a = [{'a':''}] + 6 |+a = [{'a': ''}] +7 7 | #: Okay +8 8 | a = (4,) +9 9 | b = (5, ) + +E23.py:19:10: E231 [*] Missing whitespace after ',' + | +17 | def foo() -> None: +18 | #: E231 +19 | if (1,2): + | ^ E231 +20 | pass + | + = help: Add missing whitespace + +ℹ Safe fix +16 16 | +17 17 | def foo() -> None: +18 18 | #: E231 +19 |- if (1,2): + 19 |+ if (1, 2): +20 20 | pass +21 21 | +22 22 | #: Okay + +E23.py:29:20: E231 [*] Missing whitespace after ':' + | +27 | mdtypes_template = { +28 | 'tag_full': [('mdtype', 'u4'), ('byte_count', 'u4')], +29 | 'tag_smalldata':[('byte_count_mdtype', 'u4'), ('data', 'S4')], + | ^ E231 +30 | } + | + = help: Add missing whitespace + +ℹ Safe fix +26 26 | #: E231:2:20 +27 27 | mdtypes_template = { +28 28 | 'tag_full': [('mdtype', 'u4'), ('byte_count', 'u4')], +29 |- 'tag_smalldata':[('byte_count_mdtype', 'u4'), ('data', 'S4')], + 29 |+ 'tag_smalldata': [('byte_count_mdtype', 'u4'), ('data', 'S4')], +30 30 | } +31 31 | +32 32 | # E231 + +E23.py:33:6: E231 [*] Missing whitespace after ',' + | +32 | # E231 +33 | f"{(a,b)}" + | ^ E231 +34 | +35 | # Okay because it's hard to differentiate between the usages of a colon in a f-string + | + = help: Add missing whitespace + +ℹ Safe fix +30 30 | } +31 31 | +32 32 | # E231 +33 |-f"{(a,b)}" + 33 |+f"{(a, b)}" +34 34 | +35 35 | # Okay because it's hard to differentiate between the usages of a colon in a f-string +36 36 | f"{a:=1}" + +E23.py:47:37: E231 [*] Missing whitespace after ':' + | +46 | #: E231 +47 | {len(f's3://{self.s3_bucket_name}/'):1} + | ^ E231 +48 | +49 | #: Okay + | + = help: Add missing whitespace + +ℹ Safe fix +44 44 | snapshot.file_uri[len(f's3://{self.s3_bucket_name}/'):] +45 45 | +46 46 | #: E231 +47 |-{len(f's3://{self.s3_bucket_name}/'):1} + 47 |+{len(f's3://{self.s3_bucket_name}/'): 1} +48 48 | +49 49 | #: Okay +50 50 | a = (1,) + +E23.py:60:13: E231 [*] Missing whitespace after ':' + | +58 | results = { +59 | "k1": [1], +60 | "k2":[2], + | ^ E231 +61 | } +62 | results_in_tuple = ( + | + = help: Add missing whitespace + +ℹ Safe fix +57 57 | """Primary function.""" +58 58 | results = { +59 59 | "k1": [1], +60 |- "k2":[2], + 60 |+ "k2": [2], +61 61 | } +62 62 | results_in_tuple = ( +63 63 | { + +E23.py:65:17: E231 [*] Missing whitespace after ':' + | +63 | { +64 | "k1": [1], +65 | "k2":[2], + | ^ E231 +66 | }, +67 | ) + | + = help: Add missing whitespace + +ℹ Safe fix +62 62 | results_in_tuple = ( +63 63 | { +64 64 | "k1": [1], +65 |- "k2":[2], + 65 |+ "k2": [2], +66 66 | }, +67 67 | ) +68 68 | results_in_list = [ + +E23.py:71:17: E231 [*] Missing whitespace after ':' + | +69 | { +70 | "k1": [1], +71 | "k2":[2], + | ^ E231 +72 | } +73 | ] + | + = help: Add missing whitespace + +ℹ Safe fix +68 68 | results_in_list = [ +69 69 | { +70 70 | "k1": [1], +71 |- "k2":[2], + 71 |+ "k2": [2], +72 72 | } +73 73 | ] +74 74 | results_in_list_first = [ + +E23.py:76:17: E231 [*] Missing whitespace after ':' + | +74 | results_in_list_first = [ +75 | { +76 | "k2":[2], + | ^ E231 +77 | } +78 | ] + | + = help: Add missing whitespace + +ℹ Safe fix +73 73 | ] +74 74 | results_in_list_first = [ +75 75 | { +76 |- "k2":[2], + 76 |+ "k2": [2], +77 77 | } +78 78 | ]