[Python-ideas] A comprehension scope issue in PEP 572

Chris Angelico rosuav at gmail.com
Mon May 7 08:38:51 EDT 2018

On Mon, May 7, 2018 at 9:42 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Mon, May 07, 2018 at 12:48:53PM +1000, Chris Angelico wrote:
>> On Mon, May 7, 2018 at 12:34 PM, Tim Peters <tim.peters at gmail.com> wrote:
>> > There's a difference, though:  if `y` "leaks", BFD.  Who cares? ;-)
>> > If `y` remains inaccessible, there's no way around that.
>> That's Steve D'Aprano's view - why not just let them ALL leak? I don't
>> like it though.
> I know popular opinion is against me, and backward compatibility and all
> that, but I wish that generator expressions and comprehensions ran
> in their surrounding scope, like regular for statements.
> (Yes, I know that makes generator expressions tricky to implement. As
> the guy who doesn't have to implement it, I don't have to care :-)

Yeah, it's really easy when you don't have to worry about how on earth
you can implement the concept of "unexecuted block of code that can be
executed later even after the surrounding context has returned, but
which isn't a function". :)

> (3) A compromise: binding assignments are scoped local to the
> comprehension, but they are initialised from their surrounding scope.
> This would be similar to the way Lua works, as well as function
> parameter defaults.
> I have some vague ideas about implementation, but there's no point
> discussing that unless people actually are interested in this option.
> This will *half* satisfy the running-total example:
>     total = 0
>     running_totals = [(total := total + x) for x in [98, 99]]
>     assert total == 0
> Guaranteed to generate at least two Stackoverflow posts a month
> complaining about it, but better than nothing :-)

Does it HAVE to be initialised from the surrounding scope? What if the
surrounding scope doesn't have that variable?

stuff = [spam for x in items if (spam := f(x)) < 0]

Is this going to NameError if you haven't defined spam? Or is the
compiler to somehow figure out whether or not to pull in a value?
Never mind about implementation - what are the semantics?

>> Having
>> the iteration variable NOT leak means it's a self-contained unit that
>> simply says "that thing we're iterating over".
> Assuming there are no side-effects to any of the operations inside the
> comprehension.

Which is often the case.

>> Part of it is just that people seem to be fighting for the sake of
>> fighting.
> Them's fightin' words! *wink*
> Honestly Chris, I know this must be frustrating, but I'm not fighting
> for the sake of it, and I doubt Tim is either. I'm arguing because there
> are real use-cases which remain unmet if binding-variables inside
> comprehensions are confined to the comprehension.

I don't think you are and I don't think Tim is. But do you honestly
want to say that about EVERY person in these threads?


More information about the Python-ideas mailing list