[ruff] Mark autofix for RUF052 as always unsafe (#14824)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo build (release) (push) Waiting to run
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions

This commit is contained in:
Alex Waygood 2024-12-09 23:11:44 +00:00 committed by GitHub
parent ab26d9cf9a
commit e3f34b8f5b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 46 additions and 31 deletions

View file

@ -16,8 +16,6 @@ use crate::{checkers::ast::Checker, renamer::Renamer};
/// By default, "dummy variables" are any variables with names that start with leading
/// underscores. However, this is customisable using the [`lint.dummy-variable-rgx`] setting).
///
/// Dunder variables are ignored by this rule, as are variables named `_`.
///
/// ## Why is this bad?
/// Marking a variable with a leading underscore conveys that it is intentionally unused within the function or method.
/// When these variables are later referenced in the code, it causes confusion and potential misunderstandings about
@ -27,18 +25,25 @@ use crate::{checkers::ast::Checker, renamer::Renamer};
/// Sometimes leading underscores are used to avoid variables shadowing other variables, Python builtins, or Python
/// keywords. However, [PEP 8] recommends to use trailing underscores for this rather than leading underscores.
///
/// Dunder variables are ignored by this rule, as are variables named `_`.
/// Only local variables in function scopes are flagged by the rule.
///
/// ## Example
/// ```python
/// def function():
/// _variable = 3
/// return _variable + 1
/// # important: avoid shadowing the builtin `id()` function!
/// _id = 4
/// return _variable + _id
/// ```
///
/// Use instead:
/// ```python
/// def function():
/// variable = 3
/// return variable + 1
/// # important: avoid shadowing the builtin `id()` function!
/// id_ = 4
/// return variable + id_
/// ```
///
/// ## Fix availability
@ -47,6 +52,16 @@ use crate::{checkers::ast::Checker, renamer::Renamer};
/// would not shadow any other known variables already accessible from the scope
/// in which the variable is defined.
///
/// ## Fix safety
/// This rule's fix is marked as unsafe.
///
/// For this rule's fix, Ruff renames the variable and fixes up all known references to
/// it so they point to the renamed variable. However, some renamings also require other
/// changes such as different arguments to constructor calls or alterations to comments.
/// Ruff is aware of some of these cases: `_T = TypeVar("_T")` will be fixed to
/// `T = TypeVar("T")` if the `_T` binding is flagged by this rule. However, in general,
/// cases like these are hard to detect and hard to automatically fix.
///
/// ## Options
/// - [`lint.dummy-variable-rgx`]
///
@ -146,7 +161,7 @@ pub(crate) fn used_dummy_variable(checker: &Checker, binding: &Binding) -> Optio
if let Some(fix) = get_possible_fix(name, shadowed_kind, binding.scope, checker) {
diagnostic.try_set_fix(|| {
Renamer::rename(name, &fix, scope, semantic, checker.stylist())
.map(|(edit, rest)| Fix::safe_edits(edit, rest))
.map(|(edit, rest)| Fix::unsafe_edits(edit, rest))
});
}
}

View file

@ -11,7 +11,7 @@ RUF052.py:77:9: RUF052 [*] Local dummy variable `_var` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
74 74 |
75 75 | class Class_:
76 76 | def fun(self):
@ -32,7 +32,7 @@ RUF052.py:84:5: RUF052 [*] Local dummy variable `_list` is accessed
|
= help: Prefer using trailing underscores to avoid shadowing a built-in
Safe fix
Unsafe fix
81 81 | return _var
82 82 |
83 83 | def fun():
@ -54,7 +54,7 @@ RUF052.py:91:5: RUF052 [*] Local dummy variable `_x` is accessed
|
= help: Prefer using trailing underscores to avoid shadowing a variable
Safe fix
Unsafe fix
88 88 |
89 89 | def fun():
90 90 | global x
@ -77,7 +77,7 @@ RUF052.py:98:5: RUF052 [*] Local dummy variable `_x` is accessed
|
= help: Prefer using trailing underscores to avoid shadowing a variable
Safe fix
Unsafe fix
95 95 | x = "outer"
96 96 | def bar():
97 97 | nonlocal x
@ -99,7 +99,7 @@ RUF052.py:105:5: RUF052 [*] Local dummy variable `_x` is accessed
|
= help: Prefer using trailing underscores to avoid shadowing a variable
Safe fix
Unsafe fix
102 102 |
103 103 | def fun():
104 104 | x = "local"
@ -160,7 +160,7 @@ RUF052.py:138:5: RUF052 [*] Local dummy variable `_P` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
135 135 | from enum import Enum
136 136 | from collections import namedtuple
137 137 |
@ -186,7 +186,7 @@ RUF052.py:139:5: RUF052 [*] Local dummy variable `_T` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
136 136 | from collections import namedtuple
137 137 |
138 138 | _P = ParamSpec("_P")
@ -213,7 +213,7 @@ RUF052.py:140:5: RUF052 [*] Local dummy variable `_NT` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
137 137 |
138 138 | _P = ParamSpec("_P")
139 139 | _T = TypeVar(name="_T", covariant=True, bound=int|str)
@ -239,7 +239,7 @@ RUF052.py:141:5: RUF052 [*] Local dummy variable `_E` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
138 138 | _P = ParamSpec("_P")
139 139 | _T = TypeVar(name="_T", covariant=True, bound=int|str)
140 140 | _NT = NamedTuple("_NT", [("foo", int)])
@ -264,7 +264,7 @@ RUF052.py:142:5: RUF052 [*] Local dummy variable `_NT2` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
139 139 | _T = TypeVar(name="_T", covariant=True, bound=int|str)
140 140 | _NT = NamedTuple("_NT", [("foo", int)])
141 141 | _E = Enum("_E", ["a", "b", "c"])
@ -288,7 +288,7 @@ RUF052.py:143:5: RUF052 [*] Local dummy variable `_NT3` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
140 140 | _NT = NamedTuple("_NT", [("foo", int)])
141 141 | _E = Enum("_E", ["a", "b", "c"])
142 142 | _NT2 = namedtuple("_NT2", ['x', 'y', 'z'])
@ -310,7 +310,7 @@ RUF052.py:144:5: RUF052 [*] Local dummy variable `_DynamicClass` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
141 141 | _E = Enum("_E", ["a", "b", "c"])
142 142 | _NT2 = namedtuple("_NT2", ['x', 'y', 'z'])
143 143 | _NT3 = namedtuple(typename="_NT3", field_names=['x', 'y', 'z'])
@ -332,7 +332,7 @@ RUF052.py:145:5: RUF052 [*] Local dummy variable `_NotADynamicClass` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
142 142 | _NT2 = namedtuple("_NT2", ['x', 'y', 'z'])
143 143 | _NT3 = namedtuple(typename="_NT3", field_names=['x', 'y', 'z'])
144 144 | _DynamicClass = type("_DynamicClass", (), {})

