mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-17 13:57:25 +00:00
Fix syntax error false positives for escapes and quotes in f-strings (#20867)
Summary -- Fixes #20844 by refining the unsupported syntax error check for [PEP 701] f-strings before Python 3.12 to allow backslash escapes and escaped outer quotes in the format spec part of f-strings. These are only disallowed within the f-string expression part on earlier versions. Using the examples from the PR: ```pycon >>> f"{1:\x64}" '1' >>> 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 that the second case is a runtime error, but this is actually avoidable if you override `__format__`, so despite being pretty weird, this could actually be a valid use case. ```pycon >>> class C: ... def __format__(*args, **kwargs): return "<C>" ... >>> f"{C():\"d\"}" '<C>' ``` At first I thought narrowing the range we check to exclude the format spec would only work for escapes, but it turns out that cases like `f"{1:""}"` are already covered by an existing `ParseError`, so we can just narrow the range of both our escape and quote checks. Our comment check also seems to be working correctly because it's based on the actual tokens. A case like [this](https://play.ruff.rs/9f1c2ff2-cd8e-4ad7-9f40-56c0a524209f): ```python f"""{1:# }""" ``` doesn't include a comment token, instead the `#` is part of an `InterpolatedStringLiteralElement`. Test Plan -- New inline parser tests [PEP 701]: https://peps.python.org/pep-0701/
This commit is contained in:
parent
8817ea5c84
commit
8b9ab48ac6
9 changed files with 317 additions and 62 deletions
|
@ -712,8 +712,6 @@ f'{1:hy "user"}'
|
|||
f'{1: abcd "{1}" }'
|
||||
f'{1: abcd "{'aa'}" }'
|
||||
f'{1=: "abcd {'aa'}}'
|
||||
# FIXME(brent) This should not be a syntax error on output. The escaped quotes are in the format
|
||||
# spec, which is valid even before 3.12.
|
||||
f'{x:a{z:hy "user"}} \'\'\''
|
||||
|
||||
# Changing the outer quotes is fine because the format-spec is in a nested expression.
|
||||
|
@ -1536,8 +1534,6 @@ f'{1:hy "user"}'
|
|||
f'{1: abcd "{1}" }'
|
||||
f'{1: abcd "{"aa"}" }'
|
||||
f'{1=: "abcd {'aa'}}'
|
||||
# FIXME(brent) This should not be a syntax error on output. The escaped quotes are in the format
|
||||
# spec, which is valid even before 3.12.
|
||||
f"{x:a{z:hy \"user\"}} '''"
|
||||
|
||||
# Changing the outer quotes is fine because the format-spec is in a nested expression.
|
||||
|
@ -2365,8 +2361,6 @@ f'{1:hy "user"}'
|
|||
f'{1: abcd "{1}" }'
|
||||
f'{1: abcd "{"aa"}" }'
|
||||
f'{1=: "abcd {'aa'}}'
|
||||
# FIXME(brent) This should not be a syntax error on output. The escaped quotes are in the format
|
||||
# spec, which is valid even before 3.12.
|
||||
f"{x:a{z:hy \"user\"}} '''"
|
||||
|
||||
# Changing the outer quotes is fine because the format-spec is in a nested expression.
|
||||
|
@ -2418,30 +2412,6 @@ print(f"{ {}, 1 }")
|
|||
|
||||
|
||||
### Unsupported Syntax Errors
|
||||
error[invalid-syntax]: Cannot use an escape sequence (backslash) in f-strings on Python 3.10 (syntax was added in Python 3.12)
|
||||
--> fstring.py:764:19
|
||||
|
|
||||
762 | # FIXME(brent) This should not be a syntax error on output. The escaped quotes are in the format
|
||||
763 | # spec, which is valid even before 3.12.
|
||||
764 | f"{x:a{z:hy \"user\"}} '''"
|
||||
| ^
|
||||
765 |
|
||||
766 | # Changing the outer quotes is fine because the format-spec is in a nested expression.
|
||||
|
|
||||
warning: Only accept new syntax errors if they are also present in the input. The formatter should not introduce syntax errors.
|
||||
|
||||
error[invalid-syntax]: Cannot use an escape sequence (backslash) in f-strings on Python 3.10 (syntax was added in Python 3.12)
|
||||
--> fstring.py:764:13
|
||||
|
|
||||
762 | # FIXME(brent) This should not be a syntax error on output. The escaped quotes are in the format
|
||||
763 | # spec, which is valid even before 3.12.
|
||||
764 | f"{x:a{z:hy \"user\"}} '''"
|
||||
| ^
|
||||
765 |
|
||||
766 | # Changing the outer quotes is fine because the format-spec is in a nested expression.
|
||||
|
|
||||
warning: Only accept new syntax errors if they are also present in the input. The formatter should not introduce syntax errors.
|
||||
|
||||
error[invalid-syntax]: Cannot reuse outer quote character in f-strings on Python 3.10 (syntax was added in Python 3.12)
|
||||
--> fstring.py:178:8
|
||||
|
|
||||
|
@ -2452,27 +2422,3 @@ error[invalid-syntax]: Cannot reuse outer quote character in f-strings on Python
|
|||
179 | f"foo {'"bar"'}"
|
||||
|
|
||||
warning: Only accept new syntax errors if they are also present in the input. The formatter should not introduce syntax errors.
|
||||
|
||||
error[invalid-syntax]: Cannot reuse outer quote character in f-strings on Python 3.10 (syntax was added in Python 3.12)
|
||||
--> fstring.py:773:14
|
||||
|
|
||||
771 | f'{1=: "abcd \'\'}' # Don't change the outer quotes, or it results in a syntax error
|
||||
772 | f"{1=: abcd \'\'}" # Changing the quotes here is fine because the inner quotes aren't the opposite quotes
|
||||
773 | f"{1=: abcd \"\"}" # Changing the quotes here is fine because the inner quotes are escaped
|
||||
| ^
|
||||
774 | # Don't change the quotes in the following cases:
|
||||
775 | f'{x=:hy "user"} \'\'\''
|
||||
|
|
||||
warning: Only accept new syntax errors if they are also present in the input. The formatter should not introduce syntax errors.
|
||||
|
||||
error[invalid-syntax]: Cannot reuse outer quote character in f-strings on Python 3.10 (syntax was added in Python 3.12)
|
||||
--> fstring.py:764:14
|
||||
|
|
||||
762 | # FIXME(brent) This should not be a syntax error on output. The escaped quotes are in the format
|
||||
763 | # spec, which is valid even before 3.12.
|
||||
764 | f"{x:a{z:hy \"user\"}} '''"
|
||||
| ^
|
||||
765 |
|
||||
766 | # Changing the outer quotes is fine because the format-spec is in a nested expression.
|
||||
|
|
||||
warning: Only accept new syntax errors if they are also present in the input. The formatter should not introduce syntax errors.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue