Skip to content

Commit 19cf265

Browse files
committed
[GR-23243] Make test_list pass
PullRequest: graalpython/1003
2 parents 395903b + 1bb1f66 commit 19cf265

File tree

9 files changed

+184
-25
lines changed

9 files changed

+184
-25
lines changed

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

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2018, Oracle and/or its affiliates.
1+
# Copyright (c) 2018, 2020, Oracle and/or its affiliates.
22
# Copyright (C) 1996-2017 Python Software Foundation
33
#
44
# Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
@@ -33,12 +33,11 @@ def test_init(self):
3333
self.assertNotEqual(id(a), id(b))
3434
self.assertEqual(a, b)
3535

36-
# TODO No assertRaiseRegex available
37-
# def test_getitem_error(self):
38-
# msg = "list indices must be integers or slices"
39-
# with self.assertRaisesRegex(TypeError, msg):
40-
# a = []
41-
# a['a'] = "python"
36+
def test_getitem_error(self):
37+
msg = "list indices must be integers or slices"
38+
with self.assertRaisesRegex(TypeError, msg):
39+
a = []
40+
a['a'] = "python"
4241

4342
def test_repr(self):
4443
l0 = []
@@ -133,10 +132,9 @@ def test_setitem(self):
133132
a[-1] = 9
134133
self.assertEqual(a, self.type2test([5,6,7,8,9]))
135134

136-
# TODO no assertRaisesRegex available now
137-
# msg = "list indices must be integers or slices"
138-
# with self.assertRaisesRegex(TypeError, msg):
139-
# a['a'] = "python"
135+
msg = "list indices must be integers or slices"
136+
with self.assertRaisesRegex(TypeError, msg):
137+
a['a'] = "python"
140138

141139
def test_delitem(self):
142140
a = self.type2test([0, 1])
@@ -309,10 +307,10 @@ def test_pop(self):
309307
self.assertEqual(a, [-1, 0])
310308
a.pop(0)
311309
self.assertEqual(a, [0])
312-
# self.assertRaises(IndexError, a.pop, 5)
310+
self.assertRaises(IndexError, a.pop, 5)
313311
a.pop(0)
314312
self.assertEqual(a, [])
315-
# self.assertRaises(IndexError, a.pop)
313+
self.assertRaises(IndexError, a.pop)
316314
self.assertRaises(TypeError, a.pop, 42, 42)
317315
a = self.type2test([0, 10, 20, 30, 40])
318316

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2018, Oracle and/or its affiliates.
1+
# Copyright (c) 2018, 2020, Oracle and/or its affiliates.
22
# Copyright (C) 1996-2017 Python Software Foundation
33
#
44
# Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
@@ -279,7 +279,7 @@ class subclass(self.type2test):
279279
pass
280280
u3 = subclass([0, 1])
281281
self.assertEqual(u3, u3*1)
282-
self.assertTrue(u3 is not u3*1)
282+
self.assertIsNot(u3, u3*1)
283283

