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