Skip to content

Commit 71c0da2

Browse files
Avoid nested loops in missing_whitespace (#3688)
1 parent 8a2d1a3 commit 71c0da2

File tree

1 file changed

+17
-16
lines changed

1 file changed

+17
-16
lines changed

crates/ruff/src/rules/pycodestyle/rules/missing_whitespace.rs

+17-16
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
#![allow(dead_code, unused_imports, unused_variables)]
22

3+
use itertools::Itertools;
34
use rustpython_parser::ast::Location;
4-
use rustpython_parser::Tok;
55

6-
use ruff_diagnostics::DiagnosticKind;
76
use ruff_diagnostics::Fix;
87
use ruff_diagnostics::Violation;
98
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic};
109
use ruff_macros::{derive_message_formats, violation};
1110
use ruff_python_ast::types::Range;
1211

13-
use crate::registry::AsRule;
14-
use crate::rules::pycodestyle::helpers::{is_keyword_token, is_singleton_token};
15-
1612
#[violation]
1713
pub struct MissingWhitespace {
1814
pub token: String,
@@ -40,21 +36,26 @@ pub fn missing_whitespace(
4036
indent_level: usize,
4137
) -> Vec<Diagnostic> {
4238
let mut diagnostics = vec![];
43-
for (idx, char) in line.chars().enumerate() {
44-
if idx + 1 == line.len() {
45-
break;
39+
40+
let mut num_lsqb = 0;
41+
let mut num_rsqb = 0;
42+
let mut prev_lsqb = None;
43+
let mut prev_lbrace = None;
44+
for (idx, (char, next_char)) in line.chars().tuple_windows().enumerate() {
45+
if char == '[' {
46+
num_lsqb += 1;
47+
prev_lsqb = Some(idx);
48+
} else if char == ']' {
49+
num_rsqb += 1;
50+
} else if char == '{' {
51+
prev_lbrace = Some(idx);
4652
}
47-
let next_char = line.chars().nth(idx + 1).unwrap();
4853

49-
if ",;:".contains(char) && !char::is_whitespace(next_char) {
50-
let before = &line[..idx];
51-
if char == ':'
52-
&& before.matches('[').count() > before.matches(']').count()
53-
&& before.rfind('{') < before.rfind('[')
54-
{
54+
if (char == ',' || char == ';' || char == ':') && !char::is_whitespace(next_char) {
55+
if char == ':' && num_lsqb > num_rsqb && prev_lsqb > prev_lbrace {
5556
continue; // Slice syntax, no space required
5657
}
57-
if char == ',' && ")]".contains(next_char) {
58+
if char == ',' && (next_char == ')' || next_char == ']') {
5859
continue; // Allow tuple with only one element: (3,)
5960
}
6061
if char == ':' && next_char == '=' {

0 commit comments

Comments
 (0)