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
|
@ -0,0 +1,2 @@
|
|||
# parse_options: {"target-version": "3.12"}
|
||||
f"{1:""}" # this is a ParseError on all versions
|
|
@ -0,0 +1,2 @@
|
|||
# parse_options: {"target-version": "3.11"}
|
||||
f"{1:''}" # but this is okay on all versions
|
|
@ -5,3 +5,5 @@ f"""{f'''{f'{"# not a comment"}'}'''}"""
|
|||
f"""{f'''# before expression {f'# aro{f"#{1+1}#"}und #'}'''} # after expression"""
|
||||
f"escape outside of \t {expr}\n"
|
||||
f"test\"abcd"
|
||||
f"{1:\x64}" # escapes are valid in the format spec
|
||||
f"{1:\"d\"}" # this also means that escaped outer quotes are valid
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue