[Tim, suggests changes to the Reference Manual's 4.2.1]
""" An assignment expression binds the target, except in a function F synthesized to implement a list comprehension or generator expression (see XXX). In the latter case, if the target is not in F's environment (see section 4.2.2) , the target is bound in the block containing F. """
Let me try that again ;-) The notion of "environment" includes the global scope, but that's not really wanted here. "Environment" has more of a runtime flavor anyway. And since nobody will tell me anything about class scope, I read the docs myself ;-) And that's a problem, I think! If a comprehension C is in class scope S, apparently the class locals are _not_ in C's environment. Since C doesn't even have read access to S's locals, it seems to me bizarre that ":=" could _create_ a local in S. Since I personally couldn't care less about running comprehensions of any kind at class scope, I propose to make `:=` a SyntaxError if someone tries to use a comprehension with ':=' at class scope (of course they may be able to use ":=" in nested comprehensions anyway - not that anyone would). If someone objects to that, fine, you figure it out ;-) So here's another stab. """ An assignment expression binds the target, except in a function F synthesized to implement a list comprehension or generator expression (see XXX). In the latter case[1]: - If the target also appears as an identifier target of a `for` loop header in F, a `SyntaxError` exception is raised. - If the block containing F is a class block, a `SyntaxError` exception is raised. - If the target is not local to any function enclosing F, and is not declared `global` in the block containing F, then the target is bound in the block containing F. Footnote: [1] The intent is that runtime binding of the target occurs as if the binding were performed in the block containing F. Because that necessarily makes the target not local in F, it's an error if the target also appears in a `for` loop header, which is a local binding for the same target. If the containing block is a class block, F has no access to that block's scope, so it doesn't make sense to consider the containing block. If the target is already known to the containing block, the target inherits its scope resolution from the containing block. Else the target is established as local to the containing block. """ I realize the docs don't generally use bullet lists. Convert to WallOfText if you must. The material in the footnote would usually go in a "Rationale" doc instead, but we don't have one of those, and I think the intent is too hard to deduce without that info. And repeating the other point, to keep a self-contained account:
Earlier, for now-necessary disambiguation, I expect that in
... targets that are identifiers if occurring in an assignment, ...
" statement" should be inserted before the comma.