
[Guido]
So the way I envision it is that *in the absence of a nonlocal or global declaration in the containing scope*, := inside a comprehension or genexpr causes the compiler to assign to a local in the containing scope, which is elevated to a cell (if it isn't already). If there is an explicit nonlocal or global declaration in the containing scope, that is honored.
[Juancarlo AƱez <apalala@gmail.com>]
This seems to be getting awfully complicated. Proof? Try to write the docs for the proposed semantics.
Implementation details - even just partial sketches - are always "busy". Think of it this way instead: it's _currently_ the case that listcomps & genexps run in a scope S that's the same as the scope C that contains them, _except_ that names appearing as `for` targets are local to S. All other names in S resolve to exactly the same scopes they resolved to in C (local in C, global in C, nonlocal in C - doesn't matter). What changes now? Nothing in that high-level description, except that a name appearing as a binding expression target in S that's otherwise unknown in C establishes that the name is local to C. That's nothing essentially new, though - bindings _always_ establish scopes for otherwise-unknown names in Python.
I don't understand why we went so astray from the original requirements, which could all be met by having `if` and `while` accept `as` to bind an expression to a variable that would be local to the structured statement.
"Original" depends on when you first jumped into this ;-)