[`pylint`] - add fix for unary expressions in `PLC2801` (#9587)

## Summary

Closes #9572

Don't go easy on this review!

## Test Plan

`cargo test`
This commit is contained in:
Steve C 2024-03-04 05:25:17 -05:00 committed by GitHub
parent 00300c0d9d
commit 8dde81a905
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 900 additions and 41 deletions

View File

@ -1,6 +1,6 @@
from typing import Any
a = 2
print((3.0).__add__(4.0)) # PLC2801
print((3.0).__sub__(4.0)) # PLC2801
print((3.0).__mul__(4.0)) # PLC2801
@ -17,6 +17,67 @@ print((3.0).__str__()) # PLC2801
print((3.0).__repr__()) # PLC2801
print([1, 2, 3].__len__()) # PLC2801
print((1).__neg__()) # PLC2801
print(-a.__sub__(1)) # PLC2801
print(-(a).__sub__(1)) # PLC2801
print(-(-a.__sub__(1))) # PLC2801
print((5 - a).__sub__(1)) # PLC2801
print(-(5 - a).__sub__(1)) # PLC2801
print(-(-5 - a).__sub__(1)) # PLC2801
print(+-+-+-a.__sub__(1)) # PLC2801
print(a.__rsub__(2 - 1)) # PLC2801
print(a.__sub__(((((1)))))) # PLC2801
print(a.__sub__(((((2 - 1)))))) # PLC2801
print(a.__sub__(
3
+
4
))
print(a.__rsub__(
3
+
4
))
print(2 * a.__add__(3)) # PLC2801
x = 2 * a.__add__(3) # PLC2801
x = 2 * -a.__add__(3) # PLC2801
x = a.__add__(3) # PLC2801
x = -a.__add__(3) # PLC2801
x = (-a).__add__(3) # PLC2801
x = -(-a).__add__(3) # PLC2801
# Calls
print(a.__call__()) # PLC2801 (no fix, intentional)
# Lambda expressions
blah = lambda: a.__add__(1) # PLC2801
# If expressions
print(a.__add__(1) if a > 0 else a.__sub__(1)) # PLC2801
# Dict/Set/List/Tuple
print({"a": a.__add__(1)}) # PLC2801
print({a.__add__(1)}) # PLC2801
print([a.__add__(1)]) # PLC2801
print((a.__add__(1),)) # PLC2801
# Comprehension variants
print({i: i.__add__(1) for i in range(5)}) # PLC2801
print({i.__add__(1) for i in range(5)}) # PLC2801
print([i.__add__(1) for i in range(5)]) # PLC2801
print((i.__add__(1) for i in range(5))) # PLC2801
# Generators
gen = (i.__add__(1) for i in range(5)) # PLC2801
print(next(gen))
# Subscripts
print({"a": a.__add__(1)}["a"]) # PLC2801
# Starred
print(*[a.__add__(1)]) # PLC2801
# Slices
print([a.__add__(1), a.__sub__(1)][0:1]) # PLC2801
class Thing:

View File

@ -124,21 +124,30 @@ pub(crate) fn unnecessary_dunder_call(checker: &mut Checker, call: &ast::ExprCal
title = Some(message.to_string());
}
([arg], DunderReplacement::Operator(replacement, message)) => {
fixed = Some(format!(
"{} {} {}",
checker.locator().slice(value.as_ref()),
replacement,
checker.locator().slice(arg),
));
let value_slice = checker.locator().slice(value.as_ref());
let arg_slice = checker.locator().slice(arg);
if can_be_represented_without_parentheses(arg) {
// if it's something that can reasonably be removed from parentheses,
// we'll do that.
fixed = Some(format!("{value_slice} {replacement} {arg_slice}"));
} else {
fixed = Some(format!("{value_slice} {replacement} ({arg_slice})"));
}
title = Some(message.to_string());
}
([arg], DunderReplacement::ROperator(replacement, message)) => {
fixed = Some(format!(
"{} {} {}",
checker.locator().slice(arg),
replacement,
checker.locator().slice(value.as_ref()),
));
let value_slice = checker.locator().slice(value.as_ref());
let arg_slice = checker.locator().slice(arg);
if arg.is_attribute_expr() || arg.is_name_expr() || arg.is_literal_expr() {
// if it's something that can reasonably be removed from parentheses,
// we'll do that.
fixed = Some(format!("{arg_slice} {replacement} {value_slice}"));
} else {
fixed = Some(format!("({arg_slice}) {replacement} {value_slice}"));
}
title = Some(message.to_string());
}
(_, DunderReplacement::MessageOnly(message)) => {
@ -156,8 +165,25 @@ pub(crate) fn unnecessary_dunder_call(checker: &mut Checker, call: &ast::ExprCal
call.range(),
);
if let Some(fixed) = fixed {
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(fixed, call.range())));
if let Some(mut fixed) = fixed {
// by the looks of it, we don't need to wrap the expression in parens if
// it's the only argument to a call expression.
// being in any other kind of expression though, we *will* add parens.
// e.g. `print(a.__add__(3))` -> `print(a + 3)` instead of `print((a + 3))`
// a multiplication expression example: `x = 2 * a.__add__(3)` -> `x = 2 * (a + 3)`
let wrap_in_paren = checker
.semantic()
.current_expression_parent()
.is_some_and(|parent| !can_be_represented_without_parentheses(parent));
if wrap_in_paren {
fixed = format!("({fixed})");
}
diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement(
fixed,
call.range(),
)));
};
checker.diagnostics.push(diagnostic);
@ -358,3 +384,24 @@ fn in_dunder_method_definition(semantic: &SemanticModel) -> bool {
func_def.name.starts_with("__") && func_def.name.ends_with("__")
})
}
/// Returns `true` if the [`Expr`] can be represented without parentheses.
fn can_be_represented_without_parentheses(expr: &Expr) -> bool {
expr.is_attribute_expr()
|| expr.is_name_expr()
|| expr.is_literal_expr()
|| expr.is_call_expr()
|| expr.is_lambda_expr()
|| expr.is_if_exp_expr()
|| expr.is_generator_exp_expr()
|| expr.is_subscript_expr()
|| expr.is_starred_expr()
|| expr.is_slice_expr()
|| expr.is_dict_expr()
|| expr.is_dict_comp_expr()
|| expr.is_list_expr()
|| expr.is_list_comp_expr()
|| expr.is_tuple_expr()
|| expr.is_set_comp_expr()
|| expr.is_set_expr()
}

