Skip to content

Commit 192c4d1

Browse files
committed
[GR-9677] Method insert of list returns wrong time and raise IndexOutOfBound.
PullRequest: graalpython-open/31
2 parents edbb1bd + e24b62d commit 192c4d1

File tree

3 files changed

+136
-10
lines changed

3 files changed

+136
-10
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: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,36 @@ 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)
308+
309+
a = [0]
310+
a.insert(LONG_NUMBER, 1)
311+
self.assertEqual([0,1], a)
312+
313+
a.insert(False, -1)
314+
self.assertEqual([-1,0,1], a)

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

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

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+
target.insertIntItem(normalizeIndex(index, list.len()), value);
511+
return PNone.NONE;
512+
}
513+
514+
@Specialization(guards = "isLongStorage(list)")
515+
public PNone insertLongLong(PList list, int index, int value) {
516+
LongSequenceStorage target = (LongSequenceStorage) list.getSequenceStorage();
517+
target.insertLongItem(normalizeIndex(index, list.len()), value);
518+
return PNone.NONE;
519+
}
520+
521+
@Specialization(guards = "isLongStorage(list)")
522+
public PNone insertLongLong(PList list, int index, long value) {
523+
LongSequenceStorage target = (LongSequenceStorage) list.getSequenceStorage();
524+
target.insertLongItem(normalizeIndex(index, list.len()), value);
525+
return PNone.NONE;
526+
}
527+
528+
@Specialization(guards = "isDoubleStorage(list)")
529+
public PNone insertDoubleDouble(PList list, int index, double value) {
530+
DoubleSequenceStorage target = (DoubleSequenceStorage) list.getSequenceStorage();
531+
target.insertDoubleItem(normalizeIndex(index, list.len()), value);
532+
return PNone.NONE;
533+
}
534+
535+
@Specialization(guards = "isNotSpecialCase(list, value)")
536+
public PNone insert(PList list, int index, Object value) {
537+
list.insert(normalizeIndex(index, list.len()), value);
538+
return PNone.NONE;
539+
}
540+
505541
@Specialization
506-
public PList insert(PList list, int index, Object value) {
507-
list.insert(index, value);
508-
return list;
542+
public PNone insertLongIndex(PList list, long index, Object value,
543+
@Cached("createListInsertNode()") ListInsertNode insertNode) {
544+
int where = index < Integer.MIN_VALUE ? 0 : index > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) index;
545+
where = normalizeIndex(where, list.len());
546+
return insertNode.execute(list, where, value);
509547
}
510548

511549
@Specialization
512-
@SuppressWarnings("unused")
513-
public PList insert(PList list, Object i, Object arg1) {
514-
throw new RuntimeException("invalid arguments for insert()");
550+
public PNone insertPIntIndex(PList list, PInt index, Object value,
551+
@Cached("createListInsertNode()") ListInsertNode insertNode) {
552+
int where = normalizePIntForIndex(index);
553+
where = normalizeIndex(where, list.len());
554+
return insertNode.execute(list, where, value);
555+
}
556+
557+
@Specialization(guards = {"!isIntegerOrPInt(i)"})
558+
public PNone insert(PList list, Object i, Object value,
559+
@Cached("create(__INDEX__)") LookupAndCallUnaryNode indexNode,
560+
@Cached("createListInsertNode()") ListInsertNode insertNode) {
561+
Object indexValue = indexNode.executeObject(i);
562+
if (PNone.NO_VALUE == indexValue) {
563+
throw raise(TypeError, "'%p' object cannot be interpreted as an integer", i);
564+
}
565+
return insertNode.execute(list, indexValue, value);
566+
}
567+
568+
@TruffleBoundary
569+
private static int normalizePIntForIndex(PInt index) {
570+
int where = 0;
571+
BigInteger bigIndex = index.getValue();
572+
if (bigIndex.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) == -1) {
573+
where = 0;
574+
} else if (bigIndex.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) == 1) {
575+
where = Integer.MAX_VALUE;
576+
} else {
577+
where = bigIndex.intValue();
578+
}
579+
return where;
580+
}
581+
582+
private static int normalizeIndex(int index, int len) {
583+
int idx = index;
584+
if (idx < 0) {
585+
idx += len;
586+
if (idx < 0) {
587+
idx = 0;
588+
}
589+
}
590+
if (idx > len) {
591+
idx = len;
592+
}
593+
return idx;
594+
}
595+
596+
protected boolean isNotSpecialCase(PList list, Object value) {
597+
return !((PGuards.isIntStorage(list) && value instanceof Integer) || (PGuards.isLongStorage(list) && PGuards.isInteger(value)) ||
598+
(PGuards.isDoubleStorage(list) && value instanceof Double));
515599
}
600+
601+
protected boolean isIntegerOrPInt(Object index) {
602+
return index instanceof Integer || index instanceof PInt;
603+
}
604+
605+
protected ListInsertNode createListInsertNode() {
606+
return ListBuiltinsFactory.ListInsertNodeFactory.create(new PNode[0]);
607+
}
608+
516609
}
517610

518611
// list.remove(x)

0 commit comments

Comments
 (0)