-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[ruff] Suppress strings with backslashes in interpolations before Python 3.12 (RUF027)
#21069
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
|
Backslashes in f-strings aren’t the problem. >>> f"\n"
'\n'The problem is backslashes in f-string interpolations. >>> f"{'\n'}"
File "<stdin>", line 1
f"{'\n'}"
^
SyntaxError: f-string expression part cannot include a backslash |
Updated the RUF027 rule to only skip f-string suggestions for Python < 3.12 when backslashes appear in interpolations, not in the entire string. Adjusted test cases and snapshots to reflect this refined behavior.
ruff] Suppress strings with backslashes before Python 3.12 (RUF027)ruff] Suppress strings with backslashes in interpolations before Python 3.12 (RUF027)
|
I just worked on two issues for our syntax error related to this: #20867 and #20949. I think the fix here is similar to the incorrect code I had originally in the parser, which turned out to be too naive in the presence of nested interpolations. To summarize the two issues, code like this is valid on 3.11: >>> f"{1:\"d\"}"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Invalid format specifier '"d"' for object of type 'int'Note the In contrast, code like this is still invalid on 3.11 because it's in the expression part of a nested interpolation: >>> f'{1: abcd "{'aa'}" }'
File "<stdin>", line 1
f'{1: abcd "{'aa'}" }'
^^
SyntaxError: f-string: expecting '}'But the It might be fair to be more conservative here since it's almost definitely easier to implement, but I wanted to mention this since it was relevant. |
| literal: &ast::StringLiteral, | ||
| locator: &Locator, | ||
| semantic: &SemanticModel, | ||
| checker: &Checker, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could drop the locator and semantic arguments if we're passing the Checker they both come from. Alternatively, we could pass only the target_version, which is the only additional field we're accessing now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add a variant of this test where we use a Python version before 3.12. This is still showing a diagnostic being emitted.
Updates the MissingFStringSyntax rule to correctly skip diagnostics for f-string interpolations containing backslashes when targeting Python 3.11, matching Python's behavior. Adds a dedicated test and snapshot to verify the change.
Summary
Fixes #21033 (RUF027) to suppress f-string suggestions for strings containing backslashes in interpolation expressions when targeting Python versions below 3.12, preventing syntax errors.
Problem Analysis
RUF027 was suggesting f-string conversions for strings with backslashes in interpolation expressions (e.g.,
"{'\\n'}"), but f-strings with backslashes in interpolations are only valid syntax in Python 3.12+. This caused syntax errors when the fix was applied to code targeting older Python versions.The issue occurred because the
should_be_fstringfunction was checking for backslashes anywhere in the string literal, rather than specifically within the interpolation expressions where the syntax restriction applies.Approach
Added a version check in the
should_be_fstringfunction to suppress RUF027 for strings containing backslashes within interpolation expressions when the target Python version is below 3.12. This ensures:"{'\\n'}{x}")