Skip to content

Commit e37bde4

Browse files
[ruff] implement useless if-else (RUF034) (#13218)
1 parent 862bd0c commit e37bde4

File tree

8 files changed

+101
-0
lines changed

8 files changed

+101
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Valid
2+
x = 1 if True else 2
3+
4+
# Invalid
5+
x = 1 if True else 1
6+
7+
# Invalid
8+
x = "a" if True else "a"
9+
10+
# Invalid
11+
x = 0.1 if False else 0.1

crates/ruff_linter/src/checkers/ast/analyze/expression.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1404,6 +1404,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
14041404
if checker.enabled(Rule::IfExpInsteadOfOrOperator) {
14051405
refurb::rules::if_exp_instead_of_or_operator(checker, if_exp);
14061406
}
1407+
if checker.enabled(Rule::UselessIfElse) {
1408+
ruff::rules::useless_if_else(checker, if_exp);
1409+
}
14071410
}
14081411
Expr::ListComp(
14091412
comp @ ast::ExprListComp {

crates/ruff_linter/src/codes.rs

+1
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
961961
(Ruff, "031") => (RuleGroup::Preview, rules::ruff::rules::IncorrectlyParenthesizedTupleInSubscript),
962962
(Ruff, "032") => (RuleGroup::Preview, rules::ruff::rules::DecimalFromFloatLiteral),
963963
(Ruff, "033") => (RuleGroup::Preview, rules::ruff::rules::PostInitDefault),
964+
(Ruff, "034") => (RuleGroup::Preview, rules::ruff::rules::UselessIfElse),
964965
(Ruff, "100") => (RuleGroup::Stable, rules::ruff::rules::UnusedNOQA),
965966
(Ruff, "101") => (RuleGroup::Stable, rules::ruff::rules::RedirectedNOQA),
966967

crates/ruff_linter/src/rules/ruff/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ mod tests {
5858
#[test_case(Rule::AssertWithPrintMessage, Path::new("RUF030.py"))]
5959
#[test_case(Rule::IncorrectlyParenthesizedTupleInSubscript, Path::new("RUF031.py"))]
6060
#[test_case(Rule::DecimalFromFloatLiteral, Path::new("RUF032.py"))]
61+
#[test_case(Rule::UselessIfElse, Path::new("RUF034.py"))]
6162
#[test_case(Rule::RedirectedNOQA, Path::new("RUF101.py"))]
6263
#[test_case(Rule::PostInitDefault, Path::new("RUF033.py"))]
6364
fn rules(rule_code: Rule, path: &Path) -> Result<()> {

crates/ruff_linter/src/rules/ruff/rules/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub(crate) use unnecessary_iterable_allocation_for_first_element::*;
2929
pub(crate) use unnecessary_key_check::*;
3030
pub(crate) use unused_async::*;
3131
pub(crate) use unused_noqa::*;
32+
pub(crate) use useless_if_else::*;
3233
pub(crate) use zip_instead_of_pairwise::*;
3334

3435
mod ambiguous_unicode_character;
@@ -66,6 +67,7 @@ mod unnecessary_iterable_allocation_for_first_element;
6667
mod unnecessary_key_check;
6768
mod unused_async;
6869
mod unused_noqa;
70+
mod useless_if_else;
6971
mod zip_instead_of_pairwise;
7072

7173
#[derive(Clone, Copy)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use crate::checkers::ast::Checker;
2+
use ruff_diagnostics::{Diagnostic, Violation};
3+
use ruff_macros::{derive_message_formats, violation};
4+
use ruff_python_ast as ast;
5+
use ruff_python_ast::comparable::ComparableExpr;
6+
7+
/// ## What it does
8+
/// Checks for useless if-else conditions with identical arms.
9+
///
10+
/// ## Why is this bad?
11+
/// Useless if-else conditions add unnecessary complexity to the code without
12+
/// providing any logical benefit.
13+
///
14+
/// Assigning the value directly is clearer and more explicit, and
15+
/// should be preferred.
16+
///
17+
/// ## Example
18+
/// ```python
19+
/// # Bad
20+
/// foo = x if y else x
21+
/// ```
22+
///
23+
/// Use instead:
24+
/// ```python
25+
/// # Good
26+
/// foo = x
27+
/// ```
28+
#[violation]
29+
pub struct UselessIfElse;
30+
31+
impl Violation for UselessIfElse {
32+
#[derive_message_formats]
33+
fn message(&self) -> String {
34+
format!("Useless if-else condition")
35+
}
36+
}
37+
38+
/// RUF031
39+
pub(crate) fn useless_if_else(checker: &mut Checker, if_expr: &ast::ExprIf) {
40+
let ast::ExprIf {
41+
body,
42+
orelse,
43+
range,
44+
..
45+
} = if_expr;
46+
47+
// Skip if the body and orelse are not the same
48+
if ComparableExpr::from(body) != ComparableExpr::from(orelse) {
49+
return;
50+
}
51+
52+
checker
53+
.diagnostics
54+
.push(Diagnostic::new(UselessIfElse, *range));
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
source: crates/ruff_linter/src/rules/ruff/mod.rs
3+
---
4+
RUF034.py:5:5: RUF034 Useless if-else condition
5+
|
6+
4 | # Invalid
7+
5 | x = 1 if True else 1
8+
| ^^^^^^^^^^^^^^^^ RUF034
9+
6 |
10+
7 | # Invalid
11+
|
12+
13+
RUF034.py:8:5: RUF034 Useless if-else condition
14+
|
15+
7 | # Invalid
16+
8 | x = "a" if True else "a"
17+
| ^^^^^^^^^^^^^^^^^^^^ RUF034
18+
9 |
19+
10 | # Invalid
20+
|
21+
22+
RUF034.py:11:5: RUF034 Useless if-else condition
23+
|
24+
10 | # Invalid
25+
11 | x = 0.1 if False else 0.1
26+
| ^^^^^^^^^^^^^^^^^^^^^ RUF034
27+
|

ruff.schema.json

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)