Skip to content

Commit 25463d8

Browse files
committed
[GR-25388] Support start and end arguments in the bytes.index method and implement itertools.tee.
PullRequest: graalpython/1176
2 parents 7d5fb53 + 56bb668 commit 25463d8

File tree

4 files changed

+67
-33
lines changed

4 files changed

+67
-33
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2018, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2020, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -25,37 +25,19 @@
2525
*/
2626
package com.oracle.graal.python.builtins.modules;
2727

28-
import static com.oracle.graal.python.runtime.exception.PythonErrorType.NotImplementedError;
29-
28+
import java.util.Collections;
3029
import java.util.List;
3130

32-
import com.oracle.graal.python.builtins.Builtin;
3331
import com.oracle.graal.python.builtins.CoreFunctions;
3432
import com.oracle.graal.python.builtins.PythonBuiltins;
35-
import com.oracle.graal.python.builtins.objects.PNone;
3633
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
37-
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
38-
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
3934
import com.oracle.truffle.api.dsl.NodeFactory;
40-
import com.oracle.truffle.api.dsl.Specialization;
4135

4236
@CoreFunctions(defineModule = "itertools")
4337
public final class ItertoolsModuleBuiltins extends PythonBuiltins {
4438

4539
@Override
4640
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
47-
return ItertoolsModuleBuiltinsFactory.getFactories();
48-
}
49-
50-
// tee(iterable, n=2)
51-
@Builtin(name = "tee", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2)
52-
@GenerateNodeFactory
53-
public abstract static class TeeNode extends PythonBuiltinNode {
54-
@SuppressWarnings("unused")
55-
@Specialization(guards = "isNoValue(n)")
56-
Object tee(Object iterable, PNone n) {
57-
throw raise(NotImplementedError, "tee");
58-
}
41+
return Collections.emptyList();
5942
}
60-
6143
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesBuiltins.java

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import com.oracle.graal.python.builtins.objects.PNotImplemented;
6363
import com.oracle.graal.python.builtins.objects.bytes.BytesBuiltinsFactory.BytesLikeNoGeneralizationNodeGen;
6464
import com.oracle.graal.python.builtins.objects.common.IndexNodes.NormalizeIndexNode;
65+
import com.oracle.graal.python.builtins.objects.common.SequenceNodes;
6566
import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetObjectArrayNode;
6667
import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetSequenceStorageNode;
6768
import com.oracle.graal.python.builtins.objects.common.SequenceNodesFactory.GetObjectArrayNodeGen;
@@ -853,23 +854,42 @@ protected boolean doIt(byte[] bytes, byte[] suffix, int start, int end) {
853854

854855
// bytes.index(x)
855856
// bytearray.index(x)
856-
@Builtin(name = "index", minNumOfPositionalArgs = 2)
857+
@Builtin(name = "index", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 4)
857858
@GenerateNodeFactory
858-
public abstract static class ByteArrayIndexNode extends PythonBuiltinNode {
859-
@Child private SequenceStorageNodes.LenNode lenNode;
860-
859+
public abstract static class ByteArrayIndexNode extends PythonQuaternaryBuiltinNode {
861860
@Specialization
862-
public int index(VirtualFrame frame, PIBytesLike byteArray, Object arg,
863-
@Cached("create()") BytesNodes.FindNode findNode) {
864-
return findNode.execute(frame, byteArray, arg, 0, getLength(byteArray.getSequenceStorage()));
861+
int index(VirtualFrame frame, PIBytesLike byteArray, Object arg, @SuppressWarnings("unused") PNone start, @SuppressWarnings("unused") PNone end,
862+
@Shared("len") @Cached SequenceStorageNodes.LenNode lenNode,
863+
@Shared("storage") @Cached SequenceNodes.GetSequenceStorageNode getStorageNode,
864+
@Shared("findNode") @Cached("create()") BytesNodes.FindNode findNode) {
865+
return checkResult(findNode.execute(frame, byteArray, arg, 0, lenNode.execute(getStorageNode.execute(byteArray))));
865866
}
866867

867-
private int getLength(SequenceStorage s) {
868-
if (lenNode == null) {
869-
CompilerDirectives.transferToInterpreterAndInvalidate();
870-
lenNode = insert(SequenceStorageNodes.LenNode.create());
868+
@Specialization(guards = {"!isPNone(start)"})
869+
int indexWithStart(VirtualFrame frame, PIBytesLike byteArray, Object arg, Object start, @SuppressWarnings("unused") PNone end,
870+
@Shared("storage") @Cached SequenceNodes.GetSequenceStorageNode getStorageNode,
871+
@Shared("len") @Cached SequenceStorageNodes.LenNode lenNode,
872+
@Shared("findNode") @Cached("create()") BytesNodes.FindNode findNode) {
873+
return checkResult(findNode.execute(frame, byteArray, arg, start, lenNode.execute(getStorageNode.execute(byteArray))));
874+
}
875+
876+
@Specialization(guards = {"!isPNone(end)"})
877+
int indexWithEnd(VirtualFrame frame, PIBytesLike byteArray, Object arg, @SuppressWarnings("unused") PNone start, Object end,
878+
@Shared("findNode") @Cached("create()") BytesNodes.FindNode findNode) {
879+
return checkResult(checkResult(findNode.execute(frame, byteArray, arg, 0, end)));
880+
}
881+
882+
@Specialization(guards = {"!isPNone(start)", "!isPNone(end)"})
883+
int indexWithStartEnd(VirtualFrame frame, PIBytesLike byteArray, Object arg, Object start, Object end,
884+
@Shared("findNode") @Cached("create()") BytesNodes.FindNode findNode) {
885+
return checkResult(findNode.execute(frame, byteArray, arg, start, end));
886+
}
887+
888+
private int checkResult(int result) {
889+
if (result == -1) {
890+
throw raise(PythonBuiltinClassType.ValueError, ErrorMessages.SUBSECTION_NOT_FOUND);
871891
}
872-
return lenNode.execute(s);
892+
return result;
873893
}
874894
}
875895

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
@@ -473,6 +473,7 @@ public abstract class ErrorMessages {
473473
public static final String STRING_ARG_WO_ENCODING = "string argument without an encoding";
474474
public static final String STRING_INDEX_OUT_OF_RANGE = "IndexError: string index out of range";
475475
public static final String SUBSTRING_NOT_FOUND = "substring not found";
476+
public static final String SUBSECTION_NOT_FOUND = "subsection not found";
476477
public static final String SUPER_OBJ_MUST_BE_INST_SUB_OR_TYPE = "super(type, obj): obj must be an instance or subtype of type";
477478
public static final String TAKES_D_OR_D_ARGS = "%s takes %d or %d arguments";
478479
public static final String TAKES_D_POS_ARG_S_BUT_D_POS_ARG_S = "%s() takes %d positional argument%s but %d positional argument%s (and %d keyword-only argument%s) were given%s";

graalpython/lib-graalpython/itertools.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,3 +858,34 @@ def __next__(self):
858858
@__graalpython__.builtin_method
859859
def __reduce__(self):
860860
return (type(self), (self.data, self.selectors))
861+
862+
863+
def tee(iterable, n=2):
864+
import collections
865+
class _tee:
866+
@__graalpython__.builtin_method
867+
def __init__(self, it, deque, deques):
868+
self.it = it
869+
self.deque = deque
870+
self.deques = deques
871+
872+
@__graalpython__.builtin_method
873+
def __iter__(self):
874+
return self
875+
876+
@__graalpython__.builtin_method
877+
def __next__(self):
878+
if not self.deque:
879+
newval = next(self.it)
880+
for d in self.deques:
881+
d.append(newval)
882+
return self.deque.popleft()
883+
884+
if not isinstance(n, int):
885+
raise TypeError()
886+
if n < 0:
887+
raise ValueError("n must be >=0")
888+
889+
deques = [collections.deque() for i in range(n)]
890+
it = iter(iterable)
891+
return tuple(_tee(it, d, deques) for d in deques)

0 commit comments

Comments
 (0)