Message341582
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 "!=":
f'{foo!=}'
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:
{foo=}
This code:
foo=5
print(f"{foo=}")
would print
foo=5
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
{foo=!s}
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:
vvvvvvvvvv
f"{chr(65) = }"
is *exactly* the same as this:
vvvvvvvvvv
"chr(65) = 'A'"
Please vote!
Eric and /arry |
|
Date |
User |
Action |
Args |
2019-05-06 18:10:56 | eric.smith | set | recipients:
+ eric.smith, larry |
2019-05-06 18:10:56 | eric.smith | set | messageid: <1557166256.56.0.583302074071.issue36817@roundup.psfhosted.org> |
2019-05-06 18:10:56 | eric.smith | link | issue36817 messages |
2019-05-06 18:10:55 | eric.smith | create | |
|