osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Python-Dev] PEP 572 semantics


On 04Jul2018 1021, Tim Peters wrote:
> Same as now, `i` is local to the synthetic nested function created for 
> the genexp.? The scope of `a` is determined by pretending the assignment 
> occurred in the block containing the outermost (textually - static 
> analysis) comprehension.? In this case, `a = anything` before the 
> `return` would establish that `a` is local to `f`, so that's the 
> answer:? `a` is local to `f`.? If `a` had been declared global in `f`, 
> then `a` in the genexp would be the same global `a`.? And similarly if 
> `a` had been declared nonlocal.in <http://nonlocal.in> `f`.
> 
> In all cases the scope resolution is inherited from the closest 
> containing non-comprehension/genexp block, with the twist if that if a 
> name is unknown in that block, the name is established as being local to 
> that block.? So your example is actually the subtlest case.

Okay, so as far as the specification goes, saying "assignment 
expressions in comprehensions get or create a cell variable in the 
defining scope and update its value" satisfies me just fine (or some 
other wording that more closely mirrors the actual behaviour - all my 
work here is on my own compiler, not the actual CPython one, and I don't 
know that they're identical).

I don't think this should be left assumed by the PEP. If it's likely to 
be a restriction on other implementations to say "cell variable", then 
say "For example, in CPython, ..."

>  > From the any()/all() examples, it seems clear that the target scope for
>  > the assignment has to be referenced from the generator scope (but not
>  > for other comprehension types, which can simply do one transfer of the
>  > assigned name after fully evaluating all the contents).
> 
> I don't think that follows.? It _may_ in some cases.? For example,
> [SNIP]
> _While_ the list comprehension is executing, it needs to rebind f's `i` 
> on each iteration so that the call to `g()` on each iteration can see 
> `i`'s then-current value.

Good point. My statement above captures this nuance, as far as I'm 
concerned. (Same for the frame lifetime discussion, which I snipped).

Cheers,
Steve