-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[pylint] Implement redefined-argument-from-local (R1704) (#8159)
## Summary It implements Pylint rule R1704: redefined-argument-from-local Problematic code: ```python def show(host_id=10.11): # +1: [redefined-argument-from-local] for host_id, host in [[12.13, "Venus"], [14.15, "Mars"]]: print(host_id, host) ``` Correct code: ```python def show(host_id=10.11): for inner_host_id, host in [[12.13, "Venus"], [14.15, "Mars"]]: print(host_id, inner_host_id, host) ``` References: [Pylint documentation](https://pylint.readthedocs.io/en/latest/user_guide/messages/refactor/redefined-argument-from-local.html) [Related Issue](#970) ## Test Plan `cargo test`
- Loading branch information
Showing
8 changed files
with
268 additions
and
0 deletions.
There are no files selected for viewing
79 changes: 79 additions & 0 deletions
79
crates/ruff_linter/resources/test/fixtures/pylint/redefined_argument_from_local.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# No Errors | ||
def func(a): | ||
for b in range(1): | ||
... | ||
|
||
|
||
def func(a): | ||
try: | ||
... | ||
except ValueError: | ||
... | ||
except KeyError: | ||
... | ||
|
||
|
||
if True: | ||
def func(a): | ||
... | ||
else: | ||
for a in range(1): | ||
print(a) | ||
|
||
|
||
# Errors | ||
def func(a): | ||
for a in range(1): | ||
... | ||
|
||
|
||
def func(i): | ||
for i in range(10): | ||
print(i) | ||
|
||
|
||
def func(e): | ||
try: | ||
... | ||
except Exception as e: | ||
print(e) | ||
|
||
|
||
def func(f): | ||
with open('', ) as f: | ||
print(f) | ||
|
||
|
||
def func(a, b): | ||
with context() as (a, b, c): | ||
print(a, b, c) | ||
|
||
|
||
def func(a, b): | ||
with context() as [a, b, c]: | ||
print(a, b, c) | ||
|
||
|
||
def func(a): | ||
with open('foo.py', ) as f, open('bar.py') as a: | ||
... | ||
|
||
|
||
def func(a): | ||
def bar(b): | ||
for a in range(1): | ||
print(a) | ||
|
||
|
||
def func(a): | ||
def bar(b): | ||
for b in range(1): | ||
print(b) | ||
|
||
|
||
def func(a=1): | ||
def bar(b=2): | ||
for a in range(1): | ||
print(a) | ||
for b in range(1): | ||
print(b) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
crates/ruff_linter/src/rules/pylint/rules/redefined_argument_from_local.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
use ruff_diagnostics::Violation; | ||
use ruff_macros::{derive_message_formats, violation}; | ||
|
||
/// ## What it does | ||
/// Checks for variables defined in `for`, `try`, `with` statements | ||
/// that redefine function parameters. | ||
/// | ||
/// ## Why is this bad? | ||
/// Redefined variable can cause unexpected behavior because of overridden function parameter. | ||
/// If nested functions are declared, inner function's body can override outer function's parameter. | ||
/// | ||
/// ## Example | ||
/// ```python | ||
/// def show(host_id=10.11): | ||
/// for host_id, host in [[12.13, "Venus"], [14.15, "Mars"]]: | ||
/// print(host_id, host) | ||
/// ``` | ||
/// | ||
/// Use instead: | ||
/// ```python | ||
/// def show(host_id=10.11): | ||
/// for inner_host_id, host in [[12.13, "Venus"], [14.15, "Mars"]]: | ||
/// print(host_id, inner_host_id, host) | ||
/// ``` | ||
/// ## References | ||
/// - [Pylint documentation](https://pylint.readthedocs.io/en/latest/user_guide/messages/refactor/redefined-argument-from-local.html) | ||
#[violation] | ||
pub struct RedefinedArgumentFromLocal { | ||
pub(crate) name: String, | ||
} | ||
|
||
impl Violation for RedefinedArgumentFromLocal { | ||
#[derive_message_formats] | ||
fn message(&self) -> String { | ||
let RedefinedArgumentFromLocal { name } = self; | ||
format!("Redefining argument with the local name `{name}`") | ||
} | ||
} |
115 changes: 115 additions & 0 deletions
115
...napshots/ruff_linter__rules__pylint__tests__PLR1704_redefined_argument_from_local.py.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
--- | ||
source: crates/ruff_linter/src/rules/pylint/mod.rs | ||
--- | ||
redefined_argument_from_local.py:26:9: PLR1704 Redefining argument with the local name `a` | ||
| | ||
24 | # Errors | ||
25 | def func(a): | ||
26 | for a in range(1): | ||
| ^ PLR1704 | ||
27 | ... | ||
| | ||
|
||
redefined_argument_from_local.py:31:9: PLR1704 Redefining argument with the local name `i` | ||
| | ||
30 | def func(i): | ||
31 | for i in range(10): | ||
| ^ PLR1704 | ||
32 | print(i) | ||
| | ||
|
||
redefined_argument_from_local.py:38:25: PLR1704 Redefining argument with the local name `e` | ||
| | ||
36 | try: | ||
37 | ... | ||
38 | except Exception as e: | ||
| ^ PLR1704 | ||
39 | print(e) | ||
| | ||
|
||
redefined_argument_from_local.py:43:24: PLR1704 Redefining argument with the local name `f` | ||
| | ||
42 | def func(f): | ||
43 | with open('', ) as f: | ||
| ^ PLR1704 | ||
44 | print(f) | ||
| | ||
|
||
redefined_argument_from_local.py:48:24: PLR1704 Redefining argument with the local name `a` | ||
| | ||
47 | def func(a, b): | ||
48 | with context() as (a, b, c): | ||
| ^ PLR1704 | ||
49 | print(a, b, c) | ||
| | ||
|
||
redefined_argument_from_local.py:48:27: PLR1704 Redefining argument with the local name `b` | ||
| | ||
47 | def func(a, b): | ||
48 | with context() as (a, b, c): | ||
| ^ PLR1704 | ||
49 | print(a, b, c) | ||
| | ||
|
||
redefined_argument_from_local.py:53:24: PLR1704 Redefining argument with the local name `a` | ||
| | ||
52 | def func(a, b): | ||
53 | with context() as [a, b, c]: | ||
| ^ PLR1704 | ||
54 | print(a, b, c) | ||
| | ||
|
||
redefined_argument_from_local.py:53:27: PLR1704 Redefining argument with the local name `b` | ||
| | ||
52 | def func(a, b): | ||
53 | with context() as [a, b, c]: | ||
| ^ PLR1704 | ||
54 | print(a, b, c) | ||
| | ||
|
||
redefined_argument_from_local.py:58:51: PLR1704 Redefining argument with the local name `a` | ||
| | ||
57 | def func(a): | ||
58 | with open('foo.py', ) as f, open('bar.py') as a: | ||
| ^ PLR1704 | ||
59 | ... | ||
| | ||
|
||
redefined_argument_from_local.py:64:13: PLR1704 Redefining argument with the local name `a` | ||
| | ||
62 | def func(a): | ||
63 | def bar(b): | ||
64 | for a in range(1): | ||
| ^ PLR1704 | ||
65 | print(a) | ||
| | ||
|
||
redefined_argument_from_local.py:70:13: PLR1704 Redefining argument with the local name `b` | ||
| | ||
68 | def func(a): | ||
69 | def bar(b): | ||
70 | for b in range(1): | ||
| ^ PLR1704 | ||
71 | print(b) | ||
| | ||
|
||
redefined_argument_from_local.py:76:13: PLR1704 Redefining argument with the local name `a` | ||
| | ||
74 | def func(a=1): | ||
75 | def bar(b=2): | ||
76 | for a in range(1): | ||
| ^ PLR1704 | ||
77 | print(a) | ||
78 | for b in range(1): | ||
| | ||
|
||
redefined_argument_from_local.py:78:13: PLR1704 Redefining argument with the local name `b` | ||
| | ||
76 | for a in range(1): | ||
77 | print(a) | ||
78 | for b in range(1): | ||
| ^ PLR1704 | ||
79 | print(b) | ||
| | ||
|
||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.