mirror of https://github.com/astral-sh/ruff
[`flake8-simplify`] Further simplify to binary in preview for `if-else-block-instead-of-if-exp (SIM108)` (#12796)
In most cases we should suggest a ternary operator, but there are three
edge cases where a binary operator is more appropriate.
Given an if-else block of the form
```python
if test:
target_var = body_value
else:
target_var = else_value
```
This PR updates the check for SIM108 to the following:
- If `test == body_value` and preview enabled, suggest to replace with
`target_var = test or else_value`
- If `test == not body_value` and preview enabled, suggest to replace
with `target_var = body_value and else_value`
- If `not test == body_value` and preview enabled, suggest to replace
with `target_var = body_value and else_value`
- Otherwise, suggest to replace with `target_var = body_value if test
else else_value`
Closes #12189.
This commit is contained in:
parent
cf1a57df5a
commit
0c2b88f224
|
|
@ -135,3 +135,62 @@ if TYPE_CHECKING:
|
|||
x = 3
|
||||
else:
|
||||
x = 5
|
||||
|
||||
# SIM108 - should suggest
|
||||
# z = cond or other_cond
|
||||
if cond:
|
||||
z = cond
|
||||
else:
|
||||
z = other_cond
|
||||
|
||||
# SIM108 - should suggest
|
||||
# z = cond and other_cond
|
||||
if not cond:
|
||||
z = cond
|
||||
else:
|
||||
z = other_cond
|
||||
|
||||
# SIM108 - should suggest
|
||||
# z = not cond and other_cond
|
||||
if cond:
|
||||
z = not cond
|
||||
else:
|
||||
z = other_cond
|
||||
|
||||
# SIM108 does not suggest
|
||||
# a binary option in these cases,
|
||||
# despite the fact that `bool`
|
||||
# is a subclass of both `int` and `float`
|
||||
# so, e.g. `True == 1`.
|
||||
# (Of course, these specific expressions
|
||||
# should be simplified for other reasons...)
|
||||
if True:
|
||||
z = 1
|
||||
else:
|
||||
z = other
|
||||
|
||||
if False:
|
||||
z = 1
|
||||
else:
|
||||
z = other
|
||||
|
||||
if 1:
|
||||
z = True
|
||||
else:
|
||||
z = other
|
||||
|
||||
# SIM108 does not suggest a binary option in this
|
||||
# case, since we'd be reducing the number of calls
|
||||
# from Two to one.
|
||||
if foo():
|
||||
z = foo()
|
||||
else:
|
||||
z = other
|
||||
|
||||
# SIM108 does not suggest a binary option in this
|
||||
# case, since we'd be reducing the number of calls
|
||||
# from Two to one.
|
||||
if foo():
|
||||
z = not foo()
|
||||
else:
|
||||
z = other
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ mod tests {
|
|||
use test_case::test_case;
|
||||
|
||||
use crate::registry::Rule;
|
||||
use crate::settings::types::PreviewMode;
|
||||
use crate::settings::LinterSettings;
|
||||
use crate::test::test_path;
|
||||
use crate::{assert_messages, settings};
|
||||
|
||||
|
|
@ -54,4 +56,22 @@ mod tests {
|
|||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::IfElseBlockInsteadOfIfExp, Path::new("SIM108.py"))]
|
||||
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"preview__{}_{}",
|
||||
rule_code.noqa_code(),
|
||||
path.to_string_lossy()
|
||||
);
|
||||
let diagnostics = test_path(
|
||||
Path::new("flake8_simplify").join(path).as_path(),
|
||||
&LinterSettings {
|
||||
preview: PreviewMode::Enabled,
|
||||
..LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
)?;
|
||||
assert_messages!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::{self as ast, ElifElseClause, Expr, Stmt};
|
||||
use ruff_python_ast::comparable::ComparableExpr;
|
||||
use ruff_python_ast::helpers::contains_effect;
|
||||
use ruff_python_ast::{self as ast, BoolOp, ElifElseClause, Expr, Stmt};
|
||||
use ruff_python_semantic::analyze::typing::{is_sys_version_block, is_type_checking_block};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
|
|
@ -9,12 +11,15 @@ use crate::fix::edits::fits;
|
|||
|
||||
/// ## What it does
|
||||
/// Check for `if`-`else`-blocks that can be replaced with a ternary operator.
|
||||
/// Moreover, in [preview], check if these ternary expressions can be
|
||||
/// further simplified to binary expressions.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// `if`-`else`-blocks that assign a value to a variable in both branches can
|
||||
/// be expressed more concisely by using a ternary operator.
|
||||
/// be expressed more concisely by using a ternary or binary operator.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```python
|
||||
/// if foo:
|
||||
/// bar = x
|
||||
|
|
@ -27,11 +32,31 @@ use crate::fix::edits::fits;
|
|||
/// bar = x if foo else y
|
||||
/// ```
|
||||
///
|
||||
/// Or, in [preview]:
|
||||
///
|
||||
/// ```python
|
||||
/// if cond:
|
||||
/// z = cond
|
||||
/// else:
|
||||
/// z = other_cond
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
///
|
||||
/// ```python
|
||||
/// z = cond or other_cond
|
||||
/// ```
|
||||
///
|
||||
/// ## References
|
||||
/// - [Python documentation: Conditional expressions](https://docs.python.org/3/reference/expressions.html#conditional-expressions)
|
||||
///
|
||||
/// [preview]: https://docs.astral.sh/ruff/preview/
|
||||
#[violation]
|
||||
pub struct IfElseBlockInsteadOfIfExp {
|
||||
/// The ternary or binary expression to replace the `if`-`else`-block.
|
||||
contents: String,
|
||||
/// Whether to use a binary or ternary assignment.
|
||||
kind: AssignmentKind,
|
||||
}
|
||||
|
||||
impl Violation for IfElseBlockInsteadOfIfExp {
|
||||
|
|
@ -39,12 +64,19 @@ impl Violation for IfElseBlockInsteadOfIfExp {
|
|||
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let IfElseBlockInsteadOfIfExp { contents } = self;
|
||||
format!("Use ternary operator `{contents}` instead of `if`-`else`-block")
|
||||
let IfElseBlockInsteadOfIfExp { contents, kind } = self;
|
||||
match kind {
|
||||
AssignmentKind::Ternary => {
|
||||
format!("Use ternary operator `{contents}` instead of `if`-`else`-block")
|
||||
}
|
||||
AssignmentKind::Binary => {
|
||||
format!("Use binary operator `{contents}` instead of `if`-`else`-block")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fix_title(&self) -> Option<String> {
|
||||
let IfElseBlockInsteadOfIfExp { contents } = self;
|
||||
let IfElseBlockInsteadOfIfExp { contents, .. } = self;
|
||||
Some(format!("Replace `if`-`else`-block with `{contents}`"))
|
||||
}
|
||||
}
|
||||
|
|
@ -121,9 +153,59 @@ pub(crate) fn if_else_block_instead_of_if_exp(checker: &mut Checker, stmt_if: &a
|
|||
return;
|
||||
}
|
||||
|
||||
let target_var = &body_target;
|
||||
let ternary = ternary(target_var, body_value, test, else_value);
|
||||
let contents = checker.generator().stmt(&ternary);
|
||||
// In most cases we should now suggest a ternary operator,
|
||||
// but there are three edge cases where a binary operator
|
||||
// is more appropriate.
|
||||
//
|
||||
// For the reader's convenience, here is how
|
||||
// the notation translates to the if-else block:
|
||||
//
|
||||
// ```python
|
||||
// if test:
|
||||
// target_var = body_value
|
||||
// else:
|
||||
// target_var = else_value
|
||||
// ```
|
||||
//
|
||||
// The match statement below implements the following
|
||||
// logic:
|
||||
// - If `test == body_value` and preview enabled, replace with `target_var = test or else_value`
|
||||
// - If `test == not body_value` and preview enabled, replace with `target_var = body_value and else_value`
|
||||
// - If `not test == body_value` and preview enabled, replace with `target_var = body_value and else_value`
|
||||
// - Otherwise, replace with `target_var = body_value if test else else_value`
|
||||
let (contents, assignment_kind) =
|
||||
match (checker.settings.preview.is_enabled(), test, body_value) {
|
||||
(true, test_node, body_node)
|
||||
if ComparableExpr::from(test_node) == ComparableExpr::from(body_node)
|
||||
&& !contains_effect(test_node, |id| {
|
||||
checker.semantic().has_builtin_binding(id)
|
||||
}) =>
|
||||
{
|
||||
let target_var = &body_target;
|
||||
let binary = assignment_binary_or(target_var, body_value, else_value);
|
||||
(checker.generator().stmt(&binary), AssignmentKind::Binary)
|
||||
}
|
||||
(true, test_node, body_node)
|
||||
if (test_node.as_unary_op_expr().is_some_and(|op_expr| {
|
||||
op_expr.op.is_not()
|
||||
&& ComparableExpr::from(&op_expr.operand) == ComparableExpr::from(body_node)
|
||||
}) || body_node.as_unary_op_expr().is_some_and(|op_expr| {
|
||||
op_expr.op.is_not()
|
||||
&& ComparableExpr::from(&op_expr.operand) == ComparableExpr::from(test_node)
|
||||
})) && !contains_effect(test_node, |id| {
|
||||
checker.semantic().has_builtin_binding(id)
|
||||
}) =>
|
||||
{
|
||||
let target_var = &body_target;
|
||||
let binary = assignment_binary_and(target_var, body_value, else_value);
|
||||
(checker.generator().stmt(&binary), AssignmentKind::Binary)
|
||||
}
|
||||
_ => {
|
||||
let target_var = &body_target;
|
||||
let ternary = assignment_ternary(target_var, body_value, test, else_value);
|
||||
(checker.generator().stmt(&ternary), AssignmentKind::Ternary)
|
||||
}
|
||||
};
|
||||
|
||||
// Don't flag if the resulting expression would exceed the maximum line length.
|
||||
if !fits(
|
||||
|
|
@ -139,6 +221,7 @@ pub(crate) fn if_else_block_instead_of_if_exp(checker: &mut Checker, stmt_if: &a
|
|||
let mut diagnostic = Diagnostic::new(
|
||||
IfElseBlockInsteadOfIfExp {
|
||||
contents: contents.clone(),
|
||||
kind: assignment_kind,
|
||||
},
|
||||
stmt_if.range(),
|
||||
);
|
||||
|
|
@ -154,7 +237,18 @@ pub(crate) fn if_else_block_instead_of_if_exp(checker: &mut Checker, stmt_if: &a
|
|||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
|
||||
fn ternary(target_var: &Expr, body_value: &Expr, test: &Expr, orelse_value: &Expr) -> Stmt {
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum AssignmentKind {
|
||||
Binary,
|
||||
Ternary,
|
||||
}
|
||||
|
||||
fn assignment_ternary(
|
||||
target_var: &Expr,
|
||||
body_value: &Expr,
|
||||
test: &Expr,
|
||||
orelse_value: &Expr,
|
||||
) -> Stmt {
|
||||
let node = ast::ExprIf {
|
||||
test: Box::new(test.clone()),
|
||||
body: Box::new(body_value.clone()),
|
||||
|
|
@ -168,3 +262,33 @@ fn ternary(target_var: &Expr, body_value: &Expr, test: &Expr, orelse_value: &Exp
|
|||
};
|
||||
node1.into()
|
||||
}
|
||||
|
||||
fn assignment_binary_and(target_var: &Expr, left_value: &Expr, right_value: &Expr) -> Stmt {
|
||||
let node = ast::ExprBoolOp {
|
||||
op: BoolOp::And,
|
||||
values: vec![left_value.clone(), right_value.clone()],
|
||||
range: TextRange::default(),
|
||||
};
|
||||
let node1 = ast::StmtAssign {
|
||||
targets: vec![target_var.clone()],
|
||||
value: Box::new(node.into()),
|
||||
range: TextRange::default(),
|
||||
};
|
||||
node1.into()
|
||||
}
|
||||
|
||||
fn assignment_binary_or(target_var: &Expr, left_value: &Expr, right_value: &Expr) -> Stmt {
|
||||
(ast::StmtAssign {
|
||||
range: TextRange::default(),
|
||||
targets: vec![target_var.clone()],
|
||||
value: Box::new(
|
||||
(ast::ExprBoolOp {
|
||||
range: TextRange::default(),
|
||||
op: BoolOp::Or,
|
||||
values: vec![left_value.clone(), right_value.clone()],
|
||||
})
|
||||
.into(),
|
||||
),
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,4 +119,186 @@ SIM108.py:117:1: SIM108 Use ternary operator `x = 3 if True else 5` instead of `
|
|||
|
|
||||
= help: Replace `if`-`else`-block with `x = 3 if True else 5`
|
||||
|
||||
SIM108.py:141:1: SIM108 [*] Use ternary operator `z = cond if cond else other_cond` instead of `if`-`else`-block
|
||||
|
|
||||
139 | # SIM108 - should suggest
|
||||
140 | # z = cond or other_cond
|
||||
141 | / if cond:
|
||||
142 | | z = cond
|
||||
143 | | else:
|
||||
144 | | z = other_cond
|
||||
| |__________________^ SIM108
|
||||
145 |
|
||||
146 | # SIM108 - should suggest
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `z = cond if cond else other_cond`
|
||||
|
||||
ℹ Unsafe fix
|
||||
138 138 |
|
||||
139 139 | # SIM108 - should suggest
|
||||
140 140 | # z = cond or other_cond
|
||||
141 |-if cond:
|
||||
142 |- z = cond
|
||||
143 |-else:
|
||||
144 |- z = other_cond
|
||||
141 |+z = cond if cond else other_cond
|
||||
145 142 |
|
||||
146 143 | # SIM108 - should suggest
|
||||
147 144 | # z = cond and other_cond
|
||||
|
||||
SIM108.py:148:1: SIM108 [*] Use ternary operator `z = cond if not cond else other_cond` instead of `if`-`else`-block
|
||||
|
|
||||
146 | # SIM108 - should suggest
|
||||
147 | # z = cond and other_cond
|
||||
148 | / if not cond:
|
||||
149 | | z = cond
|
||||
150 | | else:
|
||||
151 | | z = other_cond
|
||||
| |__________________^ SIM108
|
||||
152 |
|
||||
153 | # SIM108 - should suggest
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `z = cond if not cond else other_cond`
|
||||
|
||||
ℹ Unsafe fix
|
||||
145 145 |
|
||||
146 146 | # SIM108 - should suggest
|
||||
147 147 | # z = cond and other_cond
|
||||
148 |-if not cond:
|
||||
149 |- z = cond
|
||||
150 |-else:
|
||||
151 |- z = other_cond
|
||||
148 |+z = cond if not cond else other_cond
|
||||
152 149 |
|
||||
153 150 | # SIM108 - should suggest
|
||||
154 151 | # z = not cond and other_cond
|
||||
|
||||
SIM108.py:155:1: SIM108 [*] Use ternary operator `z = not cond if cond else other_cond` instead of `if`-`else`-block
|
||||
|
|
||||
153 | # SIM108 - should suggest
|
||||
154 | # z = not cond and other_cond
|
||||
155 | / if cond:
|
||||
156 | | z = not cond
|
||||
157 | | else:
|
||||
158 | | z = other_cond
|
||||
| |__________________^ SIM108
|
||||
159 |
|
||||
160 | # SIM108 does not suggest
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `z = not cond if cond else other_cond`
|
||||
|
||||
ℹ Unsafe fix
|
||||
152 152 |
|
||||
153 153 | # SIM108 - should suggest
|
||||
154 154 | # z = not cond and other_cond
|
||||
155 |-if cond:
|
||||
156 |- z = not cond
|
||||
157 |-else:
|
||||
158 |- z = other_cond
|
||||
155 |+z = not cond if cond else other_cond
|
||||
159 156 |
|
||||
160 157 | # SIM108 does not suggest
|
||||
161 158 | # a binary option in these cases,
|
||||
|
||||
SIM108.py:167:1: SIM108 [*] Use ternary operator `z = 1 if True else other` instead of `if`-`else`-block
|
||||
|
|
||||
165 | # (Of course, these specific expressions
|
||||
166 | # should be simplified for other reasons...)
|
||||
167 | / if True:
|
||||
168 | | z = 1
|
||||
169 | | else:
|
||||
170 | | z = other
|
||||
| |_____________^ SIM108
|
||||
171 |
|
||||
172 | if False:
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `z = 1 if True else other`
|
||||
|
||||
ℹ Unsafe fix
|
||||
164 164 | # so, e.g. `True == 1`.
|
||||
165 165 | # (Of course, these specific expressions
|
||||
166 166 | # should be simplified for other reasons...)
|
||||
167 |-if True:
|
||||
168 |- z = 1
|
||||
169 |-else:
|
||||
170 |- z = other
|
||||
167 |+z = 1 if True else other
|
||||
171 168 |
|
||||
172 169 | if False:
|
||||
173 170 | z = 1
|
||||
|
||||
SIM108.py:177:1: SIM108 [*] Use ternary operator `z = True if 1 else other` instead of `if`-`else`-block
|
||||
|
|
||||
175 | z = other
|
||||
176 |
|
||||
177 | / if 1:
|
||||
178 | | z = True
|
||||
179 | | else:
|
||||
180 | | z = other
|
||||
| |_____________^ SIM108
|
||||
181 |
|
||||
182 | # SIM108 does not suggest a binary option in this
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `z = True if 1 else other`
|
||||
|
||||
ℹ Unsafe fix
|
||||
174 174 | else:
|
||||
175 175 | z = other
|
||||
176 176 |
|
||||
177 |-if 1:
|
||||
178 |- z = True
|
||||
179 |-else:
|
||||
180 |- z = other
|
||||
177 |+z = True if 1 else other
|
||||
181 178 |
|
||||
182 179 | # SIM108 does not suggest a binary option in this
|
||||
183 180 | # case, since we'd be reducing the number of calls
|
||||
|
||||
SIM108.py:185:1: SIM108 [*] Use ternary operator `z = foo() if foo() else other` instead of `if`-`else`-block
|
||||
|
|
||||
183 | # case, since we'd be reducing the number of calls
|
||||
184 | # from Two to one.
|
||||
185 | / if foo():
|
||||
186 | | z = foo()
|
||||
187 | | else:
|
||||
188 | | z = other
|
||||
| |_____________^ SIM108
|
||||
189 |
|
||||
190 | # SIM108 does not suggest a binary option in this
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `z = foo() if foo() else other`
|
||||
|
||||
ℹ Unsafe fix
|
||||
182 182 | # SIM108 does not suggest a binary option in this
|
||||
183 183 | # case, since we'd be reducing the number of calls
|
||||
184 184 | # from Two to one.
|
||||
185 |-if foo():
|
||||
186 |- z = foo()
|
||||
187 |-else:
|
||||
188 |- z = other
|
||||
185 |+z = foo() if foo() else other
|
||||
189 186 |
|
||||
190 187 | # SIM108 does not suggest a binary option in this
|
||||
191 188 | # case, since we'd be reducing the number of calls
|
||||
|
||||
SIM108.py:193:1: SIM108 [*] Use ternary operator `z = not foo() if foo() else other` instead of `if`-`else`-block
|
||||
|
|
||||
191 | # case, since we'd be reducing the number of calls
|
||||
192 | # from Two to one.
|
||||
193 | / if foo():
|
||||
194 | | z = not foo()
|
||||
195 | | else:
|
||||
196 | | z = other
|
||||
| |_____________^ SIM108
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `z = not foo() if foo() else other`
|
||||
|
||||
ℹ Unsafe fix
|
||||
190 190 | # SIM108 does not suggest a binary option in this
|
||||
191 191 | # case, since we'd be reducing the number of calls
|
||||
192 192 | # from Two to one.
|
||||
193 |-if foo():
|
||||
194 |- z = not foo()
|
||||
195 |-else:
|
||||
196 |- z = other
|
||||
193 |+z = not foo() if foo() else other
|
||||
|
|
|
|||
|
|
@ -0,0 +1,304 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_simplify/mod.rs
|
||||
---
|
||||
SIM108.py:2:1: SIM108 [*] Use ternary operator `b = c if a else d` instead of `if`-`else`-block
|
||||
|
|
||||
1 | # SIM108
|
||||
2 | / if a:
|
||||
3 | | b = c
|
||||
4 | | else:
|
||||
5 | | b = d
|
||||
| |_________^ SIM108
|
||||
6 |
|
||||
7 | # OK
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `b = c if a else d`
|
||||
|
||||
ℹ Unsafe fix
|
||||
1 1 | # SIM108
|
||||
2 |-if a:
|
||||
3 |- b = c
|
||||
4 |-else:
|
||||
5 |- b = d
|
||||
2 |+b = c if a else d
|
||||
6 3 |
|
||||
7 4 | # OK
|
||||
8 5 | b = c if a else d
|
||||
|
||||
SIM108.py:30:5: SIM108 [*] Use ternary operator `b = 1 if a else 2` instead of `if`-`else`-block
|
||||
|
|
||||
28 | pass
|
||||
29 | else:
|
||||
30 | if a:
|
||||
| _____^
|
||||
31 | | b = 1
|
||||
32 | | else:
|
||||
33 | | b = 2
|
||||
| |_____________^ SIM108
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `b = 1 if a else 2`
|
||||
|
||||
ℹ Unsafe fix
|
||||
27 27 | if True:
|
||||
28 28 | pass
|
||||
29 29 | else:
|
||||
30 |- if a:
|
||||
31 |- b = 1
|
||||
32 |- else:
|
||||
33 |- b = 2
|
||||
30 |+ b = 1 if a else 2
|
||||
34 31 |
|
||||
35 32 |
|
||||
36 33 | import sys
|
||||
|
||||
SIM108.py:58:1: SIM108 Use ternary operator `abc = x if x > 0 else -x` instead of `if`-`else`-block
|
||||
|
|
||||
57 | # SIM108 (without fix due to comments)
|
||||
58 | / if x > 0:
|
||||
59 | | # test test
|
||||
60 | | abc = x
|
||||
61 | | else:
|
||||
62 | | # test test test
|
||||
63 | | abc = -x
|
||||
| |____________^ SIM108
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `abc = x if x > 0 else -x`
|
||||
|
||||
SIM108.py:82:1: SIM108 [*] Use ternary operator `b = "cccccccccccccccccccccccccccccccccß" if a else "ddddddddddddddddddddddddddddddddd💣"` instead of `if`-`else`-block
|
||||
|
|
||||
81 | # SIM108
|
||||
82 | / if a:
|
||||
83 | | b = "cccccccccccccccccccccccccccccccccß"
|
||||
84 | | else:
|
||||
85 | | b = "ddddddddddddddddddddddddddddddddd💣"
|
||||
| |_____________________________________________^ SIM108
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `b = "cccccccccccccccccccccccccccccccccß" if a else "ddddddddddddddddddddddddddddddddd💣"`
|
||||
|
||||
ℹ Unsafe fix
|
||||
79 79 |
|
||||
80 80 |
|
||||
81 81 | # SIM108
|
||||
82 |-if a:
|
||||
83 |- b = "cccccccccccccccccccccccccccccccccß"
|
||||
84 |-else:
|
||||
85 |- b = "ddddddddddddddddddddddddddddddddd💣"
|
||||
82 |+b = "cccccccccccccccccccccccccccccccccß" if a else "ddddddddddddddddddddddddddddddddd💣"
|
||||
86 83 |
|
||||
87 84 |
|
||||
88 85 | # OK (too long)
|
||||
|
||||
SIM108.py:105:1: SIM108 Use ternary operator `exitcode = 0 if True else 1` instead of `if`-`else`-block
|
||||
|
|
||||
104 | # SIM108 (without fix due to trailing comment)
|
||||
105 | / if True:
|
||||
106 | | exitcode = 0
|
||||
107 | | else:
|
||||
108 | | exitcode = 1 # Trailing comment
|
||||
| |________________^ SIM108
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `exitcode = 0 if True else 1`
|
||||
|
||||
SIM108.py:112:1: SIM108 Use ternary operator `x = 3 if True else 5` instead of `if`-`else`-block
|
||||
|
|
||||
111 | # SIM108
|
||||
112 | / if True: x = 3 # Foo
|
||||
113 | | else: x = 5
|
||||
| |___________^ SIM108
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `x = 3 if True else 5`
|
||||
|
||||
SIM108.py:117:1: SIM108 Use ternary operator `x = 3 if True else 5` instead of `if`-`else`-block
|
||||
|
|
||||
116 | # SIM108
|
||||
117 | / if True: # Foo
|
||||
118 | | x = 3
|
||||
119 | | else:
|
||||
120 | | x = 5
|
||||
| |_________^ SIM108
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `x = 3 if True else 5`
|
||||
|
||||
SIM108.py:141:1: SIM108 [*] Use binary operator `z = cond or other_cond` instead of `if`-`else`-block
|
||||
|
|
||||
139 | # SIM108 - should suggest
|
||||
140 | # z = cond or other_cond
|
||||
141 | / if cond:
|
||||
142 | | z = cond
|
||||
143 | | else:
|
||||
144 | | z = other_cond
|
||||
| |__________________^ SIM108
|
||||
145 |
|
||||
146 | # SIM108 - should suggest
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `z = cond or other_cond`
|
||||
|
||||
ℹ Unsafe fix
|
||||
138 138 |
|
||||
139 139 | # SIM108 - should suggest
|
||||
140 140 | # z = cond or other_cond
|
||||
141 |-if cond:
|
||||
142 |- z = cond
|
||||
143 |-else:
|
||||
144 |- z = other_cond
|
||||
141 |+z = cond or other_cond
|
||||
145 142 |
|
||||
146 143 | # SIM108 - should suggest
|
||||
147 144 | # z = cond and other_cond
|
||||
|
||||
SIM108.py:148:1: SIM108 [*] Use binary operator `z = cond and other_cond` instead of `if`-`else`-block
|
||||
|
|
||||
146 | # SIM108 - should suggest
|
||||
147 | # z = cond and other_cond
|
||||
148 | / if not cond:
|
||||
149 | | z = cond
|
||||
150 | | else:
|
||||
151 | | z = other_cond
|
||||
| |__________________^ SIM108
|
||||
152 |
|
||||
153 | # SIM108 - should suggest
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `z = cond and other_cond`
|
||||
|
||||
ℹ Unsafe fix
|
||||
145 145 |
|
||||
146 146 | # SIM108 - should suggest
|
||||
147 147 | # z = cond and other_cond
|
||||
148 |-if not cond:
|
||||
149 |- z = cond
|
||||
150 |-else:
|
||||
151 |- z = other_cond
|
||||
148 |+z = cond and other_cond
|
||||
152 149 |
|
||||
153 150 | # SIM108 - should suggest
|
||||
154 151 | # z = not cond and other_cond
|
||||
|
||||
SIM108.py:155:1: SIM108 [*] Use binary operator `z = not cond and other_cond` instead of `if`-`else`-block
|
||||
|
|
||||
153 | # SIM108 - should suggest
|
||||
154 | # z = not cond and other_cond
|
||||
155 | / if cond:
|
||||
156 | | z = not cond
|
||||
157 | | else:
|
||||
158 | | z = other_cond
|
||||
| |__________________^ SIM108
|
||||
159 |
|
||||
160 | # SIM108 does not suggest
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `z = not cond and other_cond`
|
||||
|
||||
ℹ Unsafe fix
|
||||
152 152 |
|
||||
153 153 | # SIM108 - should suggest
|
||||
154 154 | # z = not cond and other_cond
|
||||
155 |-if cond:
|
||||
156 |- z = not cond
|
||||
157 |-else:
|
||||
158 |- z = other_cond
|
||||
155 |+z = not cond and other_cond
|
||||
159 156 |
|
||||
160 157 | # SIM108 does not suggest
|
||||
161 158 | # a binary option in these cases,
|
||||
|
||||
SIM108.py:167:1: SIM108 [*] Use ternary operator `z = 1 if True else other` instead of `if`-`else`-block
|
||||
|
|
||||
165 | # (Of course, these specific expressions
|
||||
166 | # should be simplified for other reasons...)
|
||||
167 | / if True:
|
||||
168 | | z = 1
|
||||
169 | | else:
|
||||
170 | | z = other
|
||||
| |_____________^ SIM108
|
||||
171 |
|
||||
172 | if False:
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `z = 1 if True else other`
|
||||
|
||||
ℹ Unsafe fix
|
||||
164 164 | # so, e.g. `True == 1`.
|
||||
165 165 | # (Of course, these specific expressions
|
||||
166 166 | # should be simplified for other reasons...)
|
||||
167 |-if True:
|
||||
168 |- z = 1
|
||||
169 |-else:
|
||||
170 |- z = other
|
||||
167 |+z = 1 if True else other
|
||||
171 168 |
|
||||
172 169 | if False:
|
||||
173 170 | z = 1
|
||||
|
||||
SIM108.py:177:1: SIM108 [*] Use ternary operator `z = True if 1 else other` instead of `if`-`else`-block
|
||||
|
|
||||
175 | z = other
|
||||
176 |
|
||||
177 | / if 1:
|
||||
178 | | z = True
|
||||
179 | | else:
|
||||
180 | | z = other
|
||||
| |_____________^ SIM108
|
||||
181 |
|
||||
182 | # SIM108 does not suggest a binary option in this
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `z = True if 1 else other`
|
||||
|
||||
ℹ Unsafe fix
|
||||
174 174 | else:
|
||||
175 175 | z = other
|
||||
176 176 |
|
||||
177 |-if 1:
|
||||
178 |- z = True
|
||||
179 |-else:
|
||||
180 |- z = other
|
||||
177 |+z = True if 1 else other
|
||||
181 178 |
|
||||
182 179 | # SIM108 does not suggest a binary option in this
|
||||
183 180 | # case, since we'd be reducing the number of calls
|
||||
|
||||
SIM108.py:185:1: SIM108 [*] Use ternary operator `z = foo() if foo() else other` instead of `if`-`else`-block
|
||||
|
|
||||
183 | # case, since we'd be reducing the number of calls
|
||||
184 | # from Two to one.
|
||||
185 | / if foo():
|
||||
186 | | z = foo()
|
||||
187 | | else:
|
||||
188 | | z = other
|
||||
| |_____________^ SIM108
|
||||
189 |
|
||||
190 | # SIM108 does not suggest a binary option in this
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `z = foo() if foo() else other`
|
||||
|
||||
ℹ Unsafe fix
|
||||
182 182 | # SIM108 does not suggest a binary option in this
|
||||
183 183 | # case, since we'd be reducing the number of calls
|
||||
184 184 | # from Two to one.
|
||||
185 |-if foo():
|
||||
186 |- z = foo()
|
||||
187 |-else:
|
||||
188 |- z = other
|
||||
185 |+z = foo() if foo() else other
|
||||
189 186 |
|
||||
190 187 | # SIM108 does not suggest a binary option in this
|
||||
191 188 | # case, since we'd be reducing the number of calls
|
||||
|
||||
SIM108.py:193:1: SIM108 [*] Use ternary operator `z = not foo() if foo() else other` instead of `if`-`else`-block
|
||||
|
|
||||
191 | # case, since we'd be reducing the number of calls
|
||||
192 | # from Two to one.
|
||||
193 | / if foo():
|
||||
194 | | z = not foo()
|
||||
195 | | else:
|
||||
196 | | z = other
|
||||
| |_____________^ SIM108
|
||||
|
|
||||
= help: Replace `if`-`else`-block with `z = not foo() if foo() else other`
|
||||
|
||||
ℹ Unsafe fix
|
||||
190 190 | # SIM108 does not suggest a binary option in this
|
||||
191 191 | # case, since we'd be reducing the number of calls
|
||||
192 192 | # from Two to one.
|
||||
193 |-if foo():
|
||||
194 |- z = not foo()
|
||||
195 |-else:
|
||||
196 |- z = other
|
||||
193 |+z = not foo() if foo() else other
|
||||
Loading…
Reference in New Issue