Skip to content

Commit f041def

Browse files
committed
[GR-10027] List.__init__ is not supported.
1 parent 929eb43 commit f041def

File tree

6 files changed

+130
-36
lines changed

6 files changed

+130
-36
lines changed

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,17 @@ def test_init(self):
2121
# Init clears previous values
2222
a = self.type2test([1, 2, 3])
2323
a.__init__()
24-
# XXX We need to implement __init__ node?
25-
# self.assertEqual(a, self.type2test([]))
24+
self.assertEqual(a, self.type2test([]))
2625

2726
# Init overwrites previous values
2827
a = self.type2test([1, 2, 3])
2928
a.__init__([4, 5, 6])
30-
# self.assertEqual(a, self.type2test([4, 5, 6]))
29+
self.assertEqual(a, self.type2test([4, 5, 6]))
3130

3231
# Mutables always return a new object
3332
b = self.type2test(a)
34-
# self.assertNotEqual(id(a), id(b))
35-
# self.assertEqual(a, b)
33+
self.assertNotEqual(id(a), id(b))
34+
self.assertEqual(a, b)
3635

3736
# TODO No assertRaiseRegex available
3837
# def test_getitem_error(self):

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,45 @@ def test_append(self):
646646
l.append("d")
647647
self.assertEqual(l, ["a", "b", "c", "d"])
648648

649+
def test_extend_bytes_2(self):
650+
b = bytes([3,4,255])
651+
l = [1,2]
652+
l.extend(b)
653+
self.assertEqual(l, [1,2,3,4,255])
654+
655+
def test_extend_bytearray(self):
656+
b = bytearray([3,4,255])
657+
l = [1,2]
658+
l.extend(b)
659+
self.assertEqual(l, [1,2,3,4,255])
660+
661+
def test_init_extend_with_lying_list(self):
662+
class LyingList(list):
663+
def __iter__(self):
664+
return iter([10, 20, 30, 40])
665+
666+
l = LyingList([1,2,3,4])
667+
self.assertEqual([1,2,3,4], l)
668+
669+
ll = list(l)
670+
self.assertEqual([10,20,30,40], ll)
671+
672+
ll = list(LyingList([1.0, 5.6, 7.7]))
673+
self.assertEqual([10,20,30,40], ll)
674+
675+
a = [1,0]
676+
a.extend(l)
677+
self.assertEqual([1,0,10,20,30,40], a)
678+
679+
a = [1,0]
680+
a.extend(ll)
681+
self.assertEqual([1,0,10,20,30,40], a)
682+
683+
ll.extend(ll)
684+
self.assertEqual([10,20,30,40,10,20,30,40], ll)
685+
686+
l.extend(l)
687+
self.assertEqual([1,2,3,4,10,20,30,40], l)
649688

