mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-14 18:01:43 +00:00
[pycodestyle] Do not trigger E225 and E275 when the next token is a ')' (#10315)
## Summary Fixes #10295. `E225` (`Missing whitespace around operator`) and `E275` (`Missing whitespace after keyword`) try to add a white space even when the next character is a `)` (which is a syntax error in most cases, the exceptions already being handled). This causes `E202` (`Whitespace before close bracket`) to try to remove the added whitespace, resulting in an infinite loop when `E225`/`E275` re-add it. This PR adds an exception in `E225` and `E275` to not trigger in case the next token is a `)`. It is a bit simplistic, but it solves the example given in the issue without introducing a change in behavior (according to the fixtures). ## Test Plan `cargo test` and the `ruff-ecosystem` check were used to check that the PR's changes do not have side-effects. A new fixture was added to check that running the 3 rules on the example given in the issue does not cause ruff to fail to converge.
This commit is contained in:
parent
bc693ea13a
commit
8d73866f70
5 changed files with 44 additions and 1 deletions
1
crates/ruff_linter/resources/test/fixtures/pycodestyle/E2_syntax_error.py
vendored
Normal file
1
crates/ruff_linter/resources/test/fixtures/pycodestyle/E2_syntax_error.py
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
a = (1 or)
|
||||||
|
|
@ -148,6 +148,23 @@ mod tests {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tests the compatibility of E2 rules (E202, E225 and E275) on syntactically incorrect code.
|
||||||
|
#[test]
|
||||||
|
fn white_space_syntax_error_compatibility() -> Result<()> {
|
||||||
|
let diagnostics = test_path(
|
||||||
|
Path::new("pycodestyle").join("E2_syntax_error.py"),
|
||||||
|
&settings::LinterSettings {
|
||||||
|
..settings::LinterSettings::for_rules([
|
||||||
|
Rule::MissingWhitespaceAroundOperator,
|
||||||
|
Rule::MissingWhitespaceAfterKeyword,
|
||||||
|
Rule::WhitespaceBeforeCloseBracket,
|
||||||
|
])
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
assert_messages!(diagnostics);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test_case(Rule::BlankLineBetweenMethods, Path::new("E30.py"))]
|
#[test_case(Rule::BlankLineBetweenMethods, Path::new("E30.py"))]
|
||||||
#[test_case(Rule::BlankLinesTopLevel, Path::new("E30.py"))]
|
#[test_case(Rule::BlankLinesTopLevel, Path::new("E30.py"))]
|
||||||
#[test_case(Rule::TooManyBlankLines, Path::new("E30.py"))]
|
#[test_case(Rule::TooManyBlankLines, Path::new("E30.py"))]
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,13 @@ pub(crate) fn missing_whitespace_after_keyword(
|
||||||
|| tok0_kind == TokenKind::Yield && tok1_kind == TokenKind::Rpar
|
|| tok0_kind == TokenKind::Yield && tok1_kind == TokenKind::Rpar
|
||||||
|| matches!(
|
|| matches!(
|
||||||
tok1_kind,
|
tok1_kind,
|
||||||
TokenKind::Colon | TokenKind::Newline | TokenKind::NonLogicalNewline
|
TokenKind::Colon
|
||||||
|
| TokenKind::Newline
|
||||||
|
| TokenKind::NonLogicalNewline
|
||||||
|
// In the event of a syntax error, do not attempt to add a whitespace.
|
||||||
|
| TokenKind::Rpar
|
||||||
|
| TokenKind::Rsqb
|
||||||
|
| TokenKind::Rbrace
|
||||||
))
|
))
|
||||||
&& tok0.end() == tok1.start()
|
&& tok0.end() == tok1.start()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,21 @@ pub(crate) fn missing_whitespace_around_operator(
|
||||||
} else {
|
} else {
|
||||||
NeedsSpace::No
|
NeedsSpace::No
|
||||||
}
|
}
|
||||||
|
} else if tokens.peek().is_some_and(|token| {
|
||||||
|
matches!(
|
||||||
|
token.kind(),
|
||||||
|
TokenKind::Rpar | TokenKind::Rsqb | TokenKind::Rbrace
|
||||||
|
)
|
||||||
|
}) {
|
||||||
|
// There should not be a closing bracket directly after a token, as it is a syntax
|
||||||
|
// error. For example:
|
||||||
|
// ```
|
||||||
|
// 1+)
|
||||||
|
// ```
|
||||||
|
//
|
||||||
|
// However, allow it in order to prevent entering an infinite loop in which E225 adds a
|
||||||
|
// space only for E202 to remove it.
|
||||||
|
NeedsSpace::No
|
||||||
} else if is_whitespace_needed(kind) {
|
} else if is_whitespace_needed(kind) {
|
||||||
NeedsSpace::Yes
|
NeedsSpace::Yes
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_linter/src/rules/pycodestyle/mod.rs
|
||||||
|
---
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue