[ruff] Don't emit used-dummy-variable on function parameters (RUF052) (#14818)

This commit is contained in:
Alex Waygood 2024-12-06 14:54:42 +00:00 committed by GitHub
parent 6b9f3d7d7c
commit 4fdd4ddfaa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 23 additions and 112 deletions

View file

@ -77,7 +77,7 @@ class Class_:
_var = "method variable" # [RUF052] _var = "method variable" # [RUF052]
return _var return _var
def fun(_var): # [RUF052] def fun(_var): # parameters are ignored
return _var return _var
def fun(): def fun():

View file

@ -1,7 +1,7 @@
use ruff_diagnostics::{Diagnostic, Fix, FixAvailability, Violation}; use ruff_diagnostics::{Diagnostic, Fix, FixAvailability, Violation};
use ruff_macros::{derive_message_formats, ViolationMetadata}; use ruff_macros::{derive_message_formats, ViolationMetadata};
use ruff_python_ast::helpers::is_dunder; use ruff_python_ast::helpers::is_dunder;
use ruff_python_semantic::{Binding, BindingKind, ScopeId}; use ruff_python_semantic::{Binding, ScopeId};
use ruff_python_stdlib::{ use ruff_python_stdlib::{
builtins::is_python_builtin, identifiers::is_identifier, keyword::is_keyword, builtins::is_python_builtin, identifiers::is_identifier, keyword::is_keyword,
}; };
@ -93,13 +93,27 @@ pub(crate) fn used_dummy_variable(checker: &Checker, binding: &Binding) -> Optio
if binding.is_unused() { if binding.is_unused() {
return None; return None;
} }
// Only variables defined via function arguments or assignments.
if !matches!( // We only emit the lint on variables defined via assignments.
binding.kind, //
BindingKind::Argument | BindingKind::Assignment // ## Why not also emit the lint on function parameters?
) { //
// There isn't universal agreement that leading underscores indicate "unused" parameters
// in Python (many people use them for "private" parameters), so this would be a lot more
// controversial than emitting the lint on assignments. Even if it's decided that it's
// desirable to emit a lint on function parameters with "dummy variable" names, it would
// possibly have to be a separate rule or we'd have to put it behind a configuration flag,
// as there's much less community consensus about the issue.
// See <https://github.com/astral-sh/ruff/issues/14796>.
//
// Moreover, autofixing the diagnostic for function parameters is much more troublesome than
// autofixing the diagnostic for assignments. See:
// - <https://github.com/astral-sh/ruff/issues/14790>
// - <https://github.com/astral-sh/ruff/issues/14799>
if !binding.kind.is_assignment() {
return None; return None;
} }
// This excludes `global` and `nonlocal` variables. // This excludes `global` and `nonlocal` variables.
if binding.is_global() || binding.is_nonlocal() { if binding.is_global() || binding.is_nonlocal() {
return None; return None;

View file

@ -20,31 +20,9 @@ RUF052.py:77:9: RUF052 [*] Local dummy variable `_var` is accessed
77 |+ var = "method variable" # [RUF052] 77 |+ var = "method variable" # [RUF052]
78 |+ return var 78 |+ return var
79 79 | 79 79 |
80 80 | def fun(_var): # [RUF052] 80 80 | def fun(_var): # parameters are ignored
81 81 | return _var 81 81 | return _var
RUF052.py:80:9: RUF052 [*] Local dummy variable `_var` is accessed
|
78 | return _var
79 |
80 | def fun(_var): # [RUF052]
| ^^^^ RUF052
81 | return _var
|
= help: Remove leading underscores
Safe fix
77 77 | _var = "method variable" # [RUF052]
78 78 | return _var
79 79 |
80 |-def fun(_var): # [RUF052]
81 |- return _var
80 |+def fun(var): # [RUF052]
81 |+ return var
82 82 |
83 83 | def fun():
84 84 | _list = "built-in" # [RUF052]
RUF052.py:84:5: RUF052 [*] Local dummy variable `_list` is accessed RUF052.py:84:5: RUF052 [*] Local dummy variable `_list` is accessed
| |
83 | def fun(): 83 | def fun():

View file

@ -20,31 +20,9 @@ RUF052.py:77:9: RUF052 [*] Local dummy variable `_var` is accessed
77 |+ var = "method variable" # [RUF052] 77 |+ var = "method variable" # [RUF052]
78 |+ return var 78 |+ return var
79 79 | 79 79 |
80 80 | def fun(_var): # [RUF052] 80 80 | def fun(_var): # parameters are ignored
81 81 | return _var 81 81 | return _var
RUF052.py:80:9: RUF052 [*] Local dummy variable `_var` is accessed
|
78 | return _var
79 |
80 | def fun(_var): # [RUF052]
| ^^^^ RUF052
81 | return _var
|
= help: Remove leading underscores
Safe fix
77 77 | _var = "method variable" # [RUF052]
78 78 | return _var
79 79 |
80 |-def fun(_var): # [RUF052]
81 |- return _var
80 |+def fun(var): # [RUF052]
81 |+ return var
82 82 |
83 83 | def fun():
84 84 | _list = "built-in" # [RUF052]
RUF052.py:84:5: RUF052 [*] Local dummy variable `_list` is accessed RUF052.py:84:5: RUF052 [*] Local dummy variable `_list` is accessed
| |
83 | def fun(): 83 | def fun():

View file

@ -1,55 +1,6 @@
--- ---
source: crates/ruff_linter/src/rules/ruff/mod.rs source: crates/ruff_linter/src/rules/ruff/mod.rs
--- ---
RUF052.py:21:9: RUF052 Local dummy variable `arg` is accessed
|
19 | _valid_fun()
20 |
21 | def fun(arg):
| ^^^ RUF052
22 | _valid_unused_var = arg
23 | pass
|
RUF052.py:50:18: RUF052 Local dummy variable `self` is accessed
|
48 | print(_valid_private_cls_attr)
49 |
50 | def __init__(self):
| ^^^^ RUF052
51 | self._valid_private_ins_attr = 2
52 | print(self._valid_private_ins_attr)
|
RUF052.py:54:23: RUF052 Local dummy variable `self` is accessed
|
52 | print(self._valid_private_ins_attr)
53 |
54 | def _valid_method(self):
| ^^^^ RUF052
55 | return self._valid_private_ins_attr
|
RUF052.py:57:16: RUF052 Local dummy variable `arg` is accessed
|
55 | return self._valid_private_ins_attr
56 |
57 | def method(arg):
| ^^^ RUF052
58 | _valid_unused_var = arg
59 | return
|
RUF052.py:61:9: RUF052 Local dummy variable `x` is accessed
|
59 | return
60 |
61 | def fun(x):
| ^ RUF052
62 | _ = 1
63 | __ = 2
|
RUF052.py:77:9: RUF052 Local dummy variable `_var` is accessed RUF052.py:77:9: RUF052 Local dummy variable `_var` is accessed
| |
75 | class Class_: 75 | class Class_:
@ -60,16 +11,6 @@ RUF052.py:77:9: RUF052 Local dummy variable `_var` is accessed
| |
= help: Remove leading underscores = help: Remove leading underscores
RUF052.py:80:9: RUF052 Local dummy variable `_var` is accessed
|
78 | return _var
79 |
80 | def fun(_var): # [RUF052]
| ^^^^ RUF052
81 | return _var
|
= help: Remove leading underscores
RUF052.py:84:5: RUF052 Local dummy variable `_list` is accessed RUF052.py:84:5: RUF052 Local dummy variable `_list` is accessed
| |
83 | def fun(): 83 | def fun():