-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Add new rule InEmptyCollection #16480
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
Conversation
|
code | total | + violation | - violation | + fix | - fix |
---|---|---|---|---|---|
RUF060 | 5 | 5 | 0 | 0 | 0 |
5c4b0a1
to
b122182
Compare
@dylwil3 would you mind taking a look at this? I think you've most context on the change as you've been involved in both linked issues |
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.
Thanks @naslundx , this looks nice! One thing is that my comment in the linked issue was that we should open a separate issue to decide whether this should be a rule, but we never actually did that.
So would you be willing to propose this as a rule in a new issue, and link this PR to it? Then we can see what folks think and do some design/decision-making there.
If we do decide to go ahead with this rule, then we'll also probably have to move it to a RUF
rule, otherwise there will be a clash when pylint
adds an R6202
.
crates/ruff_linter/src/rules/pylint/rules/in_empty_collection.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/pylint/rules/in_empty_collection.rs
Outdated
Show resolved
Hide resolved
@@ -0,0 +1,19 @@ | |||
# Errors |
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.
Can you also detect something like this?
a=[]
b= 7
if b in a:
pass
I think is possible or?
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.
With the current implementation, no. If there are mechanisms implemented to allow for this, please point me in the right direction!
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.
Something like this may be possible when the symbol is defined in the same file, but it would be a bit tricky to do reliably especially when there is complicated control flow. I think we can look into extending the rule to cover this case later, but for now I think we should stick with catching literals.
b122182
to
37779a5
Compare
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.
Thanks for this! Would you mind adding a few more containers and tests for them?
func, | ||
arguments, | ||
range: _, | ||
}) => semantic.match_builtin_expr(func, "set") && arguments.is_empty(), |
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.
We certainly at least want list
, tuple
, and dict
here as well, but maybe we also want:
- a match arm for strings, bytes literals, and f-strings of length zero?
- the remaining builtin functions that create empty containers, which I think are:
bytearray
,bytes
,frozenset
, andstr
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.
Thanks, that makes a lot of sense! The f-string was a bit tricky to figure out but I think I got it right.
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.
Updates are in a new commit
953b74a
to
e4a4e8f
Compare
Lmk if I should change the code @dylwil3 |
Yes thank you for the reminder! Looks like you're lucky number |
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.
Almost there! One nit and then we'll need to move the rule to RUF060
. Thanks for bearing with me!
Expr::FString(s) => match s.as_single_part_fstring() { | ||
Some(FString { elements, .. }) => elements.is_empty(), | ||
_ => false, | ||
}, |
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 think this won't catch implicit concatenation like "a" in f"" ""
, so maybe:
Expr::FString(s) => match s.as_single_part_fstring() { | |
Some(FString { elements, .. }) => elements.is_empty(), | |
_ => false, | |
}, | |
Expr::FString(s) => s | |
.value | |
.elements() | |
.all(|elt| elt.as_literal().is_some_and(|elt| elt.is_empty())), |
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.
Thanks!
e4a4e8f
to
b29590c
Compare
b29590c
to
f66df9d
Compare
Change rule number to RUF060 ✔️ |
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.
This is a great contribution, and I was really impressed with how comfortable you got with the codebase so quickly! Thank you!
## Summary Introducing a new rule based on discussions in astral-sh#15732 and astral-sh#15729 that checks for unnecessary in with empty collections. I called it in_empty_collection and gave the rule number RUF060. Rule is in preview group.
Thanks a lot @dylwil3 ! |
Summary
Introducing a new rule based on discussions in #15732 and #15729 that checks for unnecessary in with empty collections.
I called it in_empty_collection and gave the rule number PLR6202 but of course open for suggestions/clarifications.
Technically fixable (can be replaced by boolean or, if in an if-statement, removed entirely) and can implement that as well if it makes sense.
Rule is in preview group. (Tried following https://docs.astral.sh/ruff/contributing/#example-adding-a-new-lint-rule as best I could)
Test Plan
Tried locally against sample code. Added unit test, and created snapshot.