Skip to content

Commit

Permalink
Fix E251 false positive inside f-strings (#7894)
Browse files Browse the repository at this point in the history
## Summary

This PR fixes the bug where the rule `E251` was being triggered on a equal token
inside a f-string which was used in the context of debug expressions.

For example, the following was being flagged before the fix:

```python
print(f"{foo = }")
```

But, now it is not. This leads to false negatives such as:

```python
print(f"{foo(a = 1)}")
```

One solution would be to know if the opened parentheses was inside a f-string or
not. If it was then we can continue flagging until it's closed. If not, then we
should not flag it.

## Test Plan

Add new test cases and check that they don't raise any false positives.

fixes: #7882
  • Loading branch information
dhruvmanila authored Oct 12, 2023
1 parent b243840 commit 4454fbf
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 1 deletion.
5 changes: 5 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/pycodestyle/E25.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,8 @@ def add(a: int = _default(name='f')):
f"{a:=1}"
f"{foo(a=1)}"
f"normal {f"{a=}"} normal"

# Okay as the `=` is used inside a f-string...
print(f"{foo = }")
# ...but then it creates false negatives for now
print(f"{foo(a = 1)}")
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ pub(crate) fn whitespace_around_named_parameter_equals(
context: &mut LogicalLinesContext,
) {
let mut parens = 0u32;
let mut fstrings = 0u32;
let mut annotated_func_arg = false;
let mut prev_end = TextSize::default();

Expand All @@ -108,6 +109,8 @@ pub(crate) fn whitespace_around_named_parameter_equals(
}

match kind {
TokenKind::FStringStart => fstrings += 1,
TokenKind::FStringEnd => fstrings = fstrings.saturating_sub(1),
TokenKind::Lpar | TokenKind::Lsqb => {
parens = parens.saturating_add(1);
}
Expand All @@ -124,7 +127,7 @@ pub(crate) fn whitespace_around_named_parameter_equals(
TokenKind::Comma if parens == 1 => {
annotated_func_arg = false;
}
TokenKind::Equal if parens > 0 => {
TokenKind::Equal if parens > 0 && fstrings == 0 => {
if annotated_func_arg && parens == 1 {
let start = token.start();
if start == prev_end && prev_end != TextSize::new(0) {
Expand Down

0 comments on commit 4454fbf

Please sign in to comment.