[Python-Dev] elimination of scope bleeding of iteration variables

Ben Wing ben at 666.com
Sat Apr 29 11:16:59 CEST 2006


apologies if this has been brought up on python-dev already.

a suggestion i have, perhaps for python 3.0 since it may break some code 
(but imo it could go into 2.6 or 2.7 because the likely breakage would 
be very small, see below), is the elimination of the misfeature whereby 
the iteration variable used in for-loops, list comprehensions, etc. 
bleeds out into the surrounding scope.

[i'm aware that there is a similar proposal for python 3.0 for list 
comprehensions specifically, but that's not enough.]

i've been bitten by this problem more than once.  most recently, i had a 
simple function like this:

# Replace property named PROP with NEW in PROPLIST, a list of tuples.
def property_name_replace(prop, new, proplist):
    for i in xrange(len(proplist)):
        if x[i][0] == prop:
            x[i] = (new, x[i][1])

the use of `x' in here is an error, as it should be `proplist'; i 
previously had a loop `for x in proplist', but ran into the problem that 
tuples can't be modified, and lists can't be modified except by index.

despite this obviously bad code, however, it ran without any complaint 
from python -- which amazed me, when i finally tracked this problem 
down.  turns out i had two offenders, both way down in the "main" code 
at the bottom of the file -- a for-loop with loop variable x, and a list 
comprehension [x for x in output_file_map]  -- and suddenly `x' is a 
global variable.  yuck.

i suggest that the scope of list comprehension iteration variables be 
only the list comprehension itself (see python 3000), and the scope of 
for-loop iteration variables be only the for-loop (including any 
following `else' statement -- this way you can access it and store it in 
some other variable if you really want it).

in practice, i seriously doubt this will break much code and probably 
could be introduced like the previous scope change: using `from 
__future__' in python 2.5 or 2.6, and by default in the next version.  
it should be possible, in most circumstances, to issue a warning about 
code that relies on the old behavior.


ben



More information about the Python-Dev mailing list