[New-bugs-announce] [issue43281] Walrus comprehension rebind checking behavior

Saiyang Gou report at bugs.python.org
Sat Feb 20 20:20:04 EST 2021


New submission from Saiyang Gou <gousaiyang223 at gmail.com>:

# test

PEP 572 disallows walrus use cases such as `[(i := 1) for i in [1]]`, because `for i` implies that `i` is local to the comprehension but `(i := 1)` implies that `i` is "exported", which is a contradiction. However, I noticed the following behavior both in 3.8 and 3.9:

>>> [(a := 1) for a, (*b, c[d+e::f(g)], h.i) in [1]]
  File "<stdin>", line 1
SyntaxError: assignment expression cannot rebind comprehension iteration variable 'a'
>>> [(b := 1) for a, (*b, c[d+e::f(g)], h.i) in [1]]
  File "<stdin>", line 1
SyntaxError: assignment expression cannot rebind comprehension iteration variable 'b'
>>> [(c := 1) for a, (*b, c[d+e::f(g)], h.i) in [1]]
  File "<stdin>", line 1
SyntaxError: assignment expression cannot rebind comprehension iteration variable 'c'
>>> [(d := 1) for a, (*b, c[d+e::f(g)], h.i) in [1]]
  File "<stdin>", line 1
SyntaxError: assignment expression cannot rebind comprehension iteration variable 'd'
>>> [(e := 1) for a, (*b, c[d+e::f(g)], h.i) in [1]]
  File "<stdin>", line 1
SyntaxError: assignment expression cannot rebind comprehension iteration variable 'e'
>>> [(f := 1) for a, (*b, c[d+e::f(g)], h.i) in [1]]
  File "<stdin>", line 1
SyntaxError: assignment expression cannot rebind comprehension iteration variable 'f'
>>> [(g := 1) for a, (*b, c[d+e::f(g)], h.i) in [1]]
  File "<stdin>", line 1
SyntaxError: assignment expression cannot rebind comprehension iteration variable 'g'
>>> [(h := 1) for a, (*b, c[d+e::f(g)], h.i) in [1]]
  File "<stdin>", line 1
SyntaxError: assignment expression cannot rebind comprehension iteration variable 'h'
>>> [(i := 1) for a, (*b, c[d+e::f(g)], h.i) in [1]]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
TypeError: cannot unpack non-iterable int object

Among all of these assignment expressions, only the assignment to `i` (attribute name) is allowed. However, in my understanding, only `a` and `b` should be disallowed for assignment. This comprehension example only creates two new variables, `a` and `b`, which are local to the comprehension. Assignment expressions assigning to `c`, `d`, `e`, `f`, `g` and `h` should be allowed. `c` and `h` are already in the outer scope. `d`, `e`, `f` and `g` are just names inside the expression in the subscript part. They are not "comprehension iteration variables" and not local to the comprehension.

The same behavior is also observed when detecting inner loop variable rebinding outer loop assignment expression targets:

>>> [i for i in range(5) if (j := 0) for k[j + 1] in range(5)]
  File "<stdin>", line 1
SyntaxError: comprehension inner loop cannot rebind assignment expression target 'j'

----------
messages: 387433
nosy: gousaiyang
priority: normal
severity: normal
status: open
title: Walrus comprehension rebind checking behavior
type: behavior
versions: Python 3.10, Python 3.8, Python 3.9

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue43281>
_______________________________________


More information about the New-bugs-announce mailing list