pyflakes icon indicating copy to clipboard operation
pyflakes copied to clipboard

F841 reports misleading location in try/except block

Open andialbrecht opened this issue 7 years ago • 3 comments

In this example pyflakes reports a misleading location for an unused variable:

$ cat example.py 
def foo():
    exc = None
    try:
        print('foo')
    except NameError as exc:
        print(exc)

$ pyflakes example.py 
example.py:5: local variable 'exc' is assigned to but never used

pyflakes reports exc on line 5 (the except line) as unused, which is misleading in my opinion since it's used within the exception handling. I guess that pyflakes recognizes that exc from line 2 (exc = None) as unused (which is unused actually), but determines line 5 as the last occuring declaration of exc.

andialbrecht avatar Oct 30 '18 11:10 andialbrecht

Note that this only errors in python3, probably due to the "new" exception scoping rules (except ... as e is roughly equivalent to that block of code; del e):

$ ./venv2/bin/pyflakes t.py
$ ./venv3/bin/pyflakes t.py
t.py:5: local variable 'exc' is assigned to but never used

asottile avatar Oct 30 '18 15:10 asottile

note that the above code example in python3 will throw a NameError (global scope) or UnboundLocalError (function scope), at least for me in Py3.6.6, if you would actually use exc after that block

exc = None
try:
    raise Exception("Error.")
except Exception as exc:
    print(exc)
print(exc) # raises Error.

interestingly even like this

def testing(exc=None):
    try:
        raise Exception("Error.")
    except Exception as exc:
        print(exc)
    print(exc)

testing() # raises error.
testing('abc') # also raises error.

so i guess flagging it as unused is quite useful info, but even if you would use it, it would not be good.

g4borg avatar Nov 28 '18 09:11 g4borg

#345 is closely related

asottile avatar Jul 11 '22 17:07 asottile