<div dir="ltr">Thanks for thinking about the details! I want to answer all of these but right now I have some social obligations so it may be a few days. I expect the outcome of this investigation to result in an improved draft for PEP 572.<br></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Jul 4, 2018 at 7:29 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">Now that it's a done deal, I am closely reviewing the semantics section<br>
of PEP 572. (I had expected one more posting of the final PEP, but it<br>
seems the acceptance came somewhere in a thread that was already muted.)<br>
Since there has been no final posting that I'm aware of, I'm referring<br>
to <a href="https://www.python.org/dev/peps/pep-0572/" rel="noreferrer" target="_blank">https://www.python.org/dev/peps/pep-0572/</a> as of about an hour before<br>
posting this (hopefully it doesn't take me that long).<br>
To be clear, I am *only* looking at the "Syntax and semantics" section.<br>
So if something has been written down elsewhere in the PEP, please take<br>
my questions as a request to have it referenced from this section. I<br>
also gave up on the discussion by the third python-dev thread - if there<br>
were things decided that you think I'm stupid for not knowing, it<br>
probably means they never made it into the PEP.<br>
= Syntax and Semantics<br>
Could we include the changes necessary to<br>
<a href="https://docs.python.org/3/reference/grammar.html" rel="noreferrer" target="_blank">https://docs.python.org/3/reference/grammar.html</a> in order to specify<br>
where these expressions are valid? And ideally check that they work.<br>
This may expose new exceptional cases, but will also clarify some of the<br>
existing ones, especially for those of us who write Python parsers.<br>
== Exceptional cases<br>
Are the cases in the "Exceptional cases" section supposed to raise<br>
SyntaxError on compilation? That seems obvious, but no harm in stating<br>
it. (FWIW, I'd vote to ban the "bad" cases in style guides or by forcing<br>
parentheses, rather than syntactically. And for anyone who wonders why<br>
that's different from my position on slashes in f-strings, it's because<br>
I don't think we can ever resolve these cases but I hope that one day we<br>
can fix f-string slashes :) )<br>
== Scope of the target<br>
The PEP uses the phrase "an assignment expression occurs in a<br>
comprehension" - what does this mean? Does it occur when/where it is<br>
compiled, instantiated, or executed? This is important because where it<br>
occurs determines which scope will be modified. For sanity sake, I want<br>
to assume that it means compiled, but now what happens when that scope<br>
is gone?<br>
>>> def f():<br>
...     return (a := i for i in range(5))<br>
>>> list(f())<br>
[0, 1, 2, 3, 4]   # or a new error because the scope has gone?<br>
>>> a<br>
I'll push back real hard on doing the assignment in the scope where the<br>
generator is executed:<br>
>>> def do_secure_op(name, numbers):<br>
...     authorised = check_authorised(name)<br>
...     if not all(numbers):<br>
...         raise ValueError()<br>
...     if not authorised:<br>
...         raise SecurityError()<br>
...     print('You made it!')<br>
>>> do_secure_op('whatever', (authorised := i for i in [1, 2, 3]))<br>
You made it!<br>
>>> authorised<br>
NameError: name 'authorised' is undefined<br>
>From the any()/all() examples, it seems clear that the target scope for<br>
the assignment has to be referenced from the generator scope (but not<br>
for other comprehension types, which can simply do one transfer of the<br>
assigned name after fully evaluating all the contents). Will this<br>
reference keep the frame object alive for as long as the generator<br>
exists? Can it be a weak reference? Are assignments just going to be<br>
silently ignored when the frame they should assign to is gone? I'd like<br>
to see these clarified in the main text.<br>
When an assignment is "expressly invalid" due to avoiding "edge cases",<br>
does this mean we should raise a SyntaxError? Or a runtime error? I'm<br>
not sure how easily these can be detected by our current compiler (or<br>
runtime, for that matter), but in the other tools that I work on it<br>
isn't going to be a trivial check.<br>
Also, I'm not clear at all on why [i := i+1 for i in range(5)] is a<br>
problem? Similarly for the other examples here. There's nothing wrong<br>
with `for i in range(5): i = i+1`, so why forbid this?<br>
== Relative precedence<br>
"may be used directly in a positional function call argument" - why not<br>
use the same syntax as generator expressions? Require parentheses unless<br>
it's the only argument. It seems like that's still got a TODO on it from<br>
one of the examples, so consider this a vote for matching<br>
generator-as-argument syntax.<br>
== Differences between assignment expressions<br>
I'm pretty sure the equivalent of "x = y = z = 0" would be "z := (y :=<br>
(x := 0))". Not that it matters when there are no side-effects of<br>
assignment (unless we decide to raise at runtime for invalid<br>
assignments), but it could become a point of confusion for people in the<br>
future to see it listed like this. Assignment expressions always<br>
evaluate from innermost to outermost.<br>
Gramatically, "Single assignment targets *other than* NAME are not<br>
supported" would be more precise. And for specification's sake, does<br>
"not supported" mean "is a syntax error"?<br>
The "equivalent needs extra parentheses" examples add two sets of extra<br>
parentheses. Are both required? Or just the innermost set?<br>
Apologies for the lack of context. I've gone back and added the section<br>
headings for as I read through this section.<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org" target="_blank">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/guido%40python.org" rel="noreferrer" target="_blank">https://mail.python.org/mailman/options/python-dev/guido%40python.org</a><br>
</blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido">python.org/~guido</a>)</div>