284284
def test_iadd(self):
285285
u = self.type2test([0, 1])
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,87 @@
1+
*ListCompareTest.test_compare
2+
*ListCompareTest.test_equal_other
3+
*ListCompareTest.test_extendingClass
4+
*ListCompareTest.test_raiseTypeError
5+
*ListTest.test_StopIteration
6+
*ListTest.test_add
7+
*ListTest.test_addmul
8+
*ListTest.test_append
19
*ListTest.test_basic
210
*ListTest.test_count_index_remove_crashes
11+
*ListTest.test_clear
12+
*ListTest.test_constructor_exception_handling
13+
*ListTest.test_constructors
14+
*ListTest.test_contains
15+
*ListTest.test_copy
16+
*ListTest.test_count
17+
*ListTest.test_del_border
18+
*ListTest.test_del_item
19+
*ListTest.test_del_slice
20+
*ListTest.test_del_slice_step
21+
*ListTest.test_delitem
22+
*ListTest.test_delslice
23+
*ListTest.test_exhausted_iterator
24+
*ListTest.test_extend
25+
*ListTest.test_extend_bytearray
26+
*ListTest.test_extend_bytes
27+
*ListTest.test_extend_bytes_2
28+
*ListTest.test_extend_spec
29+
*ListTest.test_extendedslicing
30+
*ListTest.test_getitem
31+
*ListTest.test_getitemoverwriteiter
32+
*ListTest.test_getslice
33+
*ListTest.test_iadd
34+
*ListTest.test_iadd_special
335
*ListTest.test_identity
436
*ListTest.test_keyword_args
37+
*ListTest.test_imul
38+
*ListTest.test_imul_01
39+
*ListTest.test_imul_02
40+
*ListTest.test_imul_03
41+
*ListTest.test_imul_len
42+
*ListTest.test_index
43+
*ListTest.test_ininicialization_with_slice
44+
*ListTest.test_init
45+
*ListTest.test_init_extend_with_lying_list
46+
*ListTest.test_insert
47+
*ListTest.test_insert_spec
548
*ListTest.test_len
49+
*ListTest.test_literal
50+
*ListTest.test_minmax
651
*ListTest.test_no_comdat_folding
752
*ListTest.test_overflow
853
*ListTest.test_preallocation
54+
*ListTest.test_pop
55+
*ListTest.test_pop_boolean
56+
*ListTest.test_pop_border
57+
*ListTest.test_pop_double
58+
*ListTest.test_pop_int
59+
*ListTest.test_pop_long
60+
*ListTest.test_pop_mix
61+
*ListTest.test_pop_string
62+
*ListTest.test_remove
63+
*ListTest.test_remove_spec
64+
*ListTest.test_repr
965
*ListTest.test_repr_large
66+
*ListTest.test_setitem_error
67+
*ListTest.test_getitem_error
68+
*ListTest.test_reverse
69+
*ListTest.test_reversed
70+
*ListTest.test_set_slice
71+
*ListTest.test_set_slice_class_getitem
72+
*ListTest.test_set_slice_class_iter
73+
*ListTest.test_set_slice_generalize_storage
74+
*ListTest.test_set_strange_slice
75+
*ListTest.test_set_subscript
76+
*ListTest.test_setitem
77+
*ListTest.test_setslice
78+
*ListTest.test_slice
79+
*ListTest.test_sort
80+
*ListTest.test_subscript
1081
*ListTest.test_truth
82+
*ListTest.test_equal_operator_modifying_operand
83+
*ListTest.test_contains_fake
84+
*ListTest.test_contains_order
85+
*ListTest.test_repeat
86+
*ListTest.test_bigrepeat
87+
*ListTest.test_pickle

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public Object next(PBaseSetIterator self) {
142142
throw raise(StopIteration);
143143
}
144144

