Skip to content
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

Nested quotes in f-strings #4056

Closed
ujan-r opened this issue Nov 19, 2023 · 1 comment
Closed

Nested quotes in f-strings #4056

ujan-r opened this issue Nov 19, 2023 · 1 comment
Labels
T: bug Something isn't working

Comments

@ujan-r
Copy link

ujan-r commented Nov 19, 2023

Describe the bug

Python 3.12 introduced some updates to the f-string grammar (see PEP 701), including—among other things—quote reuse: strings nested within an f-string can now use the same quote character as the f-string itself. Black doesn't recognize this, inadvertently changing the semantics of some programs containing f-strings.

To Reproduce

For example, take this code:

# file.py
from urllib.parse import quote


dest = 'unescaped callback'
redirect_uri = f'127.0.0.1:443/path?dest={quote(dest, safe='')}'

print(redirect_uri)
$ python file.py
127.0.0.1:443/path?dest=unescaped%20callback

After formatting with black file.py --skip-string-normalization --target-version py312, we get:

# file.py
from urllib.parse import quote


dest = 'unescaped callback'
redirect_uri = f'127.0.0.1:443/path?dest={quote(dest, safe=' ')}'

print(redirect_uri)
$ python file.py
127.0.0.1:443/path?dest=unescaped callback

Black has silently modified the code! It interprets the f-string as two separate strings, inserting a space between them.

We only get an error when the preview flag is enabled (black file.py --preview --skip-string-normalization --target-version py312). The resulting error is:

INTERNAL ERROR: Black produced invalid code: expected argument value expression (<unknown>, line 6).)

Here is the generated log file:

  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/black/__init__.py", line 1444, in assert_equivalent
    dst_ast = parse_ast(dst)
              ^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/black/parsing.py", line 140, in parse_ast
    raise SyntaxError(first_error)
# file.py
from urllib.parse import quote


dest = 'unescaped callback'
redirect_uri = f'127.0.0.1:443/path?dest={quote(dest, safe=)}}'

print(redirect_uri)

Expected behavior

The original code (file.py) shouldn't be modified.

Environment

$ # macOS 13.5
$ black --version
black, 23.11.0 (compiled: no)
Python (CPython) 3.12.0
@ujan-r ujan-r added the T: bug Something isn't working label Nov 19, 2023
@hauntsaninja
Copy link
Collaborator

Thanks, duplicate of #3746

@hauntsaninja hauntsaninja closed this as not planned Won't fix, can't repro, duplicate, stale Nov 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T: bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants