This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author eric.smith
Recipients eric.smith, larry
Date 2019-05-06.18:10:55
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
This is an alternative proposal to issue36774.

We (Eric V. Smith and Larry Hastings) propose a minor language
change.  This level of change doesn't require a PEP, so in this
post-BDFL world what we need is "a consensus among core developers".
So please vote!  Note that "+" is typed using "shift-=", and the "1"
key can be found very nearby.

Python programmers often use "printf-style" debugging.  In the
(really) bad old days this was pretty wordy:
    print "foo=", foo, "bar=", bar

f-strings make this slightly nicer to type:
    print(f"foo={foo} bar={bar}")

But you still have to repeat yourself: you have to write
out the *string* "foo", and then the *expession* "foo".
Wouldn't it be nice if you didn't have to?

f-strings are uniquely able to help with this.  Their implementation
requires them to know the original text of the expression which they
then compile.  It's not difficult for f-strings to retain the text
and prepend it; the tricky part is figuring out how to spell it.

The initial idea was to use an f-string "conversion", which we
originally spelled "!=":
This spelling won't work, because f-strings permit arbitrary Python
expressions, and != of course tests for inequality.

We considered other spellings:
    !d (debug)
    !e (equals)
    !x (?)
    !! (easy to type)
We'd planned to go with !d.  In fact Eric gave a lightning talk
about this on Friday night and used this spelling.

And then!  On Saturday, the best spelling revealed itself!  Behold
the majesty of:
This code:
would print

With this spelling change, we've also refined the semantics.

By default, f-strings use format() (technically they call
__format__ on the value).  But the point of this is for debugging.
But you want repr() for debugging.  When you use this on a string,
you want to see the quoted string; when you use this on a datetime
object, you want to see the datetime repr, not the default
formatted string.

Second, this is now composable with conversions.  So you can use
to use str() instead of repr() on the value.

Relatedly, we've added a new conversion: "!f" means "use format()",
which you could never explicitly specify before.  For example, to only
format pi to two decimal places:
    f"{math.pi=!f:.2f}" => "3.14"

Finally, and this is the best part: what if you want whitespace around
the equals sign?  Well, to the left is no problem; whitespace is preserved
from the original text inside the curly braces:
    f"{ chr(65) =}" => " chr(65) ='A'"
But we also explicitly permit, and preserve, whitespace *after* the
equals sign:
    f"{chr(65) = }" => "chr(65) = 'A'"

What's particularly elegant is that we simply preserve all the
characters up to the final delimiter.  The equals sign sets a flag
but doesn't stop flushing through text.  So this:
    f"{chr(65) = }"
is *exactly* the same as this:
      "chr(65) = 'A'"

Please vote!

Eric and /arry
Date User Action Args
2019-05-06 18:10:56eric.smithsetrecipients: + eric.smith, larry
2019-05-06 18:10:56eric.smithsetmessageid: <>
2019-05-06 18:10:56eric.smithlinkissue36817 messages
2019-05-06 18:10:55eric.smithcreate