<div dir="auto"><div><br><br><div class="gmail_quote"><div dir="ltr">On Thu., 5 Jul. 2018, 10:23 am Steve Dower, <<a href="mailto:steve.dower@python.org">steve.dower@python.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 04Jul2018 1518, Tim Peters wrote:<br>
> The only new thing is specifying the scope of `a`, where "local to f"<br>
> means exactly the same thing as for any other name local to a function<br>
> today.  So far as the PEP semantics go, it doesn't even matter whether<br>
> an implementation _does_ implement some form of closure as such.  It<br>
> just has to provide the visible semantics of _lexically_ nested scopes<br>
> with indefinite extent, by whatever means it likes best.  That's what<br>
> "local to f" means (and has meant all along - well, since lexically<br>
> nested scopes were first introduced).<br>
<br>
In that case, please provide more examples of how it should work when<br>
the assignment expression appears to define a variable in a scope that<br>
is not on the call stack.<br>
<br>
Whether intentional or not, there will be changes to how and when names<br>
are resolved. The specification should provide enough information to<br>
determine the preferred behaviour, so we can tell the difference between<br>
intention changes and implementation bugs.<br>
<br>
For example, what should be returned from this function?<br>
<br>
>>> A = 0<br>
>>> def f(x):<br>
...     if x:<br>
...         [A := i for i in [1]]<br>
...     return A<br>
<br>
As far as I can tell, the closest current equivalent will not compile:<br>
<br>
>>> A = 0<br>
>>> def f(x):<br>
...     if x:<br>
...         def g():<br>
...             nonlocal A<br>
...             A = 1<br>
...         g()<br>
...     return A<br>
...<br>
  File "<stdin>", line 4<br>
SyntaxError: no binding for nonlocal 'A' found<br>
<br>
Is this the equivalent behaviour you want? Or do you want an<br>
UnboundLocalError when calling f(0)? Or do you want the global A to be<br>
returned? How should we approach decision making about these cases as we<br>
implement this? The PEP does not provide enough information for me to<br>
choose the right behaviour here, and I argue that it should.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Guido did fully specify this in his post on "__parentlocal" scoping, in response to my request that this be clearly spelled out in the PEP (that specification just hasn't been rolled back into the PEP yet).</div><div dir="auto"><br></div><div dir="auto">While Tim's correct that the underlying runtime semantics here aren't new (which is why PEP 558 doesn't need to change), there's a new requirement imposed on a Python compiler's symbol table analysis pass to see "A := expr" in a comprehension or generator expression scope and interpret that as equivalent to either:</div><div dir="auto"><br></div><div dir="auto">1. An implied "global A" in the child scope if the parent scope is the module scope, or A is explicitly declared as global in the parent scope</div><div dir="auto"><br></div><div dir="auto">2. An implied "nonlocal A" in the child scope if the parent scope is a function scope and A is not defined as global in that scope. If A is not already declared as local or nonlocal in the parent scope, then it is implicitly declared as local in that scope with no associated annotation (akin to "if 0: for A in (): pass")</div><div dir="auto"><br></div><div dir="auto">3. A compile time error if the parent scope is a class scope (since we don't have any existing scope declaration semantics that can be used to make that case work sensibly)</div><div dir="auto"><br></div><div dir="auto">I'm still wondering if it might make sense to define a new "TargetScopeError" subclass of SyntaxError for that last case, since it isn't the assignment expression syntax itself that's the problem: it's where that expression is located.</div><div dir="auto"><br></div><div dir="auto">Cheers,</div><div dir="auto">Nick.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Cheers,<br>
Steve<br>
_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org" target="_blank" rel="noreferrer">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com" rel="noreferrer noreferrer" target="_blank">https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com</a><br>
</blockquote></div></div></div>