View File

@ -3,6 +3,7 @@ source: crates/ruff_linter/src/rules/pylint/mod.rs
---
unnecessary_dunder_call.py:4:7: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
3 | a = 2
4 | print((3.0).__add__(4.0)) # PLC2801
| ^^^^^^^^^^^^^^^^^^ PLC2801
5 | print((3.0).__sub__(4.0)) # PLC2801
@ -10,10 +11,10 @@ unnecessary_dunder_call.py:4:7: PLC2801 [*] Unnecessary dunder call to `__add__`
|
= help: Use `+` operator
Safe fix
Unsafe fix
1 1 | from typing import Any
2 2 |
3 3 |
3 3 | a = 2
4 |-print((3.0).__add__(4.0)) # PLC2801
4 |+print(3.0 + 4.0) # PLC2801
5 5 | print((3.0).__sub__(4.0)) # PLC2801
@ -22,6 +23,7 @@ unnecessary_dunder_call.py:4:7: PLC2801 [*] Unnecessary dunder call to `__add__`
unnecessary_dunder_call.py:5:7: PLC2801 [*] Unnecessary dunder call to `__sub__`. Use `-` operator.
|
3 | a = 2
4 | print((3.0).__add__(4.0)) # PLC2801
5 | print((3.0).__sub__(4.0)) # PLC2801
| ^^^^^^^^^^^^^^^^^^ PLC2801
@ -30,9 +32,9 @@ unnecessary_dunder_call.py:5:7: PLC2801 [*] Unnecessary dunder call to `__sub__`
|
= help: Use `-` operator
Safe fix
Unsafe fix
2 2 |
3 3 |
3 3 | a = 2
4 4 | print((3.0).__add__(4.0)) # PLC2801
5 |-print((3.0).__sub__(4.0)) # PLC2801
5 |+print(3.0 - 4.0) # PLC2801
@ -51,8 +53,8 @@ unnecessary_dunder_call.py:6:7: PLC2801 [*] Unnecessary dunder call to `__mul__`
|
= help: Use `*` operator
Safe fix
3 3 |
Unsafe fix
3 3 | a = 2
4 4 | print((3.0).__add__(4.0)) # PLC2801
5 5 | print((3.0).__sub__(4.0)) # PLC2801
6 |-print((3.0).__mul__(4.0)) # PLC2801
@ -72,7 +74,7 @@ unnecessary_dunder_call.py:7:7: PLC2801 [*] Unnecessary dunder call to `__truedi
|
= help: Use `/` operator
Safe fix
Unsafe fix
4 4 | print((3.0).__add__(4.0)) # PLC2801
5 5 | print((3.0).__sub__(4.0)) # PLC2801
6 6 | print((3.0).__mul__(4.0)) # PLC2801
@ -93,7 +95,7 @@ unnecessary_dunder_call.py:8:7: PLC2801 [*] Unnecessary dunder call to `__floord
|
= help: Use `//` operator
Safe fix
Unsafe fix
5 5 | print((3.0).__sub__(4.0)) # PLC2801
6 6 | print((3.0).__mul__(4.0)) # PLC2801
7 7 | print((3.0).__truediv__(4.0)) # PLC2801
@ -114,7 +116,7 @@ unnecessary_dunder_call.py:9:7: PLC2801 [*] Unnecessary dunder call to `__mod__`
|
= help: Use `%` operator
Safe fix
Unsafe fix
6 6 | print((3.0).__mul__(4.0)) # PLC2801
7 7 | print((3.0).__truediv__(4.0)) # PLC2801
8 8 | print((3.0).__floordiv__(4.0)) # PLC2801
@ -135,7 +137,7 @@ unnecessary_dunder_call.py:10:7: PLC2801 [*] Unnecessary dunder call to `__eq__`
|
= help: Use `==` operator
Safe fix
Unsafe fix
7 7 | print((3.0).__truediv__(4.0)) # PLC2801
8 8 | print((3.0).__floordiv__(4.0)) # PLC2801
9 9 | print((3.0).__mod__(4.0)) # PLC2801
@ -156,7 +158,7 @@ unnecessary_dunder_call.py:11:7: PLC2801 [*] Unnecessary dunder call to `__ne__`
|
= help: Use `!=` operator
Safe fix
Unsafe fix
8 8 | print((3.0).__floordiv__(4.0)) # PLC2801
9 9 | print((3.0).__mod__(4.0)) # PLC2801
10 10 | print((3.0).__eq__(4.0)) # PLC2801
@ -177,7 +179,7 @@ unnecessary_dunder_call.py:12:7: PLC2801 [*] Unnecessary dunder call to `__lt__`
|
= help: Use `<` operator
Safe fix
Unsafe fix
9 9 | print((3.0).__mod__(4.0)) # PLC2801
10 10 | print((3.0).__eq__(4.0)) # PLC2801
11 11 | print((3.0).__ne__(4.0)) # PLC2801
@ -198,7 +200,7 @@ unnecessary_dunder_call.py:13:7: PLC2801 [*] Unnecessary dunder call to `__le__`
|
= help: Use `<=` operator
Safe fix
Unsafe fix
10 10 | print((3.0).__eq__(4.0)) # PLC2801
11 11 | print((3.0).__ne__(4.0)) # PLC2801
12 12 | print((3.0).__lt__(4.0)) # PLC2801
@ -219,7 +221,7 @@ unnecessary_dunder_call.py:14:7: PLC2801 [*] Unnecessary dunder call to `__gt__`
|
= help: Use `>` operator
Safe fix
Unsafe fix
11 11 | print((3.0).__ne__(4.0)) # PLC2801
12 12 | print((3.0).__lt__(4.0)) # PLC2801
13 13 | print((3.0).__le__(4.0)) # PLC2801
@ -240,7 +242,7 @@ unnecessary_dunder_call.py:15:7: PLC2801 [*] Unnecessary dunder call to `__ge__`
|
= help: Use `>=` operator
Safe fix
Unsafe fix
12 12 | print((3.0).__lt__(4.0)) # PLC2801
13 13 | print((3.0).__le__(4.0)) # PLC2801
14 14 | print((3.0).__gt__(4.0)) # PLC2801
@ -261,7 +263,7 @@ unnecessary_dunder_call.py:16:7: PLC2801 [*] Unnecessary dunder call to `__str__
|
= help: Use `str()` builtin
Safe fix
Unsafe fix
13 13 | print((3.0).__le__(4.0)) # PLC2801
14 14 | print((3.0).__gt__(4.0)) # PLC2801
15 15 | print((3.0).__ge__(4.0)) # PLC2801
@ -282,7 +284,7 @@ unnecessary_dunder_call.py:17:7: PLC2801 [*] Unnecessary dunder call to `__repr_
|
= help: Use `repr()` builtin
Safe fix
Unsafe fix
14 14 | print((3.0).__gt__(4.0)) # PLC2801
15 15 | print((3.0).__ge__(4.0)) # PLC2801
16 16 | print((3.0).__str__()) # PLC2801
@ -290,7 +292,7 @@ unnecessary_dunder_call.py:17:7: PLC2801 [*] Unnecessary dunder call to `__repr_
17 |+print(repr(3.0)) # PLC2801
18 18 | print([1, 2, 3].__len__()) # PLC2801
19 19 | print((1).__neg__()) # PLC2801
20 20 |
20 20 | print(-a.__sub__(1)) # PLC2801
unnecessary_dunder_call.py:18:7: PLC2801 [*] Unnecessary dunder call to `__len__`. Use `len()` builtin.
|
@ -299,18 +301,19 @@ unnecessary_dunder_call.py:18:7: PLC2801 [*] Unnecessary dunder call to `__len__
18 | print([1, 2, 3].__len__()) # PLC2801
| ^^^^^^^^^^^^^^^^^^^ PLC2801
19 | print((1).__neg__()) # PLC2801
20 | print(-a.__sub__(1)) # PLC2801
|
= help: Use `len()` builtin
Safe fix
Unsafe fix
15 15 | print((3.0).__ge__(4.0)) # PLC2801
16 16 | print((3.0).__str__()) # PLC2801
17 17 | print((3.0).__repr__()) # PLC2801
18 |-print([1, 2, 3].__len__()) # PLC2801
18 |+print(len([1, 2, 3])) # PLC2801
19 19 | print((1).__neg__()) # PLC2801
20 20 |
21 21 |
20 20 | print(-a.__sub__(1)) # PLC2801
21 21 | print(-(a).__sub__(1)) # PLC2801
unnecessary_dunder_call.py:19:7: PLC2801 Unnecessary dunder call to `__neg__`. Multiply by -1 instead.
|
@ -318,16 +321,764 @@ unnecessary_dunder_call.py:19:7: PLC2801 Unnecessary dunder call to `__neg__`. M
18 | print([1, 2, 3].__len__()) # PLC2801
19 | print((1).__neg__()) # PLC2801
| ^^^^^^^^^^^^^ PLC2801
20 | print(-a.__sub__(1)) # PLC2801
21 | print(-(a).__sub__(1)) # PLC2801
|
= help: Multiply by -1 instead
unnecessary_dunder_call.py:31:16: PLC2801 Unnecessary dunder call to `__getattribute__`. Access attribute directly or use getattr built-in function.
unnecessary_dunder_call.py:20:8: PLC2801 [*] Unnecessary dunder call to `__sub__`. Use `-` operator.
|
30 | def do_thing(self, item):
31 | return object.__getattribute__(self, item) # PLC2801
18 | print([1, 2, 3].__len__()) # PLC2801
19 | print((1).__neg__()) # PLC2801
20 | print(-a.__sub__(1)) # PLC2801
| ^^^^^^^^^^^^ PLC2801
21 | print(-(a).__sub__(1)) # PLC2801
22 | print(-(-a.__sub__(1))) # PLC2801
|
= help: Use `-` operator
Unsafe fix
17 17 | print((3.0).__repr__()) # PLC2801
18 18 | print([1, 2, 3].__len__()) # PLC2801
19 19 | print((1).__neg__()) # PLC2801
20 |-print(-a.__sub__(1)) # PLC2801
20 |+print(-(a - 1)) # PLC2801
21 21 | print(-(a).__sub__(1)) # PLC2801
22 22 | print(-(-a.__sub__(1))) # PLC2801
23 23 | print((5 - a).__sub__(1)) # PLC2801
unnecessary_dunder_call.py:21:8: PLC2801 [*] Unnecessary dunder call to `__sub__`. Use `-` operator.
|
19 | print((1).__neg__()) # PLC2801
20 | print(-a.__sub__(1)) # PLC2801
21 | print(-(a).__sub__(1)) # PLC2801
| ^^^^^^^^^^^^^^ PLC2801
22 | print(-(-a.__sub__(1))) # PLC2801
23 | print((5 - a).__sub__(1)) # PLC2801
|
= help: Use `-` operator
Unsafe fix
18 18 | print([1, 2, 3].__len__()) # PLC2801
19 19 | print((1).__neg__()) # PLC2801
20 20 | print(-a.__sub__(1)) # PLC2801
21 |-print(-(a).__sub__(1)) # PLC2801
21 |+print(-(a - 1)) # PLC2801
22 22 | print(-(-a.__sub__(1))) # PLC2801
23 23 | print((5 - a).__sub__(1)) # PLC2801
24 24 | print(-(5 - a).__sub__(1)) # PLC2801
unnecessary_dunder_call.py:22:10: PLC2801 [*] Unnecessary dunder call to `__sub__`. Use `-` operator.
|
20 | print(-a.__sub__(1)) # PLC2801
21 | print(-(a).__sub__(1)) # PLC2801
22 | print(-(-a.__sub__(1))) # PLC2801
| ^^^^^^^^^^^^ PLC2801
23 | print((5 - a).__sub__(1)) # PLC2801
24 | print(-(5 - a).__sub__(1)) # PLC2801
|
= help: Use `-` operator
Unsafe fix
19 19 | print((1).__neg__()) # PLC2801
20 20 | print(-a.__sub__(1)) # PLC2801
21 21 | print(-(a).__sub__(1)) # PLC2801
22 |-print(-(-a.__sub__(1))) # PLC2801
22 |+print(-(-(a - 1))) # PLC2801
23 23 | print((5 - a).__sub__(1)) # PLC2801
24 24 | print(-(5 - a).__sub__(1)) # PLC2801
25 25 | print(-(-5 - a).__sub__(1)) # PLC2801
unnecessary_dunder_call.py:23:7: PLC2801 [*] Unnecessary dunder call to `__sub__`. Use `-` operator.
|
21 | print(-(a).__sub__(1)) # PLC2801
22 | print(-(-a.__sub__(1))) # PLC2801
23 | print((5 - a).__sub__(1)) # PLC2801
| ^^^^^^^^^^^^^^^^^^ PLC2801
24 | print(-(5 - a).__sub__(1)) # PLC2801
25 | print(-(-5 - a).__sub__(1)) # PLC2801
|
= help: Use `-` operator
Unsafe fix
20 20 | print(-a.__sub__(1)) # PLC2801
21 21 | print(-(a).__sub__(1)) # PLC2801
22 22 | print(-(-a.__sub__(1))) # PLC2801
23 |-print((5 - a).__sub__(1)) # PLC2801
23 |+print(5 - a - 1) # PLC2801
24 24 | print(-(5 - a).__sub__(1)) # PLC2801
25 25 | print(-(-5 - a).__sub__(1)) # PLC2801
26 26 | print(+-+-+-a.__sub__(1)) # PLC2801
unnecessary_dunder_call.py:24:8: PLC2801 [*] Unnecessary dunder call to `__sub__`. Use `-` operator.
|
22 | print(-(-a.__sub__(1))) # PLC2801
23 | print((5 - a).__sub__(1)) # PLC2801
24 | print(-(5 - a).__sub__(1)) # PLC2801
| ^^^^^^^^^^^^^^^^^^ PLC2801
25 | print(-(-5 - a).__sub__(1)) # PLC2801
26 | print(+-+-+-a.__sub__(1)) # PLC2801
|
= help: Use `-` operator
Unsafe fix
21 21 | print(-(a).__sub__(1)) # PLC2801
22 22 | print(-(-a.__sub__(1))) # PLC2801
23 23 | print((5 - a).__sub__(1)) # PLC2801
24 |-print(-(5 - a).__sub__(1)) # PLC2801
24 |+print(-(5 - a - 1)) # PLC2801
25 25 | print(-(-5 - a).__sub__(1)) # PLC2801
26 26 | print(+-+-+-a.__sub__(1)) # PLC2801
27 27 | print(a.__rsub__(2 - 1)) # PLC2801
unnecessary_dunder_call.py:25:8: PLC2801 [*] Unnecessary dunder call to `__sub__`. Use `-` operator.
|
23 | print((5 - a).__sub__(1)) # PLC2801
24 | print(-(5 - a).__sub__(1)) # PLC2801
25 | print(-(-5 - a).__sub__(1)) # PLC2801
| ^^^^^^^^^^^^^^^^^^^ PLC2801
26 | print(+-+-+-a.__sub__(1)) # PLC2801
27 | print(a.__rsub__(2 - 1)) # PLC2801
|
= help: Use `-` operator
Unsafe fix
22 22 | print(-(-a.__sub__(1))) # PLC2801
23 23 | print((5 - a).__sub__(1)) # PLC2801
24 24 | print(-(5 - a).__sub__(1)) # PLC2801
25 |-print(-(-5 - a).__sub__(1)) # PLC2801
25 |+print(-(-5 - a - 1)) # PLC2801
26 26 | print(+-+-+-a.__sub__(1)) # PLC2801
27 27 | print(a.__rsub__(2 - 1)) # PLC2801
28 28 | print(a.__sub__(((((1)))))) # PLC2801
unnecessary_dunder_call.py:26:13: PLC2801 [*] Unnecessary dunder call to `__sub__`. Use `-` operator.
|
24 | print(-(5 - a).__sub__(1)) # PLC2801
25 | print(-(-5 - a).__sub__(1)) # PLC2801
26 | print(+-+-+-a.__sub__(1)) # PLC2801
| ^^^^^^^^^^^^ PLC2801
27 | print(a.__rsub__(2 - 1)) # PLC2801
28 | print(a.__sub__(((((1)))))) # PLC2801
|
= help: Use `-` operator
Unsafe fix
23 23 | print((5 - a).__sub__(1)) # PLC2801
24 24 | print(-(5 - a).__sub__(1)) # PLC2801
25 25 | print(-(-5 - a).__sub__(1)) # PLC2801
26 |-print(+-+-+-a.__sub__(1)) # PLC2801
26 |+print(+-+-+-(a - 1)) # PLC2801
27 27 | print(a.__rsub__(2 - 1)) # PLC2801
28 28 | print(a.__sub__(((((1)))))) # PLC2801
29 29 | print(a.__sub__(((((2 - 1)))))) # PLC2801
unnecessary_dunder_call.py:27:7: PLC2801 [*] Unnecessary dunder call to `__rsub__`. Use `-` operator.
|
25 | print(-(-5 - a).__sub__(1)) # PLC2801
26 | print(+-+-+-a.__sub__(1)) # PLC2801
27 | print(a.__rsub__(2 - 1)) # PLC2801
| ^^^^^^^^^^^^^^^^^ PLC2801
28 | print(a.__sub__(((((1)))))) # PLC2801
29 | print(a.__sub__(((((2 - 1)))))) # PLC2801
|
= help: Use `-` operator
Unsafe fix
24 24 | print(-(5 - a).__sub__(1)) # PLC2801
25 25 | print(-(-5 - a).__sub__(1)) # PLC2801
26 26 | print(+-+-+-a.__sub__(1)) # PLC2801
27 |-print(a.__rsub__(2 - 1)) # PLC2801
27 |+print((2 - 1) - a) # PLC2801
28 28 | print(a.__sub__(((((1)))))) # PLC2801
29 29 | print(a.__sub__(((((2 - 1)))))) # PLC2801
30 30 | print(a.__sub__(
unnecessary_dunder_call.py:28:7: PLC2801 [*] Unnecessary dunder call to `__sub__`. Use `-` operator.
|
26 | print(+-+-+-a.__sub__(1)) # PLC2801
27 | print(a.__rsub__(2 - 1)) # PLC2801
28 | print(a.__sub__(((((1)))))) # PLC2801
| ^^^^^^^^^^^^^^^^^^^^ PLC2801
29 | print(a.__sub__(((((2 - 1)))))) # PLC2801
30 | print(a.__sub__(
|
= help: Use `-` operator
Unsafe fix
25 25 | print(-(-5 - a).__sub__(1)) # PLC2801
26 26 | print(+-+-+-a.__sub__(1)) # PLC2801
27 27 | print(a.__rsub__(2 - 1)) # PLC2801
28 |-print(a.__sub__(((((1)))))) # PLC2801
28 |+print(a - 1) # PLC2801
29 29 | print(a.__sub__(((((2 - 1)))))) # PLC2801
30 30 | print(a.__sub__(
31 31 | 3
unnecessary_dunder_call.py:29:7: PLC2801 [*] Unnecessary dunder call to `__sub__`. Use `-` operator.
|
27 | print(a.__rsub__(2 - 1)) # PLC2801
28 | print(a.__sub__(((((1)))))) # PLC2801
29 | print(a.__sub__(((((2 - 1)))))) # PLC2801
| ^^^^^^^^^^^^^^^^^^^^^^^^ PLC2801
30 | print(a.__sub__(
31 | 3
|
= help: Use `-` operator
Unsafe fix
26 26 | print(+-+-+-a.__sub__(1)) # PLC2801
27 27 | print(a.__rsub__(2 - 1)) # PLC2801
28 28 | print(a.__sub__(((((1)))))) # PLC2801
29 |-print(a.__sub__(((((2 - 1)))))) # PLC2801
29 |+print(a - (2 - 1)) # PLC2801
30 30 | print(a.__sub__(
31 31 | 3
32 32 | +
unnecessary_dunder_call.py:30:7: PLC2801 [*] Unnecessary dunder call to `__sub__`. Use `-` operator.
|
28 | print(a.__sub__(((((1)))))) # PLC2801
29 | print(a.__sub__(((((2 - 1)))))) # PLC2801
30 | print(a.__sub__(
| _______^
31 | | 3
32 | | +
33 | | 4
34 | | ))
| |_^ PLC2801
35 | print(a.__rsub__(
36 | 3
|
= help: Use `-` operator
Unsafe fix
27 27 | print(a.__rsub__(2 - 1)) # PLC2801
28 28 | print(a.__sub__(((((1)))))) # PLC2801
29 29 | print(a.__sub__(((((2 - 1)))))) # PLC2801
30 |-print(a.__sub__(
31 |- 3
30 |+print(a - (3
32 31 | +
33 |- 4
34 |-))
32 |+ 4))
35 33 | print(a.__rsub__(
36 34 | 3
37 35 | +
unnecessary_dunder_call.py:35:7: PLC2801 [*] Unnecessary dunder call to `__rsub__`. Use `-` operator.
|
33 | 4
34 | ))
35 | print(a.__rsub__(
| _______^
36 | | 3
37 | | +
38 | | 4
39 | | ))
| |_^ PLC2801
40 | print(2 * a.__add__(3)) # PLC2801
41 | x = 2 * a.__add__(3) # PLC2801
|
= help: Use `-` operator
Unsafe fix
32 32 | +
33 33 | 4
34 34 | ))
35 |-print(a.__rsub__(
36 |- 3
35 |+print((3
37 36 | +
38 |- 4
39 |-))
37 |+ 4) - a)
40 38 | print(2 * a.__add__(3)) # PLC2801
41 39 | x = 2 * a.__add__(3) # PLC2801
42 40 | x = 2 * -a.__add__(3) # PLC2801
unnecessary_dunder_call.py:40:11: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
38 | 4
39 | ))
40 | print(2 * a.__add__(3)) # PLC2801
| ^^^^^^^^^^^^ PLC2801
41 | x = 2 * a.__add__(3) # PLC2801
42 | x = 2 * -a.__add__(3) # PLC2801
|
= help: Use `+` operator
Unsafe fix
37 37 | +
38 38 | 4
39 39 | ))
40 |-print(2 * a.__add__(3)) # PLC2801
40 |+print(2 * (a + 3)) # PLC2801
41 41 | x = 2 * a.__add__(3) # PLC2801
42 42 | x = 2 * -a.__add__(3) # PLC2801
43 43 | x = a.__add__(3) # PLC2801
unnecessary_dunder_call.py:41:9: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
39 | ))
40 | print(2 * a.__add__(3)) # PLC2801
41 | x = 2 * a.__add__(3) # PLC2801
| ^^^^^^^^^^^^ PLC2801
42 | x = 2 * -a.__add__(3) # PLC2801
43 | x = a.__add__(3) # PLC2801
|
= help: Use `+` operator
Unsafe fix
38 38 | 4
39 39 | ))
40 40 | print(2 * a.__add__(3)) # PLC2801
41 |-x = 2 * a.__add__(3) # PLC2801
41 |+x = 2 * (a + 3) # PLC2801
42 42 | x = 2 * -a.__add__(3) # PLC2801
43 43 | x = a.__add__(3) # PLC2801
44 44 | x = -a.__add__(3) # PLC2801
unnecessary_dunder_call.py:42:10: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
40 | print(2 * a.__add__(3)) # PLC2801
41 | x = 2 * a.__add__(3) # PLC2801
42 | x = 2 * -a.__add__(3) # PLC2801
| ^^^^^^^^^^^^ PLC2801
43 | x = a.__add__(3) # PLC2801
44 | x = -a.__add__(3) # PLC2801
|
= help: Use `+` operator
Unsafe fix
39 39 | ))
40 40 | print(2 * a.__add__(3)) # PLC2801
41 41 | x = 2 * a.__add__(3) # PLC2801
42 |-x = 2 * -a.__add__(3) # PLC2801
42 |+x = 2 * -(a + 3) # PLC2801
43 43 | x = a.__add__(3) # PLC2801
44 44 | x = -a.__add__(3) # PLC2801
45 45 | x = (-a).__add__(3) # PLC2801
unnecessary_dunder_call.py:43:5: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
41 | x = 2 * a.__add__(3) # PLC2801
42 | x = 2 * -a.__add__(3) # PLC2801
43 | x = a.__add__(3) # PLC2801
| ^^^^^^^^^^^^ PLC2801
44 | x = -a.__add__(3) # PLC2801
45 | x = (-a).__add__(3) # PLC2801
|
= help: Use `+` operator
Unsafe fix
40 40 | print(2 * a.__add__(3)) # PLC2801
41 41 | x = 2 * a.__add__(3) # PLC2801
42 42 | x = 2 * -a.__add__(3) # PLC2801
43 |-x = a.__add__(3) # PLC2801
43 |+x = a + 3 # PLC2801
44 44 | x = -a.__add__(3) # PLC2801
45 45 | x = (-a).__add__(3) # PLC2801
46 46 | x = -(-a).__add__(3) # PLC2801
unnecessary_dunder_call.py:44:6: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
42 | x = 2 * -a.__add__(3) # PLC2801
43 | x = a.__add__(3) # PLC2801
44 | x = -a.__add__(3) # PLC2801
| ^^^^^^^^^^^^ PLC2801
45 | x = (-a).__add__(3) # PLC2801
46 | x = -(-a).__add__(3) # PLC2801
|
= help: Use `+` operator
Unsafe fix
41 41 | x = 2 * a.__add__(3) # PLC2801
42 42 | x = 2 * -a.__add__(3) # PLC2801
43 43 | x = a.__add__(3) # PLC2801
44 |-x = -a.__add__(3) # PLC2801
44 |+x = -(a + 3) # PLC2801
45 45 | x = (-a).__add__(3) # PLC2801
46 46 | x = -(-a).__add__(3) # PLC2801
47 47 |
unnecessary_dunder_call.py:45:5: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
43 | x = a.__add__(3) # PLC2801
44 | x = -a.__add__(3) # PLC2801
45 | x = (-a).__add__(3) # PLC2801
| ^^^^^^^^^^^^^^^ PLC2801
46 | x = -(-a).__add__(3) # PLC2801
|
= help: Use `+` operator
Unsafe fix
42 42 | x = 2 * -a.__add__(3) # PLC2801
43 43 | x = a.__add__(3) # PLC2801
44 44 | x = -a.__add__(3) # PLC2801
45 |-x = (-a).__add__(3) # PLC2801
45 |+x = -a + 3 # PLC2801
46 46 | x = -(-a).__add__(3) # PLC2801
47 47 |
48 48 | # Calls
unnecessary_dunder_call.py:46:6: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
44 | x = -a.__add__(3) # PLC2801
45 | x = (-a).__add__(3) # PLC2801
46 | x = -(-a).__add__(3) # PLC2801
| ^^^^^^^^^^^^^^^ PLC2801
47 |
48 | # Calls
|
= help: Use `+` operator
Unsafe fix
43 43 | x = a.__add__(3) # PLC2801
44 44 | x = -a.__add__(3) # PLC2801
45 45 | x = (-a).__add__(3) # PLC2801
46 |-x = -(-a).__add__(3) # PLC2801
46 |+x = -(-a + 3) # PLC2801
47 47 |
48 48 | # Calls
49 49 | print(a.__call__()) # PLC2801 (no fix, intentional)
unnecessary_dunder_call.py:49:7: PLC2801 Unnecessary dunder call to `__call__`
|
48 | # Calls
49 | print(a.__call__()) # PLC2801 (no fix, intentional)
| ^^^^^^^^^^^^ PLC2801
50 |
51 | # Lambda expressions
|
unnecessary_dunder_call.py:52:16: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
51 | # Lambda expressions
52 | blah = lambda: a.__add__(1) # PLC2801
| ^^^^^^^^^^^^ PLC2801
53 |
54 | # If expressions
|
= help: Use `+` operator
Unsafe fix
49 49 | print(a.__call__()) # PLC2801 (no fix, intentional)
50 50 |
51 51 | # Lambda expressions
52 |-blah = lambda: a.__add__(1) # PLC2801
52 |+blah = lambda: a + 1 # PLC2801
53 53 |
54 54 | # If expressions
55 55 | print(a.__add__(1) if a > 0 else a.__sub__(1)) # PLC2801
unnecessary_dunder_call.py:55:7: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
54 | # If expressions
55 | print(a.__add__(1) if a > 0 else a.__sub__(1)) # PLC2801
| ^^^^^^^^^^^^ PLC2801
56 |
57 | # Dict/Set/List/Tuple
|
= help: Use `+` operator
Unsafe fix
52 52 | blah = lambda: a.__add__(1) # PLC2801
53 53 |
54 54 | # If expressions
55 |-print(a.__add__(1) if a > 0 else a.__sub__(1)) # PLC2801
55 |+print(a + 1 if a > 0 else a.__sub__(1)) # PLC2801
56 56 |
57 57 | # Dict/Set/List/Tuple
58 58 | print({"a": a.__add__(1)}) # PLC2801
unnecessary_dunder_call.py:55:34: PLC2801 [*] Unnecessary dunder call to `__sub__`. Use `-` operator.
|
54 | # If expressions
55 | print(a.__add__(1) if a > 0 else a.__sub__(1)) # PLC2801
| ^^^^^^^^^^^^ PLC2801
56 |
57 | # Dict/Set/List/Tuple
|
= help: Use `-` operator
Unsafe fix
52 52 | blah = lambda: a.__add__(1) # PLC2801
53 53 |
54 54 | # If expressions
55 |-print(a.__add__(1) if a > 0 else a.__sub__(1)) # PLC2801
55 |+print(a.__add__(1) if a > 0 else a - 1) # PLC2801
56 56 |
57 57 | # Dict/Set/List/Tuple
58 58 | print({"a": a.__add__(1)}) # PLC2801
unnecessary_dunder_call.py:58:13: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
57 | # Dict/Set/List/Tuple
58 | print({"a": a.__add__(1)}) # PLC2801
| ^^^^^^^^^^^^ PLC2801
59 | print({a.__add__(1)}) # PLC2801
60 | print([a.__add__(1)]) # PLC2801
|
= help: Use `+` operator
Unsafe fix
55 55 | print(a.__add__(1) if a > 0 else a.__sub__(1)) # PLC2801
56 56 |
57 57 | # Dict/Set/List/Tuple
58 |-print({"a": a.__add__(1)}) # PLC2801
58 |+print({"a": a + 1}) # PLC2801
59 59 | print({a.__add__(1)}) # PLC2801
60 60 | print([a.__add__(1)]) # PLC2801
61 61 | print((a.__add__(1),)) # PLC2801
unnecessary_dunder_call.py:59:8: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
57 | # Dict/Set/List/Tuple
58 | print({"a": a.__add__(1)}) # PLC2801
59 | print({a.__add__(1)}) # PLC2801
| ^^^^^^^^^^^^ PLC2801
60 | print([a.__add__(1)]) # PLC2801
61 | print((a.__add__(1),)) # PLC2801
|
= help: Use `+` operator
Unsafe fix
56 56 |
57 57 | # Dict/Set/List/Tuple
58 58 | print({"a": a.__add__(1)}) # PLC2801
59 |-print({a.__add__(1)}) # PLC2801
59 |+print({a + 1}) # PLC2801
60 60 | print([a.__add__(1)]) # PLC2801
61 61 | print((a.__add__(1),)) # PLC2801
62 62 |
unnecessary_dunder_call.py:60:8: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
58 | print({"a": a.__add__(1)}) # PLC2801
59 | print({a.__add__(1)}) # PLC2801
60 | print([a.__add__(1)]) # PLC2801
| ^^^^^^^^^^^^ PLC2801
61 | print((a.__add__(1),)) # PLC2801
|
= help: Use `+` operator
Unsafe fix
57 57 | # Dict/Set/List/Tuple
58 58 | print({"a": a.__add__(1)}) # PLC2801
59 59 | print({a.__add__(1)}) # PLC2801
60 |-print([a.__add__(1)]) # PLC2801
60 |+print([a + 1]) # PLC2801
61 61 | print((a.__add__(1),)) # PLC2801
62 62 |
63 63 | # Comprehension variants
unnecessary_dunder_call.py:61:8: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
59 | print({a.__add__(1)}) # PLC2801
60 | print([a.__add__(1)]) # PLC2801
61 | print((a.__add__(1),)) # PLC2801
| ^^^^^^^^^^^^ PLC2801
62 |
63 | # Comprehension variants
|
= help: Use `+` operator
Unsafe fix
58 58 | print({"a": a.__add__(1)}) # PLC2801
59 59 | print({a.__add__(1)}) # PLC2801
60 60 | print([a.__add__(1)]) # PLC2801
61 |-print((a.__add__(1),)) # PLC2801
61 |+print((a + 1,)) # PLC2801
62 62 |
63 63 | # Comprehension variants
64 64 | print({i: i.__add__(1) for i in range(5)}) # PLC2801
unnecessary_dunder_call.py:64:11: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
63 | # Comprehension variants
64 | print({i: i.__add__(1) for i in range(5)}) # PLC2801
| ^^^^^^^^^^^^ PLC2801
65 | print({i.__add__(1) for i in range(5)}) # PLC2801
66 | print([i.__add__(1) for i in range(5)]) # PLC2801
|
= help: Use `+` operator
Unsafe fix
61 61 | print((a.__add__(1),)) # PLC2801
62 62 |
63 63 | # Comprehension variants
64 |-print({i: i.__add__(1) for i in range(5)}) # PLC2801
64 |+print({i: i + 1 for i in range(5)}) # PLC2801
65 65 | print({i.__add__(1) for i in range(5)}) # PLC2801
66 66 | print([i.__add__(1) for i in range(5)]) # PLC2801
67 67 | print((i.__add__(1) for i in range(5))) # PLC2801
unnecessary_dunder_call.py:65:8: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
63 | # Comprehension variants
64 | print({i: i.__add__(1) for i in range(5)}) # PLC2801
65 | print({i.__add__(1) for i in range(5)}) # PLC2801
| ^^^^^^^^^^^^ PLC2801
66 | print([i.__add__(1) for i in range(5)]) # PLC2801
67 | print((i.__add__(1) for i in range(5))) # PLC2801
|
= help: Use `+` operator
Unsafe fix
62 62 |
63 63 | # Comprehension variants
64 64 | print({i: i.__add__(1) for i in range(5)}) # PLC2801
65 |-print({i.__add__(1) for i in range(5)}) # PLC2801
65 |+print({i + 1 for i in range(5)}) # PLC2801
66 66 | print([i.__add__(1) for i in range(5)]) # PLC2801
67 67 | print((i.__add__(1) for i in range(5))) # PLC2801
68 68 |
unnecessary_dunder_call.py:66:8: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
64 | print({i: i.__add__(1) for i in range(5)}) # PLC2801
65 | print({i.__add__(1) for i in range(5)}) # PLC2801
66 | print([i.__add__(1) for i in range(5)]) # PLC2801
| ^^^^^^^^^^^^ PLC2801
67 | print((i.__add__(1) for i in range(5))) # PLC2801
|
= help: Use `+` operator
Unsafe fix
63 63 | # Comprehension variants
64 64 | print({i: i.__add__(1) for i in range(5)}) # PLC2801
65 65 | print({i.__add__(1) for i in range(5)}) # PLC2801
66 |-print([i.__add__(1) for i in range(5)]) # PLC2801
66 |+print([i + 1 for i in range(5)]) # PLC2801
67 67 | print((i.__add__(1) for i in range(5))) # PLC2801
68 68 |
69 69 | # Generators
unnecessary_dunder_call.py:67:8: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
65 | print({i.__add__(1) for i in range(5)}) # PLC2801
66 | print([i.__add__(1) for i in range(5)]) # PLC2801
67 | print((i.__add__(1) for i in range(5))) # PLC2801
| ^^^^^^^^^^^^ PLC2801
68 |
69 | # Generators
|
= help: Use `+` operator
Unsafe fix
64 64 | print({i: i.__add__(1) for i in range(5)}) # PLC2801
65 65 | print({i.__add__(1) for i in range(5)}) # PLC2801
66 66 | print([i.__add__(1) for i in range(5)]) # PLC2801
67 |-print((i.__add__(1) for i in range(5))) # PLC2801
67 |+print((i + 1 for i in range(5))) # PLC2801
68 68 |
69 69 | # Generators
70 70 | gen = (i.__add__(1) for i in range(5)) # PLC2801
unnecessary_dunder_call.py:70:8: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
69 | # Generators
70 | gen = (i.__add__(1) for i in range(5)) # PLC2801
| ^^^^^^^^^^^^ PLC2801
71 | print(next(gen))
|
= help: Use `+` operator
Unsafe fix
67 67 | print((i.__add__(1) for i in range(5))) # PLC2801
68 68 |
69 69 | # Generators
70 |-gen = (i.__add__(1) for i in range(5)) # PLC2801
70 |+gen = (i + 1 for i in range(5)) # PLC2801
71 71 | print(next(gen))
72 72 |
73 73 | # Subscripts
unnecessary_dunder_call.py:74:13: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
73 | # Subscripts
74 | print({"a": a.__add__(1)}["a"]) # PLC2801
| ^^^^^^^^^^^^ PLC2801
75 |
76 | # Starred
|
= help: Use `+` operator
Unsafe fix
71 71 | print(next(gen))
72 72 |
73 73 | # Subscripts
74 |-print({"a": a.__add__(1)}["a"]) # PLC2801
74 |+print({"a": a + 1}["a"]) # PLC2801
75 75 |
76 76 | # Starred
77 77 | print(*[a.__add__(1)]) # PLC2801
unnecessary_dunder_call.py:77:9: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
76 | # Starred
77 | print(*[a.__add__(1)]) # PLC2801
| ^^^^^^^^^^^^ PLC2801
78 |
79 | # Slices
|
= help: Use `+` operator
Unsafe fix
74 74 | print({"a": a.__add__(1)}["a"]) # PLC2801
75 75 |
76 76 | # Starred
77 |-print(*[a.__add__(1)]) # PLC2801
77 |+print(*[a + 1]) # PLC2801
78 78 |
79 79 | # Slices
80 80 | print([a.__add__(1), a.__sub__(1)][0:1]) # PLC2801
unnecessary_dunder_call.py:80:8: PLC2801 [*] Unnecessary dunder call to `__add__`. Use `+` operator.
|
79 | # Slices
80 | print([a.__add__(1), a.__sub__(1)][0:1]) # PLC2801
| ^^^^^^^^^^^^ PLC2801
|
= help: Use `+` operator
Unsafe fix
77 77 | print(*[a.__add__(1)]) # PLC2801
78 78 |
79 79 | # Slices
80 |-print([a.__add__(1), a.__sub__(1)][0:1]) # PLC2801
80 |+print([a + 1, a.__sub__(1)][0:1]) # PLC2801
81 81 |
82 82 |
83 83 | class Thing:
unnecessary_dunder_call.py:80:22: PLC2801 [*] Unnecessary dunder call to `__sub__`. Use `-` operator.
|
79 | # Slices
80 | print([a.__add__(1), a.__sub__(1)][0:1]) # PLC2801
| ^^^^^^^^^^^^ PLC2801
|
= help: Use `-` operator
Unsafe fix
77 77 | print(*[a.__add__(1)]) # PLC2801
78 78 |
79 79 | # Slices
80 |-print([a.__add__(1), a.__sub__(1)][0:1]) # PLC2801
80 |+print([a.__add__(1), a - 1][0:1]) # PLC2801
81 81 |
82 82 |
83 83 | class Thing:
unnecessary_dunder_call.py:92:16: PLC2801 Unnecessary dunder call to `__getattribute__`. Access attribute directly or use getattr built-in function.
|
91 | def do_thing(self, item):
92 | return object.__getattribute__(self, item) # PLC2801
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLC2801
32 |
33 | def use_descriptor(self, item):
93 |
94 | def use_descriptor(self, item):
|
= help: Access attribute directly or use getattr built-in function