Skip to content

Commit 2a0a88d

Browse files
committed
Fix: set slice did use iterable twice.
1 parent 87942e1 commit 2a0a88d

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,10 @@ def test_set_slice(self):
372372
self.assertEqual([1, 2, 3, 4], a)
373373
else:
374374
assert False, "expected ValueError"
375+
376+
a = [1, 2, 3, 4]
377+
a[:] = map(next, [iter([None,]), iter([None,])])
378+
self.assertEqual([None, None], a)
375379

376380

377381
def test_set_slice_class_iter(self):

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceStorageNodes.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,15 +1021,19 @@ protected static SequenceStorage doScalarGeneric(GenNodeSupplier generalizationN
10211021
protected static SequenceStorage doSlice(GenNodeSupplier generalizationNodeProvider, SequenceStorage storage, PSlice slice, Object iterable,
10221022
@Shared("generalizeProfile") @Cached BranchProfile generalizeProfile,
10231023
@Cached SetItemSliceNode setItemSliceNode,
1024-
@Shared("doGenNode") @Cached DoGeneralizationNode doGenNode) {
1024+
@Shared("doGenNode") @Cached DoGeneralizationNode doGenNode,
1025+
@Cached ListNodes.ConstructListNode constructListNode) {
10251026
SliceInfo info = slice.computeIndices(storage.length());
1027+
// We need to construct the list eagerly because if a SequenceStoreException occurs, we
1028+
// must not use iterable again. It could have sice-effects.
1029+
PList values = constructListNode.execute(iterable);
10261030
try {
1027-
setItemSliceNode.execute(storage, info, iterable);
1031+
setItemSliceNode.execute(storage, info, values);
10281032
return storage;
10291033
} catch (SequenceStoreException e) {
10301034
generalizeProfile.enter();
10311035
SequenceStorage generalized = doGenNode.execute(generalizationNodeProvider, storage, e.getIndicationValue());
1032-
setItemSliceNode.execute(generalized, info, iterable);
1036+
setItemSliceNode.execute(generalized, info, values);
10331037
return generalized;
10341038
}
10351039
}
@@ -1158,15 +1162,20 @@ protected SequenceStorage doScalarGeneric(SequenceStorage storage, Object idx, O
11581162
@Specialization
11591163
protected SequenceStorage doSlice(SequenceStorage storage, PSlice slice, Object iterable,
11601164
@Shared("generalizeProfile") @Cached BranchProfile generalizeProfile,
1161-
@Cached SetItemSliceNode setItemSliceNode) {
1165+
@Cached SetItemSliceNode setItemSliceNode,
1166+
@Cached ListNodes.ConstructListNode constructListNode) {
11621167
SliceInfo info = slice.computeIndices(storage.length());
1168+
1169+
// We need to construct the list eagerly because if a SequenceStoreException occurs, we
1170+
// must not use iterable again. It could have sice-effects.
1171+
PList values = constructListNode.execute(iterable);
11631172
try {
1164-
setItemSliceNode.execute(storage, info, iterable);
1173+
setItemSliceNode.execute(storage, info, values);
11651174
return storage;
11661175
} catch (SequenceStoreException e) {
11671176
generalizeProfile.enter();
11681177
SequenceStorage generalized = generalizeStore(storage, e.getIndicationValue());
1169-
setItemSliceNode.execute(generalized, info, iterable);
1178+
setItemSliceNode.execute(generalized, info, values);
11701179
return generalized;
11711180
}
11721181
}

0 commit comments

Comments
 (0)