145-
@Specialization(guards = "self.isPSequence()")
145+
@Specialization(guards = {"self.isPSequence()"})
146146
public Object next(VirtualFrame frame, PSequenceIterator self,
147147
@Cached SequenceNodes.GetSequenceStorageNode getStorage,
148148
@Cached SequenceStorageNodes.LenNode lenNode,

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

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
import com.oracle.truffle.api.dsl.Specialization;
113113
import com.oracle.truffle.api.dsl.TypeSystemReference;
114114
import com.oracle.truffle.api.frame.VirtualFrame;
115+
import com.oracle.truffle.api.interop.InteropLibrary;
115116
import com.oracle.truffle.api.library.CachedLibrary;
116117
import com.oracle.truffle.api.nodes.UnexpectedResultException;
117118
import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -305,12 +306,20 @@ protected Object doGeneric(Object self, @SuppressWarnings("unused") Object objec
305306
@GenerateNodeFactory
306307
public abstract static class GetItemNode extends PythonBinaryBuiltinNode {
307308

308-
@Specialization
309+
@Specialization(guards = "lib.canBeIndex(key) || isPSlice(key)")
309310
protected Object doScalar(VirtualFrame frame, PList self, Object key,
310-
@Cached("createGetItemNode()") SequenceStorageNodes.GetItemNode getItemNode) {
311+
@Cached("createGetItemNode()") SequenceStorageNodes.GetItemNode getItemNode,
312+
@SuppressWarnings("unused") @CachedLibrary(limit = "1") PythonObjectLibrary lib) {
311313
return getItemNode.execute(frame, self.getSequenceStorage(), key);
312314
}
313315

316+
@SuppressWarnings("unused")
317+
@Specialization(guards = {"!lib.canBeIndex(key)", "!isPSlice(key)"})
318+
public Object doListError(VirtualFrame frame, PList primary, Object key,
319+
@CachedLibrary(limit = "1") PythonObjectLibrary lib) {
320+
throw raise(TypeError, ErrorMessages.OBJ_INDEX_MUST_BE_INT_OR_SLICES, "list", key);
321+
}
322+
314323
protected static SequenceStorageNodes.GetItemNode createGetItemNode() {
315324
return SequenceStorageNodes.GetItemNode.create(NormalizeIndexNode.forList(), (s, f) -> f.createList(s));
316325
}
@@ -332,13 +341,21 @@ public abstract static class SetItemNode extends PythonTernaryBuiltinNode {
332341

333342
private final ConditionProfile generalizedProfile = ConditionProfile.createBinaryProfile();
334343

335-
@Specialization
344+
@Specialization(guards = "lib.fitsInInt(key) || isPSlice(key)")
336345
public Object doGeneric(VirtualFrame frame, PList primary, Object key, Object value,
346+
@SuppressWarnings("unused") @CachedLibrary(limit = "3") InteropLibrary lib,
337347
@Cached("createSetItem()") SequenceStorageNodes.SetItemNode setItemNode) {
338348
updateStorage(primary, setItemNode.execute(frame, primary.getSequenceStorage(), key, value));
339349
return PNone.NONE;
340350
}
341351

352+
@SuppressWarnings("unused")
353+
@Specialization(guards = {"!lib.fitsInInt(key)", "!isPSlice(key)"})
354+
public Object doListError(VirtualFrame frame, PList primary, Object key, Object value,
355+
@CachedLibrary(limit = "1") InteropLibrary lib) {
356+
throw raise(TypeError, ErrorMessages.OBJ_INDEX_MUST_BE_INT_OR_SLICES, "list", key);
357+
}
358+
342359
@SuppressWarnings("unused")
343360
@Fallback
344361
protected Object doGeneric(Object self, Object objectIdx, Object value) {
@@ -917,12 +934,40 @@ abstract static class RMulNode extends MulNode {
917934
@GenerateNodeFactory
918935
abstract static class EqNode extends PythonBinaryBuiltinNode {
919936

920-
@Specialization
937+
protected static boolean isObjectStorage(PList left, PList right) {
938+
return PGuards.isObjectStorage(left) || PGuards.isObjectStorage(right);
939+
}
940+
941+
@Specialization(guards = "!isObjectStorage(left, right)")
921942
boolean doPList(VirtualFrame frame, PList left, PList right,
922943
@Cached("createEq()") SequenceStorageNodes.CmpNode neNode) {
923944
return neNode.execute(frame, left.getSequenceStorage(), right.getSequenceStorage());
924945
}
925946

947+
/**
948+
* This is a fix for the bpo-38588 bug. See
949+
* {@code test_list.py: ListTest.test_equal_operator_modifying_operand}
950+
*
951+
*/
952+
@Specialization(guards = "isObjectStorage(left, right)")
953+
boolean doPListObjectStorage(VirtualFrame frame, PList left, PList right,
954+
@Cached("createEq()") SequenceStorageNodes.CmpNode neNode) {
955+
final SequenceStorage leftStorage = left.getSequenceStorage();
956+
final SequenceStorage rightStorage = right.getSequenceStorage();
957+
final boolean result = neNode.execute(frame, leftStorage, rightStorage);
958+
/**
959+
* This will check if the underlying storage has been modified and if so, we do the
960+
* check again.
961+
*/
962+
if (leftStorage == left.getSequenceStorage() && rightStorage == right.getSequenceStorage()) {
963+
return result;
964+
}
965+
/**
966+
* To avoid possible infinite recursion case, we call the default specialization.
967+
*/
968+
return doPList(frame, left, right, neNode);
969+
}
970+
926971
@Fallback
927972
@SuppressWarnings("unused")
928973
boolean doOther(Object left, Object right) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/reversed/ReversedBuiltins.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2020, Oracle and/or its affiliates.
33
* Copyright (c) 2014, Regents of the University of California
44
*
55
* All rights reserved.
@@ -64,6 +64,7 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
6464
@Builtin(name = __NEXT__, minNumOfPositionalArgs = 1)
6565
@GenerateNodeFactory
6666
public abstract static class NextNode extends PythonUnaryBuiltinNode {
67+
6768
@Specialization
6869
Object next(VirtualFrame frame, PSequenceReverseIterator self,
6970
@Cached("create(__GETITEM__)") LookupAndCallBinaryNode callGetItem,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/TupleBuiltins.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
import com.oracle.graal.python.builtins.objects.slice.PSlice;
6868
import com.oracle.graal.python.builtins.objects.str.PString;
6969
import com.oracle.graal.python.nodes.ErrorMessages;
70+
import com.oracle.graal.python.nodes.PGuards;
7071
import com.oracle.graal.python.nodes.argument.ReadArgumentNode;
7172
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
7273
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
@@ -516,9 +517,24 @@ Object doGeneric(@SuppressWarnings("unused") Object left, Object right) {
516517
@Builtin(name = __MUL__, minNumOfPositionalArgs = 2)
517518
@GenerateNodeFactory
518519
abstract static class MulNode extends PythonBuiltinNode {
519-
@Specialization
520+
521+
protected static boolean isSingleRepeat(PTuple left, PythonObjectLibrary tuplelib, Object right, PythonObjectLibrary lib) {
522+
return PGuards.isPythonBuiltinClassType(tuplelib.getLazyPythonClass(left)) && lib.canBeIndex(right) && lib.asSize(right) == 1;
523+
}
524+
525+
@SuppressWarnings("unused")
526+
@Specialization(guards = "isSingleRepeat(left, tuplelib, right, lib)")
527+
PTuple doPTupleSingleRepeat(VirtualFrame frame, PTuple left, Object right,
528+
@CachedLibrary(limit = "3") PythonObjectLibrary tuplelib,
529+
@CachedLibrary(limit = "3") PythonObjectLibrary lib) {
530+
return left;
531+
}
532+
533+
@Specialization(guards = "!isSingleRepeat(left, tuplelib, right, lib)")
520534
PTuple mul(VirtualFrame frame, PTuple left, Object right,
521-
@Cached("create()") SequenceStorageNodes.RepeatNode repeatNode) {
535+
@Cached("create()") SequenceStorageNodes.RepeatNode repeatNode,
536+
@SuppressWarnings("unused") @CachedLibrary(limit = "3") PythonObjectLibrary tuplelib,
537+
@SuppressWarnings("unused") @CachedLibrary(limit = "3") PythonObjectLibrary lib) {
522538
return factory().createTuple(repeatNode.execute(frame, left.getSequenceStorage(), right));
523539
}
524540
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ public abstract class ErrorMessages {
341341
public static final String NOT_ENOUGH_VALUES_TO_UNPACK = "not enough values to unpack (expected %d, got %d)";
342342
public static final String NOT_SUPPORTED_BETWEEN_INSTANCES = "'%s' not supported between instances of '%p' and '%p'";
343343
public static final String NUMBER_S_CANNOT_FIT_INTO_INDEXSIZED_INT = "number %s cannot fit into index-sized integer";
344+
public static final String OBJ_INDEX_MUST_BE_INT_OR_SLICES = "%s indices must be integers or slices, not %p";
344345
public static final String OBJ_CANNOT_BE_INTERPRETED_AS_INT = "%s cannot be interpreted as int (type %p)";
345346
public static final String OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER = "'%p' object cannot be interpreted as an int";
346347
public static final String OBJ_DOES_NOT_SUPPORT_INDEXING = "'%s' object does not support indexing";

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/subscript/GetItemNode.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@
3333
import com.oracle.graal.python.builtins.objects.common.IndexNodes.NormalizeIndexNode;
3434
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
3535
import com.oracle.graal.python.builtins.objects.list.PList;
36+
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
3637
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
3738
import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass;
39+
import com.oracle.graal.python.nodes.ErrorMessages;
3840
import com.oracle.graal.python.nodes.PRaiseNode;
3941
import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
4042
import com.oracle.graal.python.nodes.call.CallNode;
@@ -50,6 +52,7 @@
5052
import com.oracle.truffle.api.dsl.Cached;
5153
import com.oracle.truffle.api.dsl.Specialization;
5254
import com.oracle.truffle.api.frame.VirtualFrame;
55+
import com.oracle.truffle.api.library.CachedLibrary;
5356
import com.oracle.truffle.api.nodes.NodeInfo;
5457

5558
@NodeInfo(shortName = __GETITEM__)
@@ -89,20 +92,38 @@ public StatementNode makeWriteNode(ExpressionNode rhs) {
8992
return SetItemNode.create(getPrimary(), getSlice(), rhs);
9093
}
9194

92-
@Specialization(guards = "isBuiltinList.profileIsAnyBuiltinObject(primary)")
95+
@Specialization(guards = {"lib.canBeIndex(index) || isPSlice(index)", "isBuiltinList.profileIsAnyBuiltinObject(primary)"})
9396
Object doBuiltinList(VirtualFrame frame, PList primary, Object index,
97+
@SuppressWarnings("unused") @CachedLibrary(limit = "3") PythonObjectLibrary lib,
9498
@Cached("createGetItemNodeForList()") SequenceStorageNodes.GetItemNode getItemNode,
9599
@SuppressWarnings("unused") @Cached IsBuiltinClassProfile isBuiltinList) {
96100
return getItemNode.execute(frame, primary.getSequenceStorage(), index);
97101
}
98102

99-
@Specialization(guards = "isBuiltinTuple.profileIsAnyBuiltinObject(primary)")
103+
@SuppressWarnings("unused")
104+
@Specialization(guards = {"!lib.canBeIndex(index)", "!isPSlice(index)"})
105+
public Object doListError(VirtualFrame frame, PList primary, Object index,
106+
@CachedLibrary(limit = "1") PythonObjectLibrary lib,
107+
@Cached PRaiseNode raiseNode) {
108+
throw raiseNode.raise(TypeError, ErrorMessages.OBJ_INDEX_MUST_BE_INT_OR_SLICES, "list", index);
109+
}
110+
111+
@Specialization(guards = {"lib.canBeIndex(index) || isPSlice(index)", "isBuiltinTuple.profileIsAnyBuiltinObject(primary)"})
100112
Object doBuiltinTuple(VirtualFrame frame, PTuple primary, Object index,
113+
@SuppressWarnings("unused") @CachedLibrary(limit = "3") PythonObjectLibrary lib,
101114
@Cached("createGetItemNodeForTuple()") SequenceStorageNodes.GetItemNode getItemNode,
102115
@SuppressWarnings("unused") @Cached IsBuiltinClassProfile isBuiltinTuple) {
103116
return getItemNode.execute(frame, primary.getSequenceStorage(), index);
104117
}
105118

119+
@SuppressWarnings("unused")
120+
@Specialization(guards = {"!lib.canBeIndex(index)", "!isPSlice(index)"})
121+
public Object doTupleError(VirtualFrame frame, PTuple primary, Object index,
122+
@CachedLibrary(limit = "1") PythonObjectLibrary lib,
123+
@Cached PRaiseNode raiseNode) {
124+
throw raiseNode.raise(TypeError, ErrorMessages.OBJ_INDEX_MUST_BE_INT_OR_SLICES, "tuple", index);
125+
}
126+
106127
@Specialization(replaces = {"doBuiltinList", "doBuiltinTuple"})
107128
Object doAnyObject(VirtualFrame frame, Object primary, Object index) {
108129
if (callGetitemNode == null) {

0 commit comments

Comments
 (0)