-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
[ruff] implement useless if-else (RUF034) #13218
[ruff] implement useless if-else (RUF034) #13218
Conversation
|
code | total | + violation | - violation | + fix | - fix |
---|---|---|---|---|---|
RUF034 | 2 | 2 | 0 | 0 | 0 |
Hi Lucas, I am new to Ruff an am just reading PRs to get a better understanding of how everything works. I was wondering, how did you decide to name it |
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 overall looks great to me but we should change the rule code and its name.
I have some concerns with the scope of the rule. I know it has previously been accepted but I only just now looked closer into it.
- There's some overlap with
SIM108
that simplifies if expressions - The scope of the rule is very narrow. Should it also apply to if-statements?
@AlexWaygood what are your thoughts on the rule?
It would be great if the rule also provided a fix that removes the if expression with the true or false body.
crates/ruff_linter/src/codes.rs
Outdated
@@ -963,6 +963,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { | |||
(Ruff, "033") => (RuleGroup::Preview, rules::ruff::rules::PostInitDefault), | |||
(Ruff, "100") => (RuleGroup::Stable, rules::ruff::rules::UnusedNOQA), | |||
(Ruff, "101") => (RuleGroup::Stable, rules::ruff::rules::RedirectedNOQA), | |||
(Ruff, "102") => (RuleGroup::Preview, rules::ruff::rules::RedundantTernary), |
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.
The 1XX
ruff rules are reserved for noqa specific rules. Let's change the code to 034.
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.
@RubenVanEldik I think this answers it 😄. This is also my first time contributing here.
@@ -1404,6 +1404,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { | |||
if checker.enabled(Rule::IfExpInsteadOfOrOperator) { | |||
refurb::rules::if_exp_instead_of_or_operator(checker, if_exp); | |||
} | |||
if checker.enabled(Rule::RedundantTernary) { |
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 quickly checked other "ternary" specific rules and all of them use the term if-expr
instead. We also use the term Useless
when referring to useless code.
How about: useless-if-expr
?
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.
useless-if-expr
sounds good to me. I agree that that's more approachable language than ternary
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.
Sounds good, but if we also cover if blocks maybe we will need a different name. For example: useless-if-logic
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.
hmm, good point. Maybe useless-if-else
? Or useless-if-condition
?
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 likeuseless-if-else
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 like useless-if-else
. It provides room for expanding the rule in the future.
The ecosystem check shows an interesting false positive: |
@MichaReiser is that a false positive? The snippet in question is: sorted_args = tuple(
x if hasattr(x, "__repr__") else x for x in [*args, *sorted(kwargs.items())]
) It seems like each element in the iterable there will be collected whether or not it has a sorted_args = tuple(x for x in [*args, *sorted(kwargs.items())]) or even just sorted_args = (*args, *sorted(kwargs.items())) What they probably wanted to do was sorted_args = tuple(
repr(x) if hasattr(x, "__repr__") else x for x in [*args, *sorted(kwargs.items())]
) But even that doesn't make much sense, because all objects in Python have a >>> hasattr(object, "__repr__")
True |
I support this being a separate rule to
Also applying it to if/else statements sounds reasonable to me. |
I don't think a fix would fit this rule because users probably end up in this situation when they mistype one of the ternary ends. Instead of just removing the ternary, they probably need to correct one of the sides. |
I wonder if rule SIM114 address that |
|
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.
LGTM. I think we could merge this now and expand it to if
/else
statements as a followup. @MichaReiser what do you think?
Summary
Adds a new rule, RUF102, to check for redundant ternary operators. Message shows when both the true and false branches return the same value, as discussed in #12516
Test Plan
cargo test