black icon indicating copy to clipboard operation
black copied to clipboard

Request: removing extra spaces in f-string

Open jamesbraza opened this issue 8 months ago • 3 comments

Is your feature request related to a problem? Please describe.

I came across the below code snippet today. black==23.12.0 does not remove the extra space after the f-string's colon:

some_float = 5.0
some_string = f"{some_float: 0.3f}"

I am using Python 3.11.7.

Describe the solution you'd like

I would like black to remove the extra space after the colon, autoformatting to:

some_float = 5.0
some_string = f"{some_float:0.3f}"

Describe alternatives you've considered

Additional context

jamesbraza avatar Dec 15 '23 20:12 jamesbraza

@jamesbraza I have added a PR for this issue. Please got through the code and tell me where it needs rectification.

RigvedRocks avatar Dec 18 '23 00:12 RigvedRocks

I don't think we should do this, because the whitespace in the format spec is passed to the object's __format__ method, so removing the space could change behavior.

For example, this:

class X:
    def __format__(self, s):
        print(repr(s))
        return s
f"{X(): with space}"
f"{X():without space}"

Prints

' with space'
'without space'

JelleZijlstra avatar Jan 02 '24 01:01 JelleZijlstra

Thanks for the thoughtful response! I see what you're saying.

Where I discovered this, it was a typo adding extra whitespace, and also 0.3f format specifier is not something the extra space has meaning for.

Personally, I would rather see the space outside the format specifier:

class X:
    def __format__(self, s):
        print(repr(s))
        return s
print(repr(f"{X(): space in format}"))
print(repr(f" {X():space outside format}"))  # I prefer this
' space in format'
' space in format'
'space outside format'
' space outside format'

I guess I still think most use cases with space(s) inside the format specifier are accidentally added whitespace.

I am not very opinionated here, I just thought it could be a new a handy trick for black, so also feel free to close this out

jamesbraza avatar Jan 02 '24 03:01 jamesbraza

I actually format strings this way, especially when combined with =, as in:

a = 5.13
print(f"{a = :0.1f}")
'a = 5.1'

I don't think we should make any formatting changes that change the output of the code.

danielpodrazka avatar Feb 09 '24 02:02 danielpodrazka

Thanks for sharing your use case. Out of curiosity, what do you think of formatting on the right side of the colon @danielpodrazka ?

jamesbraza avatar Feb 09 '24 02:02 jamesbraza

We definitely won't format cases like @danielpodrazka's, because it changes visible behavior. We also can't remove spaces from the format spec in general, because it also changes visible behavior:

>>> f"{1:d}"
'1'
>>> f"{1: d}"
' 1'

We could (and should) format code like f"{1 + 1}" to remove excess spaces, but there are already open issues about the fact we don't format code inside f-strings. Therefore, closing this issue.

JelleZijlstra avatar Feb 09 '24 02:02 JelleZijlstra