Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,50 @@ def t(self):
obj = T()
obj.a = obj.a + 1


a = a+-1

# Regression tests for https://github.com/astral-sh/ruff/issues/11672
test = 0x5
test = test + 0xBA

test2 = b""
test2 = test2 + b"\000"

test3 = ""
test3 = test3 + ( a := R""
f"oo" )

test4 = []
test4 = test4 + ( e
for e in
range(10)
)

test5 = test5 + (
4
*
10
)

test6 = test6 + \
(
4
*
10
)

test7 = \
100 \
+ test7

test8 = \
886 \
+ \
\
test8


# OK
a_list[0] = a_list[:] * 3
index = a_number = a_number + 1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use ast::{Expr, StmtAugAssign};
use ast::Expr;
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, ViolationMetadata};
use ruff_python_ast as ast;
use ruff_python_ast::comparable::ComparableExpr;
use ruff_python_ast::Operator;
use ruff_python_codegen::Generator;
use ruff_text_size::{Ranged, TextRange};
use ruff_python_ast::parenthesize::parenthesized_range;
use ruff_python_ast::{AstNode, ExpressionRef, Operator, StmtAssign};
use ruff_text_size::Ranged;

use crate::checkers::ast::Checker;

Expand Down Expand Up @@ -103,11 +103,11 @@ pub(crate) fn non_augmented_assignment(checker: &mut Checker, assign: &ast::Stmt
if ComparableExpr::from(target) == ComparableExpr::from(&value.left) {
let mut diagnostic = Diagnostic::new(NonAugmentedAssignment { operator }, assign.range());
diagnostic.set_fix(Fix::unsafe_edit(augmented_assignment(
checker.generator(),
checker,
target,
value.op,
operator,
&value.right,
assign.range(),
assign,
)));
checker.diagnostics.push(diagnostic);
return;
Expand All @@ -121,11 +121,11 @@ pub(crate) fn non_augmented_assignment(checker: &mut Checker, assign: &ast::Stmt
{
let mut diagnostic = Diagnostic::new(NonAugmentedAssignment { operator }, assign.range());
diagnostic.set_fix(Fix::unsafe_edit(augmented_assignment(
checker.generator(),
checker,
target,
value.op,
operator,
&value.left,
assign.range(),
assign,
)));
checker.diagnostics.push(diagnostic);
}
Expand All @@ -135,21 +135,29 @@ pub(crate) fn non_augmented_assignment(checker: &mut Checker, assign: &ast::Stmt
///
/// For example, given `x = x + 1`, the fix would be `x += 1`.
fn augmented_assignment(
generator: Generator,
checker: &Checker,
target: &Expr,
operator: Operator,
operator: AugmentedOperator,
right_operand: &Expr,
range: TextRange,
original_stmt: &StmtAssign,
) -> Edit {
Edit::range_replacement(
generator.stmt(&ast::Stmt::AugAssign(StmtAugAssign {
range: TextRange::default(),
target: Box::new(target.clone()),
op: operator,
value: Box::new(right_operand.clone()),
})),
range,
)
let locator = checker.locator();

let right_operand_ref = ExpressionRef::from(right_operand);
let parent = original_stmt.as_any_node_ref();
let comment_ranges = checker.comment_ranges();
let source = checker.source();

let right_operand_range =
parenthesized_range(right_operand_ref, parent, comment_ranges, source)
.unwrap_or(right_operand.range());
let right_operand_expr = locator.slice(right_operand_range);

let target_expr = locator.slice(target);

let new_content = format!("{target_expr} {operator} {right_operand_expr}");

Edit::range_replacement(new_content, original_stmt.range)
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ non_augmented_assignment.py:29:1: PLR6104 [*] Use `&=` to perform an augmented a
27 27 | to_cube = to_cube**to_cube
28 28 | timeDiffSeconds = timeDiffSeconds % 60
29 |-flags = flags & 0x1
29 |+flags &= 1
29 |+flags &= 0x1
30 30 | flags = flags | 0x1
31 31 | flags = flags ^ 0x1
32 32 | flags = flags << 1
Expand All @@ -290,7 +290,7 @@ non_augmented_assignment.py:30:1: PLR6104 [*] Use `|=` to perform an augmented a
28 28 | timeDiffSeconds = timeDiffSeconds % 60
29 29 | flags = flags & 0x1
30 |-flags = flags | 0x1
30 |+flags |= 1
30 |+flags |= 0x1
31 31 | flags = flags ^ 0x1
32 32 | flags = flags << 1
33 33 | flags = flags >> 1
Expand All @@ -311,7 +311,7 @@ non_augmented_assignment.py:31:1: PLR6104 [*] Use `^=` to perform an augmented a
29 29 | flags = flags & 0x1
30 30 | flags = flags | 0x1
31 |-flags = flags ^ 0x1
31 |+flags ^= 1
31 |+flags ^= 0x1
32 32 | flags = flags << 1
33 33 | flags = flags >> 1
34 34 | mat1 = mat1 @ mat2
Expand Down Expand Up @@ -495,7 +495,7 @@ non_augmented_assignment.py:42:1: PLR6104 [*] Use `*=` to perform an augmented a
40 40 | a_list[:] = a_list[:] * 3
41 41 |
42 |-index = index * (index + 10)
42 |+index *= index + 10
42 |+index *= (index + 10)
43 43 |
44 44 |
45 45 | class T:
Expand Down Expand Up @@ -524,8 +524,6 @@ non_augmented_assignment.py:51:1: PLR6104 [*] Use `+=` to perform an augmented a
50 | obj = T()
51 | obj.a = obj.a + 1
| ^^^^^^^^^^^^^^^^^ PLR6104
52 |
53 | # OK
|
= help: Replace with augmented assignment

Expand All @@ -536,5 +534,213 @@ non_augmented_assignment.py:51:1: PLR6104 [*] Use `+=` to perform an augmented a
51 |-obj.a = obj.a + 1
51 |+obj.a += 1
52 52 |
53 53 | # OK
54 54 | a_list[0] = a_list[:] * 3
53 53 |
54 54 | a = a+-1

non_augmented_assignment.py:54:1: PLR6104 [*] Use `+=` to perform an augmented assignment directly
|
54 | a = a+-1
| ^^^^^^^^ PLR6104
55 |
56 | # Regression tests for https://github.com/astral-sh/ruff/issues/11672
|
= help: Replace with augmented assignment

ℹ Unsafe fix
51 51 | obj.a = obj.a + 1
52 52 |
53 53 |
54 |-a = a+-1
54 |+a += -1
55 55 |
56 56 | # Regression tests for https://github.com/astral-sh/ruff/issues/11672
57 57 | test = 0x5

non_augmented_assignment.py:58:1: PLR6104 [*] Use `+=` to perform an augmented assignment directly
|
56 | # Regression tests for https://github.com/astral-sh/ruff/issues/11672
57 | test = 0x5
58 | test = test + 0xBA
| ^^^^^^^^^^^^^^^^^^ PLR6104
59 |
60 | test2 = b""
|
= help: Replace with augmented assignment

ℹ Unsafe fix
55 55 |
56 56 | # Regression tests for https://github.com/astral-sh/ruff/issues/11672
57 57 | test = 0x5
58 |-test = test + 0xBA
58 |+test += 0xBA
59 59 |
60 60 | test2 = b""
61 61 | test2 = test2 + b"\000"

non_augmented_assignment.py:61:1: PLR6104 [*] Use `+=` to perform an augmented assignment directly
|
60 | test2 = b""
61 | test2 = test2 + b"\000"
| ^^^^^^^^^^^^^^^^^^^^^^^ PLR6104
62 |
63 | test3 = ""
|
= help: Replace with augmented assignment

ℹ Unsafe fix
58 58 | test = test + 0xBA
59 59 |
60 60 | test2 = b""
61 |-test2 = test2 + b"\000"
61 |+test2 += b"\000"
62 62 |
63 63 | test3 = ""
64 64 | test3 = test3 + ( a := R""

non_augmented_assignment.py:64:1: PLR6104 [*] Use `+=` to perform an augmented assignment directly
|
63 | test3 = ""
64 | / test3 = test3 + ( a := R""
65 | | f"oo" )
| |__________________________________^ PLR6104
66 |
67 | test4 = []
|
= help: Replace with augmented assignment

ℹ Unsafe fix
61 61 | test2 = test2 + b"\000"
62 62 |
63 63 | test3 = ""
64 |-test3 = test3 + ( a := R""
64 |+test3 += ( a := R""
65 65 | f"oo" )
66 66 |
67 67 | test4 = []

non_augmented_assignment.py:68:1: PLR6104 [*] Use `+=` to perform an augmented assignment directly
|
67 | test4 = []
68 | / test4 = test4 + ( e
69 | | for e in
70 | | range(10)
71 | | )
| |___________________^ PLR6104
72 |
73 | test5 = test5 + (
|
= help: Replace with augmented assignment

ℹ Unsafe fix
65 65 | f"oo" )
66 66 |
67 67 | test4 = []
68 |-test4 = test4 + ( e
68 |+test4 += ( e
69 69 | for e in
70 70 | range(10)
71 71 | )

non_augmented_assignment.py:73:1: PLR6104 [*] Use `+=` to perform an augmented assignment directly
|
71 | )
72 |
73 | / test5 = test5 + (
74 | | 4
75 | | *
76 | | 10
77 | | )
| |_^ PLR6104
78 |
79 | test6 = test6 + \
|
= help: Replace with augmented assignment

ℹ Unsafe fix
70 70 | range(10)
71 71 | )
72 72 |
73 |-test5 = test5 + (
73 |+test5 += (
74 74 | 4
75 75 | *
76 76 | 10

non_augmented_assignment.py:79:1: PLR6104 [*] Use `+=` to perform an augmented assignment directly
|
77 | )
78 |
79 | / test6 = test6 + \
80 | | (
81 | | 4
82 | | *
83 | | 10
84 | | )
| |_________^ PLR6104
85 |
86 | test7 = \
|
= help: Replace with augmented assignment

ℹ Unsafe fix
76 76 | 10
77 77 | )
78 78 |
79 |-test6 = test6 + \
80 |- (
79 |+test6 += (
81 80 | 4
82 81 | *
83 82 | 10

non_augmented_assignment.py:86:1: PLR6104 [*] Use `+=` to perform an augmented assignment directly
|
84 | )
85 |
86 | / test7 = \
87 | | 100 \
88 | | + test7
| |___________^ PLR6104
89 |
90 | test8 = \
|
= help: Replace with augmented assignment

ℹ Unsafe fix
83 83 | 10
84 84 | )
85 85 |
86 |-test7 = \
87 |- 100 \
88 |- + test7
86 |+test7 += 100
89 87 |
90 88 | test8 = \
91 89 | 886 \

non_augmented_assignment.py:90:1: PLR6104 [*] Use `+=` to perform an augmented assignment directly
|
88 | + test7
89 |
90 | / test8 = \
91 | | 886 \
92 | | + \
93 | | \
94 | | test8
| |_________^ PLR6104
|
= help: Replace with augmented assignment

ℹ Unsafe fix
87 87 | 100 \
88 88 | + test7
89 89 |
90 |-test8 = \
91 |- 886 \
92 |- + \
93 |- \
94 |- test8
90 |+test8 += 886
95 91 |
96 92 |
97 93 | # OK
Loading
Loading