Skip to content

Commit 46d6f2f

Browse files
committed
[GR-9677] Method insert of list returns wrong time and raise IndexOutOfBound.
1 parent c5885b3 commit 46d6f2f

File tree

3 files changed

+110
-9
lines changed

3 files changed

+110
-9
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ def __length_hint__(self):
288288
a = self.type2test([1,2,3,4])
289289
a.extend(CustomIter())
290290
self.assertEqual(a, [1,2,3,4])
291-
291+
'''
292292
def test_insert(self):
293293
a = self.type2test([0, 1, 2])
294294
a.insert(0, -2)
@@ -298,12 +298,12 @@ def test_insert(self):
298298

299299
b = a[:]
300300
b.insert(-2, "foo")
301-
b.insert(-200, "left")e
302-
b.intert(200, "right")
301+
b.insert(-200, "left")
302+
b.insert(200, "right")
303303
self.assertEqual(b, self.type2test(["left",-2,-1,0,0,"foo",1,2,"right"]))
304304

305305
self.assertRaises(TypeError, a.insert)
306-
'''
306+
307307
def test_pop(self):
308308
a = self.type2test([-1, 0, 1])
309309
a.pop()

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,29 @@ def test_set_slice_generalize_storage(self):
279279
a = [1,2]
280280
a[1:5] = [1.1, 2.2, 3.3]
281281
self.assertEqual([1,1.1, 2.2, 3.3], a)
282+
283+
def test_insert_spec(self):
284+
a = [1,2]
285+
self.assertRaises(TypeError, a.insert, [1,2,3], 1)
286+
287+
class MyInt(int):
288+
pass
289+
290+
a = [2,4]
291+
a.insert(MyInt(1),3)
292+
self.assertEqual([2,3,4], a)
293+
294+
class MyIndex():
295+
def __index__(self):
296+
return 2
297+
298+
a.insert(MyIndex(), 7)
299+
self.assertEqual([2,3,7,4], a)
300+
301+
class SecondIndex(int):
302+
def __index__(self):
303+
return self + 3;
304+
305+
a = [0,0,0,0,0]
306+
a.insert(SecondIndex(1), 1)
307+
self.assertEqual([0,1,0,0,0,0], a)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/list/ListBuiltins.java

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -502,17 +502,92 @@ public PList extend(PList list, Object source,
502502
@GenerateNodeFactory
503503
public abstract static class ListInsertNode extends PythonBuiltinNode {
504504

505-
@Specialization
506-
public PList insert(PList list, int index, Object value) {
505+
public abstract PNone execute(PList list, Object index, Object value);
506+
507+
@Specialization(guards = "isIntStorage(list)")
508+
public PNone insertIntInt(PList list, int index, int value) {
509+
IntSequenceStorage target = (IntSequenceStorage) list.getSequenceStorage();
510+
index = normalizeIndex(index, list.len());
511+
target.insertIntItem(index, value);
512+
return PNone.NONE;
513+
}
514+
515+
@Specialization(guards = "isLongStorage(list)")
516+
public PNone insertLongLong(PList list, int index, int value) {
517+
LongSequenceStorage target = (LongSequenceStorage) list.getSequenceStorage();
518+
index = normalizeIndex(index, list.len());
519+
target.insertLongItem(index, value);
520+
return PNone.NONE;
521+
}
522+
523+
@Specialization(guards = "isLongStorage(list)")
524+
public PNone insertLongLong(PList list, int index, long value) {
525+
LongSequenceStorage target = (LongSequenceStorage) list.getSequenceStorage();
526+
index = normalizeIndex(index, list.len());
527+
target.insertLongItem(index, value);
528+
return PNone.NONE;
529+
}
530+
531+
@Specialization(guards = "isDoubleStorage(list)")
532+
public PNone insertDoubleDouble(PList list, int index, double value) {
533+
DoubleSequenceStorage target = (DoubleSequenceStorage) list.getSequenceStorage();
534+
index = normalizeIndex(index, list.len());
535+
target.insertDoubleItem(index, value);
536+
return PNone.NONE;
537+
}
538+
539+
@Specialization(guards = "isNotSpecialCase(list, value)")
540+
public PNone insert(PList list, int index, Object value) {
541+
index = normalizeIndex(index, list.len());
507542
list.insert(index, value);
508-
return list;
543+
return PNone.NONE;
509544
}
510545

511546
@Specialization
547+
public PNone insert(PList list, PInt index, Object value) {
548+
int where = normalizeIndex(index.intValue(), list.len());
549+
list.insert(where, value);
550+
return PNone.NONE;
551+
}
552+
553+
@Specialization(guards = {"!isIntegerOrPInt(i)"})
512554
@SuppressWarnings("unused")
513-
public PList insert(PList list, Object i, Object arg1) {
514-
throw new RuntimeException("invalid arguments for insert()");
555+
public PNone insert(PList list, Object i, Object value,
556+
@Cached("create(__INDEX__)") LookupAndCallUnaryNode indexNode,
557+
@Cached("createListInsertNode()") ListInsertNode insertNode) {
558+
Object indexValue = indexNode.executeObject(i);
559+
if (PNone.NO_VALUE == indexValue) {
560+
throw raise(TypeError, "'%p' object cannot be interpreted as an integer", i);
561+
}
562+
return insertNode.execute(list, indexValue, value);
563+
}
564+
565+
private int normalizeIndex(int index, int len) {
566+
if (index < 0) {
567+
index += len;
568+
if (index < 0) {
569+
index = 0;
570+
}
571+
}
572+
if (index > len) {
573+
index = len;
574+
}
575+
return index;
515576
}
577+
578+
protected boolean isNotSpecialCase(PList list, Object value) {
579+
return !((PGuards.isIntStorage(list) && value instanceof Integer) || (PGuards.isLongStorage(list) && PGuards.isInteger(value)) ||
580+
(PGuards.isDoubleStorage(list) && value instanceof Double));
581+
}
582+
583+
protected boolean isIntegerOrPInt(Object index) {
584+
return index instanceof Integer || index instanceof PInt;
585+
}
586+
587+
protected ListInsertNode createListInsertNode() {
588+
return ListBuiltinsFactory.ListInsertNodeFactory.create(new PNode[0]);
589+
}
590+
516591
}
517592

518593
// list.remove(x)

0 commit comments

Comments
 (0)