PyCQA / flake8-bugbear

A plugin for Flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle.
MIT License
1.07k stars 107 forks source link

Loop variable use in closure not considered #175

Open inducer opened 3 years ago

inducer commented 3 years ago

Running

flake8==3.9.2
flake8-bugbear==21.4.3
flake8-polyfill==1.0.2
flake8-quotes==3.2.0

on

def main():
    def f(x):
        print(i, x)

    for i in [1, 2, 3]:
        f('HI')

gives me

bugbearbug.py:5:9: B007 Loop control variable 'i' not used within the loop body. If this is intended, start the name with an underscore.

Clearly, i is being used (within the nested function), but bugbear doesn't seem to see it.

cooperlees commented 3 years ago

Putting my dislike for this usage aside, if someone can make the AST parser work this logic out and can show that in unittests I'll accept this. This, of course, unless someone else speaks up and gives reasons not to. I feel this will just reduce false positives.

My personal though is one should always use a function the way functions are designed to be used and not abuse scope. For example the code could be:

def main():
    def f(x, main_i):
        print(main_i, x)

    for i in [1, 2, 3]:
        f('HI', i)

I feel this has readability advantages and is harder to miss where i comes from. It also would no longer trigger bugbear B007.