contribute checking for "miscaptured" variables in loops
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Pyflakes |
New
|
Wishlist
|
Unassigned |
Bug Description
Tahoe-LAFS, a large Python codebase implementing a distributed filesystem, uses a script called "check-miscaptures" ( https:/
An example of incorrect code that it would catch is:
a = [None]*10
for i in range(0, 10):
a[i] = lambda x: x+i
# The programmer expected a[x](y) to be equivalent to x+y
print a[2](2) # not 4, but 11
This happens because all of the a[i] capture the same mutable variable i, which is 9 after the loop when the lambda is called.
For this example, the output of check-miscaptures is:
Checking miscapture.py...
miscapture.py:3 <lambda> captures 'i' assigned at line 2
1 suspiciously captured variables in 1 out of 1 file(s).
Changing the loop body to "a[i] = lambda x, i=i: x+i" fixes the problem, and check-miscaptures will not report a warning for the fixed code (it rarely gives false positives, and when it does they are easy to suppress).
The same problem can happen with named functions rather than lambdas, and with other kinds of loop or list comprehensions. More realistic examples are common in programs that define lots of callback functions, for example when using asynchronous libraries such as Twisted.
This ticket is to integrate the checking done by this script into pyflakes.
Changed in pyflakes: | |
importance: | Undecided → Wishlist |