From 9c611279202344d3c0d7bed9d3d987963d15ae01 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Tue, 10 Jul 2018 11:02:30 -0700 Subject: [PATCH] PEP 572: Tweaks suggested by Glenn Linderman and Tim Peters (#718) * PEP 572: Tweaks suggested on python-dev by Glenn Linderman. * Use Tim's rewording of the exceptional cases. * Clarify that TargetScopeError is a *new* subclass of SyntaxError. --- pep-0572.rst | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/pep-0572.rst b/pep-0572.rst index 2b5b29d20..9a8e6d601 100644 --- a/pep-0572.rst +++ b/pep-0572.rst @@ -148,7 +148,7 @@ in order to avoid ambiguities or user confusion: (y := f(x)) # Valid, though not recommended This rule is included to simplify the choice for the user between an - assignment statements and an assignment expression -- there is no + assignment statement and an assignment expression -- there is no syntactic position where both are valid. - Unparenthesized assignment expressions are prohibited at the top @@ -235,13 +235,21 @@ comprehension, for example:: partial_sums = [total := total + v for v in values] print("Total:", total) -An exception to this special case applies when the target name is the -same as a loop control variable for a comprehension containing it. -This is invalid. This exception exists to rule out edge cases of the -above scope rules as illustrated by ``[i := i+1 for i in range(5)]`` -or ``[[(j := j) for i in range(5)] for j in range(5)]``. Note that -this exception also applies to ``[i := 0 for i, j in stuff]``, as well -as to cases like ``[i+1 for i in i := stuff]``. +However, an assignment expression target name cannot be the same as a +``for``-target name appearing in any comprehension containing the +assignment expression. The latter names are local to the +comprehension in which they appear, so it would be contradictory for a +contained use of the same name to refer to the scope containing the +outermost comprehension instead. + +For example, ``[i := i+1 for i in range(5)]`` is invalid: the ``for +i`` part establishes that ``i`` is local to the comprehension, but the +``i :=`` part insists that ``i`` is not local to the comprehension. +The same reason makes these examples invalid too:: + + [[(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] A further exception applies when an assignment expression occurs in a comprehension whose containing scope is a class scope. If the rules @@ -260,13 +268,13 @@ See Appendix B for some examples of how the rules for targets in comprehensions translate to equivalent code. The two invalid cases listed above raise ``TargetScopeError``, a -subclass of ``SyntaxError`` (with the same signature). +new subclass of ``SyntaxError`` (with the same signature). Relative precedence of ``:=`` ----------------------------- The ``:=`` operator groups more tightly than a comma in all syntactic -positions where it is legal, but less tightly than all operators, +positions where it is legal, but less tightly than all other operators, including ``or``, ``and`` and ``not``. As follows from section "Exceptional cases" above, it is never allowed at the same level as ``=``. In case a different grouping is desired, parentheses should be