-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[pylint] Implement redefined-argument-from-local (R1704) #8159
Merged
charliermarsh
merged 37 commits into
astral-sh:main
from
danbi2990:redefined-argument-from-local
Nov 10, 2023
Merged
Changes from 30 commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
58c3c2e
adding rule
danbi2990 d58e38d
Merge branch 'main' of https://github.com/astral-sh/ruff into redefin…
danbi2990 969b3fa
Merge branch 'main' of https://github.com/astral-sh/ruff into redefin…
danbi2990 d6054c5
add code
danbi2990 0f75bb7
check with stmt
danbi2990 67dcefd
check for stmt
danbi2990 c660f25
check try stmt
danbi2990 f3d15cb
add python test
danbi2990 c28b437
impl rule
danbi2990 a6dd737
Merge branch 'main' of https://github.com/astral-sh/ruff into redefin…
danbi2990 6dc8afc
add rule
danbi2990 630bfaa
add test
danbi2990 e5dc044
add no error cases
danbi2990 8dd88a3
update schema
danbi2990 9c321e0
add snapshot
danbi2990 d676b9a
fix typo
danbi2990 a85a6c5
apply format
danbi2990 85166ca
check equality by if
danbi2990 0e6f48a
early continue
danbi2990 ab14d52
add WithItemVar
danbi2990 99bff35
add test cases
danbi2990 efb7ce5
remove legacy impl
danbi2990 b6dd3ad
add binding with stmt
danbi2990 a290569
add rule
danbi2990 ebf0aaa
remove WithItemVar
danbi2990 818980b
Revert "add binding with stmt"
danbi2990 6426c0e
Revert "add WithItemVar"
danbi2990 724d882
update snapshot
danbi2990 ab95194
format code
danbi2990 b29547b
Merge branch 'main' of https://github.com/astral-sh/ruff into redefin…
danbi2990 9d9c502
Merge branch 'main' of https://github.com/astral-sh/ruff into redefin…
danbi2990 d5bb19d
edit test cases
danbi2990 0698990
check WithItemVar
danbi2990 c7eca3e
check binding.is_used
danbi2990 8c8b0ac
update snapshot
danbi2990 82a7563
format code
danbi2990 c5faa27
Check even if unused
charliermarsh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
64 changes: 64 additions & 0 deletions
64
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,64 @@ | ||
|
||
# No Errors | ||
|
||
def foo(a): | ||
for b in range(1): | ||
... | ||
|
||
def foo(a): | ||
try: | ||
... | ||
except Exception as e: | ||
... | ||
|
||
def foo(a): | ||
with open('', ) as f: | ||
... | ||
|
||
if True: | ||
def foo(a): | ||
... | ||
else: | ||
for a in range(1): | ||
... | ||
|
||
# Errors | ||
|
||
def foo(i): | ||
for i in range(10): | ||
... | ||
|
||
def foo(e): | ||
try: | ||
... | ||
except Exception as e: | ||
... | ||
|
||
def foo(f): | ||
with open('', ) as f: | ||
... | ||
|
||
def foo(a, b): | ||
with context() as (a, b, c): | ||
... | ||
|
||
def foo(a, b): | ||
with context() as [a, b, c]: | ||
... | ||
|
||
def foo(a): | ||
def bar(b): | ||
for a in range(1): | ||
... | ||
|
||
def foo(a): | ||
def bar(b): | ||
for b in range(1): | ||
... | ||
|
||
def foo(a=1): | ||
def bar(b=2): | ||
for a in range(1): | ||
... | ||
for b in range(1): | ||
... |
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}`") | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
...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,58 @@ | ||
--- | ||
source: crates/ruff_linter/src/rules/pylint/mod.rs | ||
--- | ||
redefined_argument_from_local.py:28:9: PLR1704 Redefining argument with the local name `i` | ||
| | ||
27 | def foo(i): | ||
28 | for i in range(10): | ||
| ^ PLR1704 | ||
29 | ... | ||
| | ||
|
||
redefined_argument_from_local.py:34:25: PLR1704 Redefining argument with the local name `e` | ||
| | ||
32 | try: | ||
33 | ... | ||
34 | except Exception as e: | ||
| ^ PLR1704 | ||
35 | ... | ||
| | ||
|
||
redefined_argument_from_local.py:51:13: PLR1704 Redefining argument with the local name `a` | ||
| | ||
49 | def foo(a): | ||
50 | def bar(b): | ||
51 | for a in range(1): | ||
| ^ PLR1704 | ||
52 | ... | ||
| | ||
|
||
redefined_argument_from_local.py:56:13: PLR1704 Redefining argument with the local name `b` | ||
| | ||
54 | def foo(a): | ||
55 | def bar(b): | ||
56 | for b in range(1): | ||
| ^ PLR1704 | ||
57 | ... | ||
| | ||
|
||
redefined_argument_from_local.py:61:13: PLR1704 Redefining argument with the local name `a` | ||
| | ||
59 | def foo(a=1): | ||
60 | def bar(b=2): | ||
61 | for a in range(1): | ||
| ^ PLR1704 | ||
62 | ... | ||
63 | for b in range(1): | ||
| | ||
|
||
redefined_argument_from_local.py:63:13: PLR1704 Redefining argument with the local name `b` | ||
| | ||
61 | for a in range(1): | ||
62 | ... | ||
63 | for b in range(1): | ||
| ^ PLR1704 | ||
64 | ... | ||
| | ||
|
||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this supposed to check if the argument is unused? Or does it fire in either case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not checking the usage.
It looks sensible to check
binding.is_used()
as belowIn this case, results are following
Is it good to go?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was referring to the inverse -- should this depend on the argument being unused? I'll check Pylint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I erred on the side of removing the
!binding.is_used()
piece here. I think it still makes sense to raise, even if the new binding is unused, since it will cause the same problems?