650689
class ListCompareTest(CompareTest):
651690

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@
109109
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
110110
import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode;
111111
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
112-
import com.oracle.graal.python.nodes.builtins.ListNodes.ConstructListNode;
113112
import com.oracle.graal.python.nodes.builtins.TupleNodes;
114113
import com.oracle.graal.python.nodes.call.CallDispatchNode;
115114
import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode;
@@ -1209,9 +1208,8 @@ public boolean bool(Object cls, Object obj,
12091208
public abstract static class ListNode extends PythonBinaryBuiltinNode {
12101209

12111210
@Specialization
1212-
protected PList constructList(PythonClass cls, Object value,
1213-
@Cached("create()") ConstructListNode constructListNode) {
1214-
return constructListNode.execute(cls, value);
1211+
protected PList constructList(PythonClass cls, @SuppressWarnings("unused") Object value) {
1212+
return factory().createList(cls);
12151213
}
12161214

12171215
@Fallback

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@
8989
import com.oracle.graal.python.builtins.objects.slice.PSlice.SliceInfo;
9090
import com.oracle.graal.python.builtins.objects.str.PString;
9191
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
92+
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
93+
import com.oracle.graal.python.nodes.PGuards;
9294
import com.oracle.graal.python.nodes.PNodeWithContext;
9395
import com.oracle.graal.python.nodes.SpecialMethodNames;
9496
import com.oracle.graal.python.nodes.builtins.ListNodes;
@@ -97,6 +99,7 @@
9799
import com.oracle.graal.python.nodes.datamodel.IsIndexNode;
98100
import com.oracle.graal.python.nodes.expression.BinaryComparisonNode;
99101
import com.oracle.graal.python.nodes.expression.CastToBooleanNode;
102+
import com.oracle.graal.python.nodes.object.GetLazyClassNode;
100103
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
101104
import com.oracle.graal.python.nodes.util.CastToIndexNode;
102105
import com.oracle.graal.python.runtime.exception.PException;
@@ -2038,6 +2041,7 @@ public static ConcatNode create(Supplier<GeneralizationNode> genNodeProvider) {
20382041
}
20392042
}
20402043

2044+
@ImportStatic(PGuards.class)
20412045
public abstract static class ExtendNode extends SequenceStorageBaseNode {
20422046
@Child private CreateEmptyNode createEmptyNode = CreateEmptyNode.create();
20432047
@Child private GeneralizationNode genNode;
@@ -2050,7 +2054,17 @@ public ExtendNode(Supplier<GeneralizationNode> genNodeProvider) {
20502054

20512055
public abstract SequenceStorage execute(SequenceStorage s, Object iterable);
20522056

2053-
@Specialization(guards = "hasStorage(seq)")
2057+
@Child private GetLazyClassNode getClassNode;
2058+
2059+
protected LazyPythonClass getClass(Object value) {
2060+
if (getClassNode == null) {
2061+
CompilerDirectives.transferToInterpreterAndInvalidate();
2062+
getClassNode = insert(GetLazyClassNode.create());
2063+
}
2064+
return getClassNode.execute(value);
2065+
}
2066+
2067+
@Specialization(guards = {"hasStorage(seq)", "cannotBeOverridden(getClass(seq))"})
20542068
SequenceStorage doWithStorage(SequenceStorage s, PSequence seq,
20552069
@Cached("createClassProfile()") ValueProfile leftProfile,
20562070
@Cached("createClassProfile()") ValueProfile rightProfile,
@@ -2075,7 +2089,7 @@ SequenceStorage doWithStorage(SequenceStorage s, PSequence seq,
20752089
}
20762090
}
20772091

2078-
@Specialization(guards = "!hasStorage(iterable)")
2092+
@Specialization(guards = "!hasStorage(iterable) || !cannotBeOverridden(getClass(iterable))")
20792093
SequenceStorage doWithoutStorage(SequenceStorage s, Object iterable,
20802094
@Cached("create()") GetIteratorNode getIteratorNode,
20812095
@Cached("create()") GetNextNode getNextNode,

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

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import static com.oracle.graal.python.nodes.SpecialMethodNames.__HASH__;
3737
import static com.oracle.graal.python.nodes.SpecialMethodNames.__IADD__;
3838
import static com.oracle.graal.python.nodes.SpecialMethodNames.__IMUL__;
39+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__INIT__;
3940
import static com.oracle.graal.python.nodes.SpecialMethodNames.__ITER__;
4041
import static com.oracle.graal.python.nodes.SpecialMethodNames.__LEN__;
4142
import static com.oracle.graal.python.nodes.SpecialMethodNames.__LE__;
@@ -72,20 +73,18 @@
7273
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
7374
import com.oracle.graal.python.nodes.PGuards;
7475
import com.oracle.graal.python.nodes.argument.ReadArgumentNode;
76+
import com.oracle.graal.python.nodes.builtins.ListNodes.CreateStorageFromIteratorNode;
7577
import com.oracle.graal.python.nodes.builtins.ListNodes.IndexNode;
7678
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
7779
import com.oracle.graal.python.nodes.control.GetIteratorNode;
78-
import com.oracle.graal.python.nodes.control.GetNextNode;
7980
import com.oracle.graal.python.nodes.expression.BinaryComparisonNode;
8081
import com.oracle.graal.python.nodes.expression.CastToBooleanNode;
8182
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
8283
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
8384
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
8485
import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
8586
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
86-
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
8787
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
88-
import com.oracle.graal.python.runtime.exception.PException;
8988
import com.oracle.graal.python.runtime.exception.PythonErrorType;
9089
import com.oracle.graal.python.runtime.sequence.PSequence;
9190
import com.oracle.graal.python.runtime.sequence.storage.DoubleSequenceStorage;
@@ -121,23 +120,15 @@ public abstract static class ReprNode extends PythonUnaryBuiltinNode {
121120

122121
@Specialization
123122
@TruffleBoundary
124-
public Object repr(Object self,
125-
@Cached("create(__REPR__)") LookupAndCallUnaryNode repr,
126-
@Cached("create()") GetIteratorNode getIterator,
127-
@Cached("create()") GetNextNode next,
128-
@Cached("create()") IsBuiltinClassProfile errorProfile) {
123+
public Object repr(PList self,
124+
@Cached("create(__REPR__)") LookupAndCallUnaryNode repr) {
129125
StringBuilder result = new StringBuilder("[");
130-
Object iterator = getIterator.executeWith(self);
126+
SequenceStorage storage = self.getSequenceStorage();
131127
boolean initial = true;
132-
while (true) {
133-
Object value;
134-
try {
135-
value = next.execute(iterator);
136-
} catch (PException e) {
137-
e.expectStopIteration(errorProfile);
138-
return result.append(']').toString();
139-
}
140-
Object reprString;
128+
Object value;
129+
Object reprString;
130+
for (int index = 0; index < storage.length(); index++) {
131+
value = storage.getItemNormalized(index);
141132
if (self != value) {
142133
reprString = repr.executeObject(value);
143134
if (reprString instanceof PString) {
@@ -157,9 +148,57 @@ public Object repr(Object self,
157148
raise(PythonErrorType.TypeError, "__repr__ returned non-string (type %s)", reprString);
158149
}
159150
}
151+
return result.append("]").toString();
160152
}
161153
}
162154

155+
@Builtin(name = __INIT__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2)
156+
@TypeSystemReference(PythonArithmeticTypes.class)
157+
@GenerateNodeFactory
158+
public abstract static class ListInitNode extends PythonBinaryBuiltinNode {
159+
160+
public abstract PNone execute(PList list, Object source);
161+
162+
@Specialization
163+
public PNone init(PList list, String value,
164+
@Cached("create()") ListAppendNode appendNode) {
165+
clearStorage(list);
166+
char[] chars = value.toCharArray();
167+
for (char c : chars) {
168+
appendNode.execute(list, Character.toString(c));
169+
}
170+
return PNone.NONE;
171+
}
172+
173+
@Specialization(guards = "isNoValue(none)")
174+
@SuppressWarnings("unused")
175+
public PNone init(PList list, PNone none) {
176+
clearStorage(list);
177+
return PNone.NONE;
178+
}
179+
180+
@Specialization(guards = {"!isNoValue(iterable)", "!isString(iterable)"})
181+
public PNone listIterable(PList list, Object iterable,
182+
@Cached("create()") GetIteratorNode getIteratorNode,
183+
@Cached("create()") CreateStorageFromIteratorNode storageNode) {
184+
clearStorage(list);
185+
Object iterObj = getIteratorNode.executeWith(iterable);
186+
list.setSequenceStorage(storageNode.execute(iterObj));
187+
return PNone.NONE;
188+
}
189+
190+
private static void clearStorage(PList list) {
191+
if (EmptySequenceStorage.INSTANCE != list.getSequenceStorage()) {
192+
list.setSequenceStorage(EmptySequenceStorage.INSTANCE);
193+
}
194+
}
195+
196+
protected boolean isPSequence(Object value) {
197+
return value instanceof PSequence;
198+
}
199+
200+
}
201+
163202
@Builtin(name = __DELITEM__, fixedNumOfPositionalArgs = 2)
164203
@TypeSystemReference(PythonArithmeticTypes.class)
165204
@GenerateNodeFactory
@@ -287,6 +326,10 @@ private static void updateSequenceStorage(PList list, SequenceStorage s) {
287326
protected static SequenceStorageNodes.ExtendNode createExtend() {
288327
return SequenceStorageNodes.ExtendNode.create(() -> ListGeneralizationNode.create());
289328
}
329+
330+
public static ListExtendNode create() {
331+
return ListBuiltinsFactory.ListExtendNodeFactory.create();
332+
}
290333
}
291334

292335
// list.insert(i, x)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/ListNodes.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989

9090
public abstract class ListNodes {
9191

92-
public final static class CreateListFromIteratorNode extends PNodeWithContext {
92+
public final static class CreateStorageFromIteratorNode extends PNodeWithContext {
9393

9494
private static final int START_SIZE = 2;
9595

@@ -99,11 +99,11 @@ public final static class CreateListFromIteratorNode extends PNodeWithContext {
9999

100100
@CompilationFinal private ListStorageType type = ListStorageType.Uninitialized;
101101

102-
public static CreateListFromIteratorNode create() {
103-
return new CreateListFromIteratorNode();
102+
public static CreateStorageFromIteratorNode create() {
103+
return new CreateStorageFromIteratorNode();
104104
}
105105

106-
public PList execute(LazyPythonClass cls, Object iterator) {
106+
public SequenceStorage execute(Object iterator) {
107107
SequenceStorage storage;
108108
if (type == ListStorageType.Uninitialized) {
109109
try {
@@ -259,7 +259,7 @@ public PList execute(LazyPythonClass cls, Object iterator) {
259259
storage = genericFallback(iterator, array, i, e.getResult());
260260
}
261261
}
262-
return factory().createList(cls, storage);
262+
return storage;
263263
}
264264

265265
private SequenceStorage genericFallback(Object iterator, Object array, int count, Object result) {
@@ -322,10 +322,11 @@ public PList listIterable(LazyPythonClass cls, @SuppressWarnings("unused") PNone
322322
@Specialization(guards = {"!isNoValue(iterable)", "!isString(iterable)"})
323323
public PList listIterable(LazyPythonClass cls, Object iterable,
324324
@Cached("create()") GetIteratorNode getIteratorNode,
325-
@Cached("create()") CreateListFromIteratorNode createListFromIteratorNode) {
325+
@Cached("create()") CreateStorageFromIteratorNode createStorageFromIteratorNode) {
326326

327327
Object iterObj = getIteratorNode.executeWith(iterable);
328-
return createListFromIteratorNode.execute(cls, iterObj);
328+
SequenceStorage storage = createStorageFromIteratorNode.execute(iterObj);
329+
return factory().createList(cls, storage);
329330
}
330331

331332
@Fallback

0 commit comments

Comments
 (0)