Skip to content

Commit c627b10

Browse files
committed
Fix augmented assignment evaluation
1 parent c00d7ba commit c627b10

File tree

6 files changed

+137
-8
lines changed

6 files changed

+137
-8
lines changed

graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/compiler/CompilerTests.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,16 @@ public void testAugAssignment() {
9595
doTest("a += 12.0");
9696
}
9797

98+
@Test
99+
public void testAugAssignmentAttr() {
100+
doTest("a.b += 12.0");
101+
}
102+
103+
@Test
104+
public void testAugAssignmentSubscr() {
105+
doTest("a[b] += 12.0");
106+
}
107+
98108
@Test
99109
public void testAnnAssignment() {
100110
doTest("a: int = 12");

graalpython/com.oracle.graal.python.test/src/tests/test_assign.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,71 @@ def test_destructuring():
105105
assert a == -1 and b == -1 and s == [0, 1, 2, 3, 4, 5, 6, 7] and c == 8 and d == 9
106106

107107

108+
def test_augassign_evaluation_subsc():
109+
calls = []
110+
111+
class C(list):
112+
def __getitem__(self, item):
113+
calls.append("get")
114+
return super().__getitem__(item)
115+
116+
def __setitem__(self, key, value):
117+
calls.append("set")
118+
super().__setitem__(key, value)
119+
120+
class I:
121+
def __iadd__(self, other):
122+
calls.append("iadd")
123+
return 3
124+
125+
def index():
126+
calls.append("index")
127+
return 0
128+
129+
def value():
130+
calls.append("value")
131+
return 1
132+
133+
x = C([I()])
134+
135+
def container():
136+
calls.append("container")
137+
return x
138+
139+
container()[index()] += value()
140+
assert calls == ["container", "index", "get", "value", "iadd", "set"]
141+
142+
143+
def test_augassign_evaluation_attr():
144+
calls = []
145+
146+
class C(list):
147+
def __getattr__(self, item):
148+
calls.append("get")
149+
return I()
150+
151+
def __setattr__(self, key, value):
152+
calls.append("set")
153+
154+
class I:
155+
def __iadd__(self, other):
156+
calls.append("iadd")
157+
return 3
158+
159+
def value():
160+
calls.append("value")
161+
return 1
162+
163+
x = C()
164+
165+
def container():
166+
calls.append("container")
167+
return x
168+
169+
container().attr += value()
170+
assert calls == ["container", "get", "value", "iadd", "set"]
171+
172+
108173
def test_assigning_hidden_keys():
109174
class A():
110175
def __init__(self):
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Disassembly of <module>:
2+
000000 0 LOAD_NAME 0 (a)
3+
000000 2 DUP_TOP
4+
000000 3 LOAD_ATTR 1 (b)
5+
000007 5 LOAD_DOUBLE_O 0 (12.0)
6+
000000 7 BINARY_OP 1 (INPLACE_ADD)
7+
000000 9 ROT_TWO
8+
000000 10 STORE_ATTR 1 (b)
9+
000000 12 LOAD_NONE
10+
000000 13 RETURN_VALUE
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Disassembly of <module>:
2+
000000 0 LOAD_NAME 0 (a)
3+
000000 2 DUP_TOP
4+
000002 3 LOAD_NAME 1 (b)
5+
000000 5 DUP_TOP
6+
000000 6 ROT_THREE
7+
000000 7 BINARY_SUBSCR
8+
000008 8 LOAD_DOUBLE_O 0 (12.0)
9+
000000 10 BINARY_OP 1 (INPLACE_ADD)
10+
000000 12 ROT_THREE
11+
000000 13 STORE_SUBSCR
12+
000000 14 LOAD_NONE
13+
000000 15 RETURN_VALUE

graalpython/com.oracle.graal.python.test/testData/goldenFiles/CompilerTests/testBenchmark.co

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ Disassembly of docompute:
4949
000183 71 LOAD_BYTE_I 1 can quicken
5050
000178 73 BINARY_OP 1 (INPLACE_ADD) can quicken, generalizes: 71, 69
5151
000178 75 STORE_FAST 3 (j) generalizes: 73
52-
000178 77 JUMP_BACKWARD 58 (to 19)
53-
000178 >> 79 JUMP_BACKWARD 72 (to 7)
52+
000086 77 JUMP_BACKWARD 58 (to 19)
53+
000086 >> 79 JUMP_BACKWARD 72 (to 7)
5454
000197 >> 81 LOAD_FAST 2 (sum_)
5555
000190 83 RETURN_VALUE
5656

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/Compiler.java

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@
140140
import java.util.List;
141141

142142
import com.oracle.graal.python.builtins.objects.PNone;
143-
import com.oracle.graal.python.pegparser.CopyWithContextVisitor;
144143
import com.oracle.graal.python.pegparser.ErrorCallback;
145144
import com.oracle.graal.python.pegparser.ErrorCallback.ErrorType;
146145
import com.oracle.graal.python.pegparser.FExprParser;
@@ -2020,11 +2019,30 @@ public Void visit(StmtTy.AsyncWith node) {
20202019

20212020
@Override
20222021
public Void visit(StmtTy.AugAssign node) {
2023-
SourceRange savedLocation = setLocation(node);
2024-
node.target.accept(new CopyWithContextVisitor(ExprContextTy.Load)).accept(this);
2025-
setLocation(savedLocation);
2026-
node.value.accept(this);
2022+
ExprTy target = node.target;
2023+
SourceRange savedLocation = setLocation(target);
2024+
if (target instanceof ExprTy.Attribute) {
2025+
ExprTy.Attribute attr = (ExprTy.Attribute) target;
2026+
attr.value.accept(this);
2027+
addOp(DUP_TOP);
2028+
addOpName(LOAD_ATTR, unit.names, attr.attr);
2029+
} else if (target instanceof ExprTy.Subscript) {
2030+
ExprTy.Subscript subscript = (ExprTy.Subscript) target;
2031+
subscript.value.accept(this);
2032+
addOp(DUP_TOP);
2033+
subscript.slice.accept(this);
2034+
addOp(DUP_TOP);
2035+
addOp(ROT_THREE);
2036+
addOp(BINARY_SUBSCR);
2037+
} else if (target instanceof ExprTy.Name) {
2038+
ExprTy.Name name = (ExprTy.Name) target;
2039+
addNameOp(name.id, ExprContextTy.Load);
2040+
} else {
2041+
// TODO this raises SystemError under CPython
2042+
throw new IllegalArgumentException("invalid node type for augmented assignment");
2043+
}
20272044
setLocation(node);
2045+
node.value.accept(this);
20282046
switch (node.op) {
20292047
case Add:
20302048
addOp(BINARY_OP, BinaryOps.INPLACE_ADD.ordinal());
@@ -2068,7 +2086,20 @@ public Void visit(StmtTy.AugAssign node) {
20682086
default:
20692087
throw new IllegalStateException("Unknown binary inplace operation " + node.op);
20702088
}
2071-
return node.target.accept(this);
2089+
setLocation(target);
2090+
if (target instanceof ExprTy.Attribute) {
2091+
ExprTy.Attribute attr = (ExprTy.Attribute) target;
2092+
addOp(ROT_TWO);
2093+
addOpName(STORE_ATTR, unit.names, attr.attr);
2094+
} else if (target instanceof ExprTy.Subscript) {
2095+
addOp(ROT_THREE);
2096+
addOp(STORE_SUBSCR);
2097+
} else {
2098+
ExprTy.Name name = (ExprTy.Name) target;
2099+
addNameOp(name.id, ExprContextTy.Store);
2100+
}
2101+
setLocation(savedLocation);
2102+
return null;
20722103
}
20732104

20742105
@Override

0 commit comments

Comments
 (0)