Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PEP 572: Assignment Expressions #79405

Closed
emilyemorehouse opened this issue Nov 13, 2018 · 64 comments
Closed

PEP 572: Assignment Expressions #79405

emilyemorehouse opened this issue Nov 13, 2018 · 64 comments
Assignees
Labels
3.8 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement

Comments

@emilyemorehouse
Copy link
Member

BPO 35224
Nosy @gvanrossum, @tim-one, @warsaw, @rhettinger, @ncoghlan, @ericvsmith, @nedbat, @stevendaprano, @serhiy-storchaka, @koobs, @matrixise, @willingc, @vedgar, @emilyemorehouse, @joernheissler, @pablogsal, @miss-islington, @tirkarthi
PRs
  • bpo-35224: PEP 572 Implementation #10497
  • bpo-35224: PEP 572 Implementation #10497
  • bpo-35224: Add support for NamedExpr to unparse.py #11670
  • bpo-35224: Add support for NamedExpr to unparse.py #11670
  • bpo-35224: Add support for NamedExpr to unparse.py #11670
  • bpo-35224: Add PEP 572 (assignment expressions) to What's New #12941
  • Non-working attempt to introduce := as an assignment operator #6333
  • bpo-35224: Reverse evaluation order of key: value in dict comprehensions #14139
  • bpo-35224: Bump the pyc magic number after the change in MAP_ADD #14313
  • [3.8] bpo-35224: Reverse evaluation order of key: value in dict comprehensions (GH-14139) #14314
  • [3.8] bpo-35224: Bump the pyc magic number after the change in MAP_ADD (GH-14313) #14315
  • bpo-35224: Add What's new entry for evaluation order in dict comprehensions #14319
  • bpo-35224: Bump the pyc magic number by 1 instead of by 10 in last modification #14320
  • [3.8] bpo-35224: Bump the pyc magic number by 1 instead of by 10 in last modification (GH-14320) #14321
  • [3.8] bpo-35224: Add What's new entry for evaluation order in dict comprehensions (GH-14319) #14361
  • bpo-35224: Additional documentation for Assignment Expressions #15935
  • [3.8] bpo-35224: Additional documentation for Assignment Expressions (GH-15935) #15967
  • 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 = 'https://github.com/emilyemorehouse'
    closed_at = <Date 2019-09-11.15:16:49.055>
    created_at = <Date 2018-11-13.00:52:17.907>
    labels = ['interpreter-core', 'type-feature', '3.8']
    title = 'PEP 572: Assignment Expressions'
    updated_at = <Date 2019-09-11.15:29:33.173>
    user = 'https://github.com/emilyemorehouse'

    bugs.python.org fields:

    activity = <Date 2019-09-11.15:29:33.173>
    actor = 'gvanrossum'
    assignee = 'emilyemorehouse'
    closed = True
    closed_date = <Date 2019-09-11.15:16:49.055>
    closer = 'emilyemorehouse'
    components = ['Interpreter Core']
    creation = <Date 2018-11-13.00:52:17.907>
    creator = 'emilyemorehouse'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 35224
    keywords = ['patch', 'patch']
    message_count = 64.0
    messages = ['329781', '334325', '334328', '334330', '334331', '334332', '334334', '334341', '334358', '334839', '334840', '335437', '335438', '335452', '335458', '339098', '339112', '339121', '339131', '339159', '339160', '339172', '340770', '340774', '340776', '340777', '340792', '340794', '345782', '345791', '345798', '346282', '346287', '346290', '346291', '346292', '346298', '346303', '346304', '346305', '346306', '346307', '346308', '346312', '346319', '346327', '346329', '346331', '346472', '346473', '347985', '349011', '349013', '349017', '349019', '349021', '349024', '349025', '349026', '349034', '351906', '351929', '351933', '351940']
    nosy_count = 18.0
    nosy_names = ['gvanrossum', 'tim.peters', 'barry', 'rhettinger', 'ncoghlan', 'eric.smith', 'nedbat', 'steven.daprano', 'serhiy.storchaka', 'koobs', 'matrixise', 'willingc', 'veky', 'emilyemorehouse', 'joernheissler', 'pablogsal', 'miss-islington', 'xtreak']
    pr_nums = ['10497', '10497', '11670', '11670', '11670', '12941', '6333', '14139', '14313', '14314', '14315', '14319', '14320', '14321', '14361', '15935', '15967']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue35224'
    versions = ['Python 3.8']

    @emilyemorehouse
    Copy link
    Member Author

    This issue will serve to track development and PRs for the implementation of PEP-572: Assignment Expressions.

    @emilyemorehouse emilyemorehouse added the 3.8 only security fixes label Nov 13, 2018
    @emilyemorehouse emilyemorehouse self-assigned this Nov 13, 2018
    @emilyemorehouse emilyemorehouse added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement labels Nov 13, 2018
    @emilyemorehouse
    Copy link
    Member Author

    New changeset 8f59ee0 by Emily Morehouse in branch 'master':
    bpo-35224: PEP-572 Implementation (bpo-10497)
    8f59ee0

    @gvanrossum
    Copy link
    Member

    This is huge!

    I do recall there are some minor edge cases where the implementation currently doesn't match the PEP. Could you summarize those here, and add your recommendation (e.g. change the PEP, fix the code, wait and see) with motivation?

    @vstinner
    Copy link
    Member

    The change broke most buildbots: congrats Emily, each core dev has to do their as part of their training ;-) Don't worry, it's fine.

    I wrote PR bpo-11670 which should fix test_tools.

    @emilyemorehouse
    Copy link
    Member Author

    @vstinner Is there something I could/should have checked other than the CI displayed in GitHub before merging? Let me know if I can help.

    Here's a brief summary of the differences between the PEP spec and implementation:

    From the "Scope of the target" section of the PEP, there are two cases that should raise a TargetScopeError: when an assignment expression is used in a comprehension inside a class body or for special cases in comprehensions.

    Invalid examples for the latter include:

    [i := i+1 for i in range(5)]
    [[(j := j) for i in range(5)] for j in range(5)]
    [i := 0 for i, j in stuff]
    [i+1 for i in i := stuff]
    

    However, the following work in the implementation,though the PEP states they should be invalid:

        >>> [i := i+1 for i in range(5)]
        [1, 2, 3, 4, 5]
        >>> i
        5
    
        >>> [i := 0 for i, j in [(1, 2)]]
        [0]

    The following does not work in the implementation (as desired), but does not throw a TargetScopeError as defined in the PEP:

        >>> [i+1 for i in i := range(5)]
        File "<stdin>", line 1
            [i+1 for i in i := range(5)]
                            ^
        SyntaxError: invalid syntax

    IMO, I was leaning towards advocating for changing the PEP to match the implementation. I think the error messages are clear and expected, and restricting what already works would require significant special cases. I'm open to discussion though.

    There's also documentation that should certainly be added (and I believe a spot where assignment expressions are explicitly mentioned as not being included in the language, which is no longer the case)

    @vstinner
    Copy link
    Member

    @vstinner Is there something I could/should have checked other than the CI displayed in GitHub before merging? Let me know if I can help.

    It wasn't your fault. Our pre-commit checks on pull requests is incomplete on purpose: it has to be fast. It's fine to break buildbots sometimes. It's a tradeoff.

    If you want to help, please merge #11670 as soon as the CI test pass since I'm going to bed :-)

    You are the victim of a very very specific annoying test, test_unparse with its annoying "randomly pick 10 files from the stdlib" feature...

    @vstinner
    Copy link
    Member

    New changeset 1396d8f by Victor Stinner in branch 'master':
    bpo-35224: Add support for NamedExpr to unparse.py (GH-11670)
    1396d8f

    @tirkarthi
    Copy link
    Member

    I don't know if this is the correct issue for questions/clarifications but it seems parens are mandatory while using named expressions in while statement which makes some of the examples invalid like https://www.python.org/dev/peps/pep-0572/#sysconfig-py . From my limited knowledge while statement Grammar was not modified at https://github.com/python/cpython/pull/10497/files#diff-cb0b9d6312c0d67f6d4aa1966766ceddR73 and no tests for while statement which made me assume it's intentional. I haven't followed the full discussion about PEP-572 so feel free to correct me if it's a conscious decision and in that case the PEP-572 can be updated.

    # python info

    ➜ cpython git:(master) ./python.exe
    Python 3.8.0a0 (heads/bpo35113-dirty:49329a217e, Jan 25 2019, 09:57:53)
    [Clang 7.0.2 (clang-700.1.81)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.

    >>

    # Example as in PEP-572 to create a simple file that reads itself and prints lines that matches "foo"

    ➜ cpython git:(master) cat /tmp/foo.py
    import re

    with open("/tmp/foo.py") as f:
        while line := f.readline():
            if match := re.search(r"foo", line):
                print(match.string.strip("\n"))
    ➜  cpython git:(master) ./python.exe /tmp/foo.py
      File "/tmp/foo.py", line 4
        while line := f.readline():
                   ^
    SyntaxError: invalid syntax

    # Wrapping named expression with parens for while makes this valid

    ➜ cpython git:(master) cat /tmp/foo.py
    import re

    with open("/tmp/foo.py") as f:
        while (line := f.readline()):
            if match := re.search(r"foo", line):
                print(match.string.strip("\n"))
    ➜  cpython git:(master) ./python.exe /tmp/foo.py
    with open("/tmp/foo.py") as f:
            if match := re.search(r"foo", line):

    As a user I think parens shouldn't be mandatory in while statement since if statement works fine. Parens can cause while statement to be superfluous in some cases and an extra case to remember while teaching.

    @vstinner
    Copy link
    Member

    Note: I checked and 3.x buildbots are back to green (ignoring the ones which already failed previously). Good.

    @rhettinger
    Copy link
    Contributor

    FYI, we need a prominent Whatsnew entry for this.

    @emilyemorehouse
    Copy link
    Member Author

    @rhettinger absolutely, I'm going to include that in my documentation PR which is currently in progress. :)

    @hroncok
    Copy link
    Mannequin

    hroncok mannequin commented Feb 13, 2019

    PEP-572 is nowhere to be found in https://docs.python.org/3.8/whatsnew/3.8.html

    Should I open a separate issue for that?

    @hroncok
    Copy link
    Mannequin

    hroncok mannequin commented Feb 13, 2019

    (I've somehow missed the previous comments about the same, sorry about that.)

    @emilyemorehouse
    Copy link
    Member Author

    I have a work-in-progress (WIP) documentation branch I've been working on that I'll push up this week to address the following:

    If anyone has another area they think the documentation should be updated, please let me know!

    @vstinner
    Copy link
    Member

    If anyone has another area they think the documentation should be updated, please let me know!

    If we forget something, it's not an issue: it can be added later!

    @vedgar
    Copy link
    Mannequin

    vedgar mannequin commented Mar 29, 2019

    Now I had the opportunity to play with the walrus (as it is affectionately called in some parts of the community), I have to ask you for a reconsideration of one part of PEP-572.

    Unparenthesized assignment expressions are prohibited at the top level of an expression statement. This rule is included to simplify the choice for the user between an assignment statement and an assignment expression -- there is no syntactic position where both are valid.
    

    Correct, but the motivation rests on a wrong premise, that the effect is the same. In one very important case, it is not: in REPL (including things like Jupyter notebooks), the values of expressions are printed (if not None). I really hoped that the walrus would enable me to both assign and see the result at once. (Now it does, but I have to parenthesize, and that just looks ugly.)

    More than half of the cells in my Jupyter notebooks are of the form

        name = some.complicated.method(of={some: arguments})
        name
    
        another_name = another.method(name, [additional, arguments])
        another_name

    And while I understand why I had to write them like this before PEP-572, now I really think they would look much tidier as

    name := some.complicated.method(of={some: arguments})
    
    another_name := another.method(name, [additional, arguments])
    

    Please reconsider.

    @gvanrossum
    Copy link
    Member

    @veky -- please take this up on python-ideas.

    @vedgar
    Copy link
    Mannequin

    vedgar mannequin commented Mar 29, 2019

    Sorry, I don't have the energy for endless discussions without any result that almost always happen there. If you - of all people - don't see an obvious benefit of this (not even a feature - just a removal of a quite pointless limitation), then I'm probably wrong and there's no point in that.

    @willingc
    Copy link
    Contributor

    @veky As a Jupyter notebook maintainer, I can see your point and I suspect some would like it. I'm not sure how big a benefit it would be for folks based on current notebook usage and practices. I just don't know. It's worth a discussion, but it should take place on python-ideas first to see how much traction your proposal would have.

    Let's keep this issue focused on the implementation of 572 as accepted.

    @stevendaprano
    Copy link
    Member

    You are one person, who has used this feature for what, a month elapsed
    time? 300 person-hours actual experience with it? Allowing top-level
    unparenthisized walrus expressions will affect hundreds of thousands of
    people, for collectively millions of hours over a decade or more of
    elapsed time. What's the rush about lifting this restriction?

    If the restriction turns out to be "pointless", then we can remove it
    later, and no harm done. You say this is ugly in the notebooks:

    (variable := expression)
    

    but it is surely still an improvement over the status quo:

        variable = expression; variable

    But if we remove it now, and it turns out that it wasn't as pointless as
    you thought, then we're stuck with a design mistake that will be very
    hard to fix without breaking people's code.

    I'm glad you've found an excellent use-case for unbracketed assignment
    expressions, and I don't oppose your suggested change, I'm just
    advocating caution.

    Besides, Jypiter already allows interactive code that would be a syntax
    error outside of their environment. They can probably relax that
    restriction within Jypiter, while still leaving the language alone.

    @vstinner
    Copy link
    Member

    The bug tracker is not the appropriate place to discuss a PEP. This issue is about the implementation of the PEP.

    @vedgar
    Copy link
    Mannequin

    vedgar mannequin commented Mar 30, 2019

    Carol, if you're willing to go into the lion's den that is Python-ideas with this, you have my eternal gratitude. :-)

    Steven, sorry, there really is no rush. I really don't think I ever said there is. However, I think it would be much easier to change the behavior while the thing is in alpha. Isn't that the purpose of alpha?

    (If I'm wrong here, please disregard. I would be fine to see this happening few years from now. I believe in "Python in the limit", not actual versions, but too many times I have been said "what you ask makes sense in the ideal world, but that ship has sailed long ago".)

    Yes, of course (name := expression) is an improvement over what we have now, and I'm grateful for that. It's just that when I explain it to my students (" = is just assignment, := is for assignment and displaying"), I have no good reason to tell them why they must put the parentheses---except "Python is too worried you will make a mistake", and that just doesn't seem like something Python usually does. (That's something Java would do to people.:)

    Yes, Jupyter sometimes does allow things that would otherwise be SyntaxErrors (though much less than they used to, since Python gave them a lot of headache by introducing decorators---if you remember that story;), and going to Jupyter was the next thing on my mind after I'm rejected here. I just thought it would be much easier to just allow this "at the source", so Jupyter people don't have to think "what if they finally allow toplevel walruses, but with different semantics (e.g., printing result even if it is None)?".

    Carol and Victor, I'm sorry I have usurped a bugtracker issue for this discussion. First, I really thought this is about implementation of assignment expressions, and this is the best place to put it. Second, I didn't expect a discussion---I thought it would be either "that makes no sense, go away" or "yeah, good idea, we'll do it". For the next such issue (there will probably be one:), do you suggest that the more appropriate thing would be to open a new issue?

    (Let me just reiterate that I'm not going to python-ideas. You probably can't understand how stressful that place is, but believe me, it is. I'm not the only one that thinks so. If that's the only sanctioned method to improve Python, even when it is about details, then I'll just withdraw from the game.)

    @nedbat
    Copy link
    Member

    nedbat commented Apr 24, 2019

    3.8.0a3 is out, and the What's New still doesn't mention this work yet.

    @emilyemorehouse
    Copy link
    Member Author

    Ned is correct! I will be sprinting on docs for this at PyCon.

    @nedbat
    Copy link
    Member

    nedbat commented Apr 24, 2019

    Maybe we could update the What's New quickly now, and then get the longer more complex docs done later? People have been asking if this feature is in 3.8 because they don't see it mentioned.

    @vedgar
    Copy link
    Mannequin

    vedgar mannequin commented Apr 24, 2019

    ... and probably also because they start Python, type

    x := 2
    

    and get SyntaxError (as explained above). ;-)

    @gvanrossum
    Copy link
    Member

    Ouch. That means we need to buy.p the puck format version number.

    --Guido (mobile)

    @pablogsal
    Copy link
    Member

    I have created PR14313 and triggered a custom build from that PR in the buildbots to confirm our hypothesis.

    @pablogsal
    Copy link
    Member

    Although it can be related, note that the buildbots do indeed delete pyc files. Check for example https://buildbot.python.org/all/#/builders/40/builds/2621/steps/2/logs/stdio :

    ...
    Deleting .pyc/.pyo files ...
    Deleting test leftovers ...
    Using "C:\buildbot.python.org\3.x.kloth-win64\build\PCbuild\\..\externals\pythonx86\tools\python.exe" (found in externals directory)
    Fetching external libraries...
    ...

    But I could be missing something. What I don't understand currently is why it fails only on the Windows buildbots.

    @gvanrossum
    Copy link
    Member

    I don't know why the failure is Windows-only, but I suspect that some of
    the cleanup doesn't work there...

    This definitely needs a bump of the pyc format version number.

    @miss-islington
    Copy link
    Contributor

    New changeset 874ff65 by Miss Islington (bot) in branch '3.8':
    bpo-35224: Reverse evaluation order of key: value in dict comprehensions (GH-14139)
    874ff65

    @pablogsal
    Copy link
    Member

    New changeset 663131a by Pablo Galindo in branch 'master':
    bpo-35224: Bump the pyc magic number after the change in MAP_ADD (GH-14313)
    663131a

    @miss-islington
    Copy link
    Contributor

    New changeset 5c8b4e2 by Miss Islington (bot) in branch '3.8':
    bpo-35224: Bump the pyc magic number after the change in MAP_ADD (GH-14313)
    5c8b4e2

    @gvanrossum
    Copy link
    Member

    How are the buildbots doing now?

    @pablogsal
    Copy link
    Member

    All buildbots for 3.8 and master are green again :)

    @serhiy-storchaka
    Copy link
    Member

    So bpo-29652 can be closed now? Was all concerns of previous discussions addressed?

    I suggest to increment the magic number by 1, not by 10. The space of magic numbers is finite.

    Add please a What's New entry for this change.

    @pablogsal
    Copy link
    Member

    New changeset b3ca797 by Pablo Galindo in branch 'master':
    bpo-35224: Bump the pyc magic number by 1 instead of by 10 in last modification (GH-14320)
    b3ca797

    @miss-islington
    Copy link
    Contributor

    New changeset 175b2e9 by Miss Islington (bot) in branch '3.8':
    bpo-35224: Bump the pyc magic number by 1 instead of by 10 in last modification (GH-14320)
    175b2e9

    @pablogsal
    Copy link
    Member

    New changeset b51b713 by Pablo Galindo in branch 'master':
    bpo-35224: Add What's new entry for evaluation order in dict comprehensions (GH-14319)
    b51b713

    @miss-islington
    Copy link
    Contributor

    New changeset ced9e11 by Miss Islington (bot) in branch '3.8':
    bpo-35224: Add What's new entry for evaluation order in dict comprehensions (GH-14319)
    ced9e11

    @warsaw
    Copy link
    Member

    warsaw commented Jul 15, 2019

    I might be missing it, but I think the Language Reference still doesn't document assignment expressions.

    https://docs.python.org/3/reference/lexical_analysis.html#operators

    There are likely other places in the LR that need to be filled out with PEP-572 documentation.

    @ncoghlan
    Copy link
    Contributor

    ncoghlan commented Aug 5, 2019

    Did the documentation PR get pushed/merged? Emily mentioned having one in progress above, but it doesn't appear in the linked PRs.

    @ncoghlan
    Copy link
    Contributor

    ncoghlan commented Aug 5, 2019

    https://bugs.python.org/issue37757 separates out the TargetScopeError handling for conflicts between assignment expressions and comprehension iteration variables.

    @ncoghlan
    Copy link
    Contributor

    ncoghlan commented Aug 5, 2019

    Also, a major procedural note: it is NOT OK to merge a PEP implementation that completely ignores parts of the PEP. The merged tests are actively forcing NON-compliance with the accepted PEP, since they're requiring implementations to accept code that the PEP explicitly states should be disallowed.

    Those rules were added because the behaviour in CPython leaks CPython implementation details that we *don't want* to be part of the language specification.

    @rhettinger
    Copy link
    Contributor

    FWIW, I'm working on an improved whatsnew entry in #15127

    @gvanrossum
    Copy link
    Member

    Thanks for catching that this was still incomplete.

    Also, a major procedural note: it is NOT OK to merge a PEP implementation that completely ignores parts of the PEP. The merged tests are actively forcing NON-compliance with the accepted PEP, since they're requiring implementations to accept code that the PEP explicitly states should be disallowed.

    It was known the implementation was unfinished in this respect, but it was deemed better to merge what we had lest the work be lost in merge conflicts, and iterate in later betas. I've written some code that uses the walrus operator and have found it quite solid. The early existence of an implementation (albeit incomplete) has also helped get support for this in mypy (python/mypy#6899).

    I don't recall being aware that there were tests that specifically *checked* that the implementation was incomplete, and that's obviously wrong.

    @ncoghlan
    Copy link
    Contributor

    ncoghlan commented Aug 5, 2019

    bpo-37757 now has an associated PR adding the missing TargetScopeError cases: #15131

    There's one case where it goes beyond what the PEP specifies: because the outermost iterable expression gets evaluated in a different scope from the rest of the comprehension, it just flat out prohibits the use of assignment expressions in comprehension iterable expressions.

    This was one of the cases where we explicitly didn't want the CPython implementation behaviour to leak into the language specification (as name binding in the outermost iterable expression would create an unrelated binding in the containing scope, while name binding in other iterable expressions would rebind any conflicting iteration variable in the comprehension), so the current PR takes the more conservative path, and defers allowing name binding in the iterable expressions until a specific use case for doing so is presented).

    @ncoghlan
    Copy link
    Contributor

    ncoghlan commented Aug 5, 2019

    Thanks Guido. The former test cases that the new PR removes are the following:

    res = [i := i for i in range(5)]
    res = [i := 0 for i, j in [(1, 2), (3, 4)]]
    res = [(i := 0, j := 1) for i, j in [(1, 2), (3, 4)]]
    res = [(i := i, j := j) for i, j in [(1, 2), (3, 4)]]
    res = [(i := j, j := i) for i, j in [(1, 2), (3, 4)]]

    These all raise TargetScopeError with the PR applied:

    >>> res = [i := i for i in range(5)]
      File "<stdin>", line 1
    TargetScopeError: named expression cannot rebind comprehension iteration variable
    >>> res = [i := 0 for i, j in [(1, 2), (3, 4)]]
      File "<stdin>", line 1
    TargetScopeError: named expression cannot rebind comprehension iteration variable
    >>> res = [(i := 0, j := 1) for i, j in [(1, 2), (3, 4)]]
      File "<stdin>", line 1
    TargetScopeError: named expression cannot rebind comprehension iteration variable
    >>> res = [(i := i, j := j) for i, j in [(1, 2), (3, 4)]]
      File "<stdin>", line 1
    TargetScopeError: named expression cannot rebind comprehension iteration variable
    >>> res = [(i := j, j := i) for i, j in [(1, 2), (3, 4)]]
      File "<stdin>", line 1
    TargetScopeError: named expression cannot rebind comprehension iteration variable

    @gvanrossum
    Copy link
    Member

    Can you suggest a PEP update too, for the case that goes beyond the PEP?
    And please provide examples (not everybody knows immediately what
    "outermost iterable expression" refers to. :-)

    @ncoghlan
    Copy link
    Contributor

    ncoghlan commented Aug 5, 2019

    Proposed PEP update is here: python/peps#1140

    The update also aims to clarify *why* we're doing the extra work in CPython's compiler to make these cases fail (i.e. we don't want to implicitly impose the current CPython runtime behaviour on other implementations)

    @miss-islington
    Copy link
    Contributor

    New changeset 6357c95 by Miss Islington (bot) (Emily Morehouse) in branch 'master':
    bpo-35224: Additional documentation for Assignment Expressions (GH-15935)
    6357c95

    @matrixise
    Copy link
    Member

    New changeset be2aa58 by Stéphane Wirtel (Miss Islington (bot)) in branch '3.8':
    bpo-35224: Additional documentation for Assignment Expressions (GH-15935) (GH-15967)
    be2aa58

    @emilyemorehouse
    Copy link
    Member Author

    All areas that were identified for additional work have been addressed.

    If there is anything else that needs to be improved or updated, please create a new issue.

    Thanks!

    @gvanrossum
    Copy link
    Member

    Congrats! Let's party.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.8 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests