black icon indicating copy to clipboard operation
black copied to clipboard

AST safety check fails to catch incorrect f-string change

Open kwk opened this issue 1 year ago • 2 comments

Describe the style change

I wonder if f-strings should be formatted at all.

Examples in the current Black style

print(f"{"|".join(['a','b','c'])}")

Desired style

print(f"{"|".join(['a','b','c'])}")

[!NOTE] There's no change to the input here.

Additional context

Black formats the "|" to become " | " and that affects the output which cannot be desired.

Black formats the snippet like this currently:

print(f"{" | ".join(['a','b','c'])}")

kwk avatar Mar 08 '24 20:03 kwk

Confirmed this bug:

% python3.12 -m black -c '''print(f"{"|".join(['a','b','c'])}")'''
print(f"{" | ".join([a,b,c])}")

This is related to our lack of nested f-string support (#3746). I suppose our parser misparses this as two strings with an | operator in between, then we reformat it to add spaces around the operator, and the AST safety check doesn't catch it because it ignores leading/trailing whitespace for docstring reasons.

Other than adding actual support for this syntax, which is tracked in #3746, we should catch this in the AST safety check by being less lenient about the whitespace changes we allow in strings.

JelleZijlstra avatar Mar 08 '24 21:03 JelleZijlstra

Thank you for confirming this issue. I work around it like so:

# fmt: off
print(f"{"|".join(['a','b','c'])}")
# fmt: on

kwk avatar Mar 08 '24 21:03 kwk

Thank you for addressing this. Can the fix be expected in 24.2.1 or what's the next version that will include the fix?

kwk avatar Mar 15 '24 15:03 kwk

There will be a new release (24.3.0) soon.

JelleZijlstra avatar Mar 15 '24 15:03 JelleZijlstra

I just released 24.3.0 which includes this fix.

JelleZijlstra avatar Mar 15 '24 20:03 JelleZijlstra

I just released 24.3.0 which includes this fix.

I still have to wrap the code to not be formatted like this:

# fmt: off
table += f"|{c}|{" | ".join(cols)}|\n"
# fmt: on

[!WARNING] error: cannot format snapshot_manager/snapshot_manager/build_status.py: INTERNAL ERROR: Black produced code that is not equivalent to the source. Please report a bug on https://github.com/psf/black/issues. This diff might be helpful: /tmp/blk_aym4688c.log

$ cat /tmp/blk_aym4688c.log
--- src
+++ dst
@@ -6797,11 +6797,11 @@
                                 value=
                                 Constant(
                                     kind=
                                     None,  # NoneType
                                     value=
-                                    '|',  # str
+                                    ' | ',  # str
                                 )  # /Constant
                             )  # /Attribute
                             keywords=
                         )  # /Call
                     )  # /FormattedValue

kwk avatar Mar 19 '24 18:03 kwk