Whitespace not/required

Peter J. Holzer hjp-python at hjp.at
Tue Aug 25 13:53:46 EDT 2020


On 2020-08-14 16:29:18 +1200, dn via Python-list wrote:
> For f-strings/formatted string literals, the most usual form is:
> 
>     "{" f_expression ["="] ["!" conversion] [":" format_spec] "}"
> 
> Remembering that this is BNF, see the space separating the closing-brace
> from anything preceding it

No. I see a space before the quote before the closing brace.

> - how else would we separate the components to
> comprehend?
> 
> Returning to Python:
> 
> >>> one = 1    # is the loneliest number...
> >>> f'{ one }'
> '1'
> >>> f'{ one:03 }'
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> ValueError: Unknown format code '\x20' for object of type 'int'
> >>> f'{ one:03}'
> '001'
> 
> Notice the presence/absence of the final space.
> 
> >>> pi = 3.14159   # better to import math
> >>> f'{ pi!r:10 }'
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> ValueError: Unknown format code '\x20' for object of type 'str'
> >>> f'{ pi!r:10}'
> '3.14159   '
> >>> f'{ pi!r }'
>   File "<stdin>", line 1
> SyntaxError: f-string: expecting '}'
> >>> f'{ pi!r}'
> '3.14159'
> 
> So, the f-string will work if the braces include only an expression
> surrounded by spaces. However, if one adds a conversion or
> format-specification, that final space becomes a no-no. Eh what!

That doesn't surprise me. The "!" and ":" split the replacement field
into three parts.

The f_expression is just a subset of normal python expressions, which
allow whitespace, so
    f"{pi+1}"
    f"{pi + 1}"
    f"{ pi + 1 }"
    f"{ pi + 1 !r}"
    f"{ pi + 1 :f}"
are all valid.

The conversion consists only of a single character ("a", "r", or "s"),
anything else is invalid.

The format_spec is everything between the colon and the closing brace.
Syntactically, that can contain spaces. However, that is passed to the
object's __format__() method, and for builtin objects that method
doesn't know what to do with a space (you could implement it for your
own objects, though).


> To be fair, the 'book of words' does say: "A replacement field ends with a
> closing curly bracket '}'.". No mention of whitespace. No mention that a
> replacement field consisting only of an f_expression, will be treated
> differently by allowing a space.
> 
> Version 3.8 introduced the "=" short-cut:
> 
> >>> f"{ foo = }" # preserves whitespace
> " foo = 'bar'"
> 
> Note the comment! Yet, the manual's examples continue:
> 
> >>> line = "The mill's closed"
> >>> f"{line = }"
> 'line = "The mill\'s closed"'
> >>> f"{line = :20}"
> "line = The mill's closed   "
> 
> Hey, why does this second example dispense with the braces-internal spaces?

It doesn't. The space is still there - before the colon.


> Should the closing brace be considered part of a conversion or
> format-specification?

No.

> The space (I'd like to add) cannot be considered part of a conversion
> or format-specification (see BNF, see text of web.ref)!

But it is part of the format specification:

    format_spec       ::=  (literal_char | NULL | replacement_field)*
    literal_char      ::=  <any code point except "{", "}" or NULL>

Note: *any* code point except "{", "}" or NULL. So that includes space.
(BTW, what is NULL? U+0000 doesn't make much sense here (and is usually
written NUL (with one L) and an empty string is not a code point.)

        hp

-- 
   _  | Peter J. Holzer    | Story must make more sense than reality.
|_|_) |                    |
| |   | hjp at hjp.at         |    -- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |       challenge!"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-list/attachments/20200825/fcc1252c/attachment.sig>


More information about the Python-list mailing list