[Python-ideas] A comprehension scope issue in PEP 572

Tim Peters tim.peters at gmail.com
Sat May 12 22:17:54 EDT 2018

>> That's all well and good, but it is *completely insufficient for the
>> language specification*.

> I haven't been trying to write reference docs here, but so far as
> supplying a rigorous specification goes, I maintain the above gets
> "pretty close".  It needs more words, and certainly isn't in the
> _style_ of Python's current reference docs, but that's all repairable.
> Don't dismiss it just because it's brief.  Comprehensions already
> exist in the language, and so do nested scopes, so it's not necessary
> for this PEP to repeat any of the stuff that goes into those.  Mostly
> it needs to specify the scopes of assignment expression target names -
> and the _intent_ here is really quite simple.
> Here with more words, restricted to the case of assignment expressions
> in comprehensions (the only case with any subtleties):
> ...

And if you didn't like those words, you're _really_ gonna hate this
;-)  I don't believe more than just the following is actually
necessary, although much more than this would be helpful.  I spent the
first 15-plus years of my career writing compilers for a living, so am
sadly resigned to the "say the minimum necessary for a long argument
to conclude that it really was the minimum necessary" style of
language specs.  That's why I exult in giving explanations and
examples that might actually be illuminating - it's not because I
_can't_ be cryptically terse ;-)

Section 4.2.1 (Binding of names) of the Language Reference Manual has
a paragraph starting with "The following constructs bind names:".  It
really only needs another two-sentence paragraph after that to capture
all of the PEP's intended scope semantics (including my suggestion):

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.

That explicitly restates my earlier "rule #2" in the language already
used by the manual.  My "rule #1" essentially vanishes as such,
because it's subsumed by what the manual already means by "F's

This may also be the best place to add another new sentence.:

Regardless, if the target also appears as an identifier target of a
`for` loop header in F, a `SyntaxError` exception is raised.

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.

More information about the Python-ideas mailing list