astral-sh/ruff

F841 treats `except` bindings differently from all other bindings

Open

#16,537 建立於 2025年3月6日

在 GitHub 查看
 (2 留言) (0 反應) (0 負責人)Rust (47,527 star) (2,088 fork)batch import
bughelp wanted

描述

Summary

The implementation of unused-variable (F841) is split: except bindings are handled separately in bindings.rs, causing false positives. They should be processed consistently with other bindings.

One false positive occurs when the bound variable is not used within the except block but is used outside it. The fix can change program behavior by suppressing a runtime error. The fix could be beneficial, but it should be marked unsafe like other unused bindings’ fixes.

$ cat >f841_1.py <<'# EOF'
def f():
    e = None
    try:
        1 / 0
    except ZeroDivisionError as e:
        pass
    print(e)
f()
# EOF

$ python f841_1.py 2>&1 | tail -n 1
UnboundLocalError: cannot access local variable 'e' where it is not associated with a value

$ ruff --isolated check --select F841 f841_1.py --fix
Found 1 error (1 fixed, 0 remaining).

$ cat f841_1.py
def f():
    e = None
    try:
        1 / 0
    except ZeroDivisionError:
        pass
    print(e)
f()

$ python f841_1.py
None

Another false positive occurs when the binding is not within a function.

$ cat >f841_2.py <<'# EOF'
e = None
try:
    1 / 0
except ZeroDivisionError as e:
    pass
print(e)
# EOF

$ python f841_2.py 2>&1 | tail -n 1
NameError: name 'e' is not defined

$ ruff --isolated check --select F841 f841_2.py --fix
Found 1 error (1 fixed, 0 remaining).

$ cat f841_2.py
e = None
try:
    1 / 0
except ZeroDivisionError:
    pass
print(e)

$ python f841_2.py
None

There are other false positives, but they are all variations on the same theme. They can probably all be fixed by merging the two F841 implementations.

Version

ruff 0.9.9 (091d0af2a 2025-02-28)

貢獻者指南