On 19 April 2018 at 02:18, Guido van Rossum
On Wed, Apr 18, 2018 at 7:35 AM, Chris Angelico
wrote: On Wed, Apr 18, 2018 at 11:58 PM, Guido van Rossum
wrote: 2) Genexps will eagerly evaluate a lookup if it happens to be the same name as an internal iteration variable. I think we would have to specify this more precisely.
Let's say by "eagerly evaluate a lookup" you mean "include it in the function parameters with a default value being the lookup (i.e. starting in the outer scope), IOW "t=t" as I showed above. The question is *when* we would do this. IIUC the PEP already does this if the "outer scope" is a class scope for any names that a simple static analysis shows are references to variables in the class scope. (I don't know exactly what this static analysis should do but it could be as simple as gathering all names that are assigned to in the class, or alternatively all names assigned to before the point where the comprehension occurs. We shouldn't be distracted by dynamic definitions like `exec()` although we should perhaps be aware of `del`.)
My proposal is to extend this static analysis for certain loop control variables (any simple name assigned to in a for-clause in the comprehension), regardless of what kind of scope the outer scope is. If the outer scope is a function we already know how to do this. If it's a class we use the analysis referred to above. If the outer scope is the global scope we have to do something new. I propose to use the same simple static analysis we use for class scopes.
Furthermore I propose to *only* do this for the loop control variable(s) of the outermost for-clause, since that's the only place where without all this rigmarole we would have a clear difference in behavior with Python 3.7 in cases like [t for t in t]. Oh, and probably we only need to do this if that loop control variable is also used as an expression in the iterable (so we don't waste time doing any of this for e.g. [t for t in q]).
I'm not sure the symtable pass is currently clever enough to make these kinds of distinctions - it's pretty thoroughly block scope oriented. (Although I guess it *does* know enough now to treat the outermost comprehension as being part of the surrounding scope in terms of where names are referenced, so it might be feasible to adapt that logic to enable the eager binding you're describing). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia