Skip to content

f-strings do not support top-level := #80979

Closed

Description

@ericvsmith
BPO 36798
Nosy @gvanrossum, @warsaw, @scoder, @larryhastings, @ericvsmith, @ambv, @serhiy-storchaka, @emilyemorehouse, @tirkarthi, @loganasherjones
PRs
  • bpo-36798: Updating f-string docs for := use case. #13107
  • 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 = None
    closed_at = <Date 2019-05-06.16:33:17.772>
    created_at = <Date 2019-05-05.01:23:34.906>
    labels = ['easy', '3.8', 'docs']
    title = 'f-strings do not support top-level :='
    updated_at = <Date 2019-05-06.16:33:17.771>
    user = 'https://github.com/ericvsmith'

    bugs.python.org fields:

    activity = <Date 2019-05-06.16:33:17.771>
    actor = 'gvanrossum'
    assignee = 'none'
    closed = True
    closed_date = <Date 2019-05-06.16:33:17.772>
    closer = 'gvanrossum'
    components = ['Documentation']
    creation = <Date 2019-05-05.01:23:34.906>
    creator = 'eric.smith'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 36798
    keywords = ['patch', 'easy']
    message_count = 22.0
    messages = ['341413', '341423', '341425', '341426', '341428', '341429', '341432', '341433', '341434', '341435', '341443', '341451', '341454', '341458', '341461', '341464', '341466', '341469', '341471', '341501', '341557', '341558']
    nosy_count = 11.0
    nosy_names = ['gvanrossum', 'barry', 'scoder', 'larry', 'eric.smith', 'SilentGhost', 'lukasz.langa', 'serhiy.storchaka', 'emilyemorehouse', 'xtreak', 'loganasherjones']
    pr_nums = ['13107']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = None
    url = 'https://bugs.python.org/issue36798'
    versions = ['Python 3.8']

    Activity

    1. ericvsmith commented on May 5, 2019

      @ericvsmith
      MemberAuthor

      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.

    2. self-assigned this
      on May 5, 2019
    3. SilentGhost commented on May 5, 2019

      SilentGhostmannequin
      Mannequin

      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}'

    4. larryhastings commented on May 5, 2019

      @larryhastings
      Contributor

      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.

    5. SilentGhost commented on May 5, 2019

      SilentGhostmannequin
      Mannequin

      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.

    6. ericvsmith commented on May 5, 2019

      @ericvsmith
      MemberAuthor

      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.

    7. serhiy-storchaka commented on May 5, 2019

      @serhiy-storchaka
      Member

      You can use it in parenthesis:

      >>> f'{(x:=10)}'
      '10'

      It should be explicitly documented, that what looks like the assignment operator is not always the assignment operator in f-strings.

      >>> x = 10
      >>> f'{x:=10}'
      '        10'
    8. ericvsmith commented on May 5, 2019

      @ericvsmith
      MemberAuthor

      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.

    9. serhiy-storchaka commented on May 5, 2019

      @serhiy-storchaka
      Member

      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.

    10. tirkarthi commented on May 5, 2019

      @tirkarthi
      Member

      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.

    11. serhiy-storchaka commented on May 5, 2019

      @serhiy-storchaka
      Member

      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.

    12. larryhastings commented on May 5, 2019

      @larryhastings
      Contributor

      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.

    13. 4 remaining items

    14. emilyemorehouse commented on May 5, 2019

      @emilyemorehouse
      Member

      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 :)

    15. scoder commented on May 5, 2019

      @scoder
      Contributor

      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.

    16. ericvsmith commented on May 5, 2019

      @ericvsmith
      MemberAuthor

      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.

    17. added
      docsDocumentation in the Doc dir
      and removed
      interpreter-core(Objects, Python, Grammar, and Parser dirs)
      on May 5, 2019
    18. removed their assignment
      on May 5, 2019
    19. serhiy-storchaka commented on May 5, 2019

      @serhiy-storchaka
      Member

      And I think that PEP-572 should be updated too. This is a corner case that was omitted at initial consideration of the PEP.

    20. ericvsmith commented on May 5, 2019

      @ericvsmith
      MemberAuthor

      I agree with Serhiy about the need to update PEP-572 to mention this.

    21. loganasherjones commented on May 6, 2019

      loganasherjonesmannequin
      Mannequin

      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.

    22. gvanrossum commented on May 6, 2019

      @gvanrossum
      Member

      New changeset ae2c32f by Guido van Rossum (Logan Jones) in branch 'master':
      bpo-36798: Updating f-string docs for := use case (GH-13107)
      ae2c32f

    23. gvanrossum commented on May 6, 2019

      @gvanrossum
      Member

      PEP and docs have been amended.

    24. transferred this issue fromon Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      3.8 (EOL)end of lifedocsDocumentation in the Doc direasy

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions