pythonpython-2.7list-comprehensionflake8pyflakes

Is this a flake8 false positive, or am I really doing something wrong?


I have a function that can be simplified to this code sample:

def test_fun():
    for i in range(17):
        item = i
        print(item)
    for i in range(42):
        items = [[i], [i], [i]]
        flatten_items = [item[0] for item in items]
        print(flatten_items)

When I run pyflakes (1.3.0) or flake8 (3.2.0), I get the following report:

/tmp/test.py:7:38: F812 list comprehension redefines 'item' from line 3

What I see is that the item variable is indeed used twice, but under different scopes, so it shouldn't be reported, right?

Also, even if there was no second loop, why shouldn't I be allowed to rewrite the item variable, as I've finished working with the one I defined on line 3 since the print?

So, is this a false positive, or I am really writting a very poor piece of code?


Solution

  • List comprehension in Python 2.7 leaks local variable to enclosing scope.

    >>> import sys; sys.version_info
    sys.version_info(major=2, minor=7, micro=12, releaselevel='final', serial=0)
    >>> [item for item in ['a', 'b', 'c']]
    ['a', 'b', 'c']
    >>> item
    'c'
    

    This behavior was fixed in Python 3:

    >>> import sys; sys.version_info
    sys.version_info(major=3, minor=5, micro=2, releaselevel='final', serial=0)
    >>> [item for item in ['a', 'b', 'c']]
    ['a', 'b', 'c']
    >>> item
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'item' is not defined