On Wed, Nov 26, 2014 at 12:41 AM, <code-quality.wting@xoxy.net> wrote:
Python binds list comprehension variables to the local scope which has
caused some subtle bugs. Is it possible to add a warning for this in
pyflakes?

 A guiding principle of pyflakes's design is that it doesn't have warnings. If it complains about anything, it is because it's almost certainly useless or broken code. Using a list comprehension variable outside of the comprehension is perfectly valid according to python2:

>>> [x for x in range(3)]
[0, 1, 2]
>>> x
2

but an error in python3, which has different scoping rules:

>>> [x for x in range(3)]
[0, 1, 2]
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined

So in the case of python3, it's a bug that it doesn't emit a warning for this code. For python2, pyflakes is working as designed.

There's an issue, though. Pyflakes doesn't know if it's checking python2 or python3 code. It uses the AST of whatever python is running pyflakes, and if you look around checker.py[1] you can see there are some conditionals on PY2, PY32 and PY33. I think though all of these are to accommodate differences in the AST, but not to alter the checking semantics.

Given that parsing python2 with a python3 AST is already going to be problematic for a lot of other reasons (like `print` vs `print()`), maybe the thing to do is say that pyflakes always checks input against the semantics of the version of python running pyflakes. Then implement some tests, and change how list comprehensions are handled[2] to be conditional on the version. I think everyone using pyflakes for python2 and python3 concurrently either has it installed twice or invokes it with the interpreter corresponding to what they want to check, ie `python2 -m pyflakes` or `python3 -m pyflakes`, so I can't think of any reason this wouldn't work, and then pyflakes can continue not having any configuration file or options. Pull requests welcome.

  [1]: https://github.com/pyflakes/pyflakes/blob/master/pyflakes/checker.py
  [2]: https://github.com/pyflakes/pyflakes/blob/master/pyflakes/checker.py#L657