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

Tim Peters tim.peters at gmail.com
Fri May 11 03:59:00 EDT 2018


[Tim]
>> Since this is all about scope, while I'm not 100% sure of what Guido
>> meant, I assumed he was saying "p can only have one scope in the
>> synthetic function:  local or non-local, not both, and local is what I
>> propose".  For example, let's flesh out his example a bit more:
>>
>>     p = 42
>>     [p := p for p in range(10) if p == 3]
>>     print(p) # 42?  3?  9?
>>
>> If `p` is local to the listcomp, it must print 42.  If `p` is
>> not-local, it must print 9.  If it's some weird mixture of both, 3
>> makes most sense (the only time `p := p` is executed is when the `for`
>> target `p` is 3).

[Jacco van Dorp <j.van.dorp at deonet.nl>]
> With my limited experience, I'd consider 3 to make most sense, but 9
> when thinking about it in the expanded form.
>
> If it's not 3 tho, then the following would make most sense:
>
> SyntaxError("Cannot re-bind for target name in a list comprehension")
> # Or something more clear.
>
> And the rest of that mail that convinces me even more that an error
> would be the correct solution here.

Good news, then:  Nick & Guido recently agreed that it would be a
compile-time error.  Assuming it's added to the language at all, of
course.


> Before I got on this mailinglist, i never even knew comprehensions
> introduced a new scope. I'm really that new.

They didn't, at first.  That changed over time.  The real reason was
so that `for` variables - which people typically give little thought
to naming - didn't accidentally overwrite local variables that
happened to share the same name.  Like:

>>> i = -42
>>> [i+1 for i in range(3)]
[1, 2, 3]
>>> i  # unchanged!
-42

But you can productively use list comprehensions without knowing
anything about how they're implemented, and just think "ha!  Python
does some happy magic for me there :-)".


> Two years ago I'd look up stackoverflow to check the difference between
> overriding and extending a method and to verify whether I made my
> super() calls the right way.
>
> If something goes to weird, I think just throwing exceptions is a
> sensible solution that keeps the language simple, rather than making
> that much of a headache of something so trivially avoided.

Since Guido agreed with you in this case, that proves you're a true
Pythonista - or maybe just that you're both Dutch ;-)


More information about the Python-ideas mailing list