You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2019-05-06.16:33:17.772>created_at=<Date2019-05-05.01:23:34.906>labels= ['easy', '3.8', 'docs']
title='f-strings do not support top-level :='updated_at=<Date2019-05-06.16:33:17.771>user='https://github.com/ericvsmith'
The walrus operator breaks f-strings, because the f-string scanner sees the colon as the end of the expression.
>>> x ='10'
>>> f'{x:=10}'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: '=' alignment not allowed in string format specifier
This becomes: format(x, '=10'), which is an error if x is a string.
This doesn't seem at all related to walrus operator, I can reproduce this error on 3.6.7 and 3.7.3, given that format call returns exactly the same error, it seems like '=' is simply not a valid alignment for strings.
I'm not saying that walrus operator did not introduce any errors, but those could be perhaps best tested using the following code:
The point is that := is valid expression syntax in Python 3.8, but you can't use it in an f-string. The fact that the error is the same in 3.6 and 3.7 is irrelevant because := was not valid syntax in those versions.
SilentGhost commented on May 5, 2019
SilentGhostmannequin
Mannequin
More actions
The point is that := is valid expression syntax in Python 3.8, but you can't use it in an f-string.
Good? Allowing walrus operator in the f-strings will just lead to the debugging hell.
f-strings are not going to take a position on what a "good" expression is, and what is and isn't allowed. If it's a Python expression that could possibly be parsed in the f-string context, f-strings will allow it. This is clearly a bug in 3.8. I'll have a PR today or during the sprints.
Correct about the parens. I'm just going to fix it a the top level, without parens. There's no reason it shouldn't work, the fact that it doesn't work now is just an accident of implementation.
I'll fix it by adding a special test, the same way that != has a special test.
For those who say it shouldn't be allowed at the top level anyway, but should be allowed in parens: if we decide that (which I disagree with), then it should not be disallowed because of an accidental interaction with format specs. It should be explicitly checked for and disallowed. Again, I am not planning on making that change. I'm just going to allow it.
Allowing it at the top level is a breaking change. It should not be done without deprecation. And I think that it is better to use parenthesis around the assignment operator (or better do not use it in f-strings at all) that deprecate the "=" alignment.
I'm not sure why Guido's preferences would be relevant. f-strings support expressions, := is a valid expression, f-strings therefore must support it.
f-strings expressions are not top-level statements and therefore will not require parentheses around :=.
There appears to be some confusion around f-strings' use of : to delimit a "format specification". Supporting := won't break format specifications, although it will require some intelligence--if you see a :, you must examine the next character to know whether it's := or a format specification. It is not a breaking change.
Ah yes, that's what I meant. I was thinking about the confusion between f-strings (evaluated immediately and stored as a string) vs other versions of string formatting which are evaluated when used. I've seen the mix of the two confuse people when evaluating performance. I don't think this is particularly relevant to this issue though, so we can ignore it :)
FWIW, I think it's equally reasonable to allow assignment expressions directly in f-strings, as it is to require parentheses with a reference to the invalidity of top-level expressions.
That makes me lean towards adding a parse-time error message that suggests the right way to do it, and leave it out as a feature for now, because it risks conflicting with ":" as format separator. We do not know yet if we will really need this feature. It's easier to add the feature later, than to remove it again in case we find that it gets in the way more than it helps.
Because of the backward compatibility issues, I'm not going to change the f-string parser for this. We'll just need to document the requirements for using parens if you want to use :=. This is similar to the existing documentation about lambdas and f-strings in https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals
Patches welcome!
To be clear: like lambdas, this is just limitation of embedding expressions inside strings, and it's also a limitation because format specs can start with equal signs. It's not a restriction because I think f-strings shouldn't contain "top-level" := expressions.
Activity
ericvsmith commentedon May 5, 2019
The walrus operator breaks f-strings, because the f-string scanner sees the colon as the end of the expression.
This becomes: format(x, '=10'), which is an error if x is a string.
SilentGhost commentedon May 5, 2019
This doesn't seem at all related to walrus operator, I can reproduce this error on 3.6.7 and 3.7.3, given that format call returns exactly the same error, it seems like '=' is simply not a valid alignment for strings.
I'm not saying that walrus operator did not introduce any errors, but those could be perhaps best tested using the following code:
f'{x:=^10}'
larryhastings commentedon May 5, 2019
The point is that := is valid expression syntax in Python 3.8, but you can't use it in an f-string. The fact that the error is the same in 3.6 and 3.7 is irrelevant because := was not valid syntax in those versions.
SilentGhost commentedon May 5, 2019
Good? Allowing walrus operator in the f-strings will just lead to the debugging hell.
ericvsmith commentedon May 5, 2019
f-strings are not going to take a position on what a "good" expression is, and what is and isn't allowed. If it's a Python expression that could possibly be parsed in the f-string context, f-strings will allow it. This is clearly a bug in 3.8. I'll have a PR today or during the sprints.
serhiy-storchaka commentedon May 5, 2019
You can use it in parenthesis:
It should be explicitly documented, that what looks like the assignment operator is not always the assignment operator in f-strings.
ericvsmith commentedon May 5, 2019
Correct about the parens. I'm just going to fix it a the top level, without parens. There's no reason it shouldn't work, the fact that it doesn't work now is just an accident of implementation.
I'll fix it by adding a special test, the same way that != has a special test.
For those who say it shouldn't be allowed at the top level anyway, but should be allowed in parens: if we decide that (which I disagree with), then it should not be disallowed because of an accidental interaction with format specs. It should be explicitly checked for and disallowed. Again, I am not planning on making that change. I'm just going to allow it.
serhiy-storchaka commentedon May 5, 2019
Allowing it at the top level is a breaking change. It should not be done without deprecation. And I think that it is better to use parenthesis around the assignment operator (or better do not use it in f-strings at all) that deprecate the "=" alignment.
tirkarthi commentedon May 5, 2019
There was a note on PEP-572 (https://www.python.org/dev/peps/pep-0572/#exceptional-cases) to prohibit as a top level expression and a discussion on the issue also didn't agree with it https://bugs.python.org/issue35224#msg339098 . It might cause confusion to users due to this difference inside and outside of f-strings.
serhiy-storchaka commentedon May 5, 2019
Note that Guido prefers to use parentheses around the assignment operator even if the grammar does nor require this. He used this style in What's New.
larryhastings commentedon May 5, 2019
I'm not sure why Guido's preferences would be relevant. f-strings support expressions, := is a valid expression, f-strings therefore must support it.
f-strings expressions are not top-level statements and therefore will not require parentheses around :=.
There appears to be some confusion around f-strings' use of : to delimit a "format specification". Supporting := won't break format specifications, although it will require some intelligence--if you see a :, you must examine the next character to know whether it's := or a format specification. It is not a breaking change.
4 remaining items
emilyemorehouse commentedon May 5, 2019
Ah yes, that's what I meant. I was thinking about the confusion between f-strings (evaluated immediately and stored as a string) vs other versions of string formatting which are evaluated when used. I've seen the mix of the two confuse people when evaluating performance. I don't think this is particularly relevant to this issue though, so we can ignore it :)
scoder commentedon May 5, 2019
FWIW, I think it's equally reasonable to allow assignment expressions directly in f-strings, as it is to require parentheses with a reference to the invalidity of top-level expressions.
That makes me lean towards adding a parse-time error message that suggests the right way to do it, and leave it out as a feature for now, because it risks conflicting with ":" as format separator. We do not know yet if we will really need this feature. It's easier to add the feature later, than to remove it again in case we find that it gets in the way more than it helps.
ericvsmith commentedon May 5, 2019
Because of the backward compatibility issues, I'm not going to change the f-string parser for this. We'll just need to document the requirements for using parens if you want to use :=. This is similar to the existing documentation about lambdas and f-strings in https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals
Patches welcome!
To be clear: like lambdas, this is just limitation of embedding expressions inside strings, and it's also a limitation because format specs can start with equal signs. It's not a restriction because I think f-strings shouldn't contain "top-level" := expressions.
serhiy-storchaka commentedon May 5, 2019
And I think that PEP-572 should be updated too. This is a corner case that was omitted at initial consideration of the PEP.
ericvsmith commentedon May 5, 2019
I agree with Serhiy about the need to update PEP-572 to mention this.
loganasherjones commentedon May 6, 2019
I'm going to try to tackle this. I'm not exactly sure how to go about updating the PEP, but the docs should have a PR in the next 15 minutes or so.
gvanrossum commentedon May 6, 2019
New changeset ae2c32f by Guido van Rossum (Logan Jones) in branch 'master':
bpo-36798: Updating f-string docs for := use case (GH-13107)
ae2c32f
gvanrossum commentedon May 6, 2019
PEP and docs have been amended.