View file

@ -11,7 +11,7 @@ RUF052.py:77:9: RUF052 [*] Local dummy variable `_var` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
74 74 |
75 75 | class Class_:
76 76 | def fun(self):
@ -32,7 +32,7 @@ RUF052.py:84:5: RUF052 [*] Local dummy variable `_list` is accessed
|
= help: Prefer using trailing underscores to avoid shadowing a built-in
Safe fix
Unsafe fix
81 81 | return _var
82 82 |
83 83 | def fun():
@ -54,7 +54,7 @@ RUF052.py:91:5: RUF052 [*] Local dummy variable `_x` is accessed
|
= help: Prefer using trailing underscores to avoid shadowing a variable
Safe fix
Unsafe fix
88 88 |
89 89 | def fun():
90 90 | global x
@ -77,7 +77,7 @@ RUF052.py:98:5: RUF052 [*] Local dummy variable `_x` is accessed
|
= help: Prefer using trailing underscores to avoid shadowing a variable
Safe fix
Unsafe fix
95 95 | x = "outer"
96 96 | def bar():
97 97 | nonlocal x
@ -99,7 +99,7 @@ RUF052.py:105:5: RUF052 [*] Local dummy variable `_x` is accessed
|
= help: Prefer using trailing underscores to avoid shadowing a variable
Safe fix
Unsafe fix
102 102 |
103 103 | def fun():
104 104 | x = "local"
@ -160,7 +160,7 @@ RUF052.py:138:5: RUF052 [*] Local dummy variable `_P` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
135 135 | from enum import Enum
136 136 | from collections import namedtuple
137 137 |
@ -186,7 +186,7 @@ RUF052.py:139:5: RUF052 [*] Local dummy variable `_T` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
136 136 | from collections import namedtuple
137 137 |
138 138 | _P = ParamSpec("_P")
@ -213,7 +213,7 @@ RUF052.py:140:5: RUF052 [*] Local dummy variable `_NT` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
137 137 |
138 138 | _P = ParamSpec("_P")
139 139 | _T = TypeVar(name="_T", covariant=True, bound=int|str)
@ -239,7 +239,7 @@ RUF052.py:141:5: RUF052 [*] Local dummy variable `_E` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
138 138 | _P = ParamSpec("_P")
139 139 | _T = TypeVar(name="_T", covariant=True, bound=int|str)
140 140 | _NT = NamedTuple("_NT", [("foo", int)])
@ -264,7 +264,7 @@ RUF052.py:142:5: RUF052 [*] Local dummy variable `_NT2` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
139 139 | _T = TypeVar(name="_T", covariant=True, bound=int|str)
140 140 | _NT = NamedTuple("_NT", [("foo", int)])
141 141 | _E = Enum("_E", ["a", "b", "c"])
@ -288,7 +288,7 @@ RUF052.py:143:5: RUF052 [*] Local dummy variable `_NT3` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
140 140 | _NT = NamedTuple("_NT", [("foo", int)])
141 141 | _E = Enum("_E", ["a", "b", "c"])
142 142 | _NT2 = namedtuple("_NT2", ['x', 'y', 'z'])
@ -310,7 +310,7 @@ RUF052.py:144:5: RUF052 [*] Local dummy variable `_DynamicClass` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
141 141 | _E = Enum("_E", ["a", "b", "c"])
142 142 | _NT2 = namedtuple("_NT2", ['x', 'y', 'z'])
143 143 | _NT3 = namedtuple(typename="_NT3", field_names=['x', 'y', 'z'])
@ -332,7 +332,7 @@ RUF052.py:145:5: RUF052 [*] Local dummy variable `_NotADynamicClass` is accessed
|
= help: Remove leading underscores
Safe fix
Unsafe fix
142 142 | _NT2 = namedtuple("_NT2", ['x', 'y', 'z'])
143 143 | _NT3 = namedtuple(typename="_NT3", field_names=['x', 'y', 'z'])
144 144 | _DynamicClass = type("_DynamicClass", (), {})