Skip to content

Commit 3e5e565

Browse files
committed
Suppress TypeError in GetLengthNode
1 parent 2ecf186 commit 3e5e565

File tree

2 files changed

+53
-12
lines changed

2 files changed

+53
-12
lines changed

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

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,30 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects.iterator;
4242

43+
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
44+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__LENGTH_HINT__;
45+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__LEN__;
46+
4347
import com.oracle.graal.python.builtins.objects.PNone;
48+
import com.oracle.graal.python.builtins.objects.PNotImplemented;
4449
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
50+
import com.oracle.graal.python.nodes.ErrorMessages;
4551
import com.oracle.graal.python.nodes.PGuards;
4652
import com.oracle.graal.python.nodes.PNodeWithContext;
53+
import com.oracle.graal.python.nodes.PRaiseNode;
4754
import com.oracle.graal.python.nodes.SpecialMethodNames;
4855
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
4956
import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode;
57+
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
5058
import com.oracle.graal.python.nodes.util.CastToJavaIntLossyNode;
59+
import com.oracle.graal.python.runtime.exception.PException;
5160
import com.oracle.truffle.api.dsl.Cached;
5261
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
5362
import com.oracle.truffle.api.dsl.ImportStatic;
5463
import com.oracle.truffle.api.dsl.Specialization;
5564
import com.oracle.truffle.api.frame.VirtualFrame;
5665
import com.oracle.truffle.api.library.CachedLibrary;
66+
import com.oracle.truffle.api.profiles.ConditionProfile;
5767

5868
public abstract class IteratorNodes {
5969

@@ -86,22 +96,51 @@ int length(VirtualFrame frame, Object iterable,
8696
@Cached CastToJavaIntLossyNode cast,
8797
@Cached("create(__LEN__)") LookupAttributeInMRONode lenNode,
8898
@Cached("create(__LENGTH_HINT__)") LookupAttributeInMRONode lenHintNode,
89-
@Cached CallUnaryMethodNode dispatchGetattribute) {
90-
Object len;
99+
@Cached CallUnaryMethodNode dispatchGetattribute,
100+
@Cached IsBuiltinClassProfile errorProfile,
101+
@Cached ConditionProfile hasLenProfile,
102+
@Cached ConditionProfile hasLenghtHintProfile,
103+
@Cached PRaiseNode raiseNode) {
91104
Object clazz = plib.getLazyPythonClass(iterable);
92105
Object attrLenObj = lenNode.execute(clazz);
93-
if (attrLenObj != PNone.NO_VALUE && attrLenObj != PNone.NONE) {
94-
len = dispatchGetattribute.executeObject(frame, attrLenObj, iterable);
95-
} else {
96-
Object attrLenHintObj = lenHintNode.execute(clazz);
97-
if (attrLenHintObj != PNone.NO_VALUE && attrLenHintObj != PNone.NONE) {
98-
len = dispatchGetattribute.executeObject(frame, attrLenHintObj, iterable);
99-
} else {
100-
return -1;
106+
if (hasLenProfile.profile(attrLenObj != PNone.NO_VALUE && attrLenObj != PNotImplemented.NOT_IMPLEMENTED)) {
107+
Object len = null;
108+
try {
109+
len = dispatchGetattribute.executeObject(frame, attrLenObj, iterable);
110+
} catch (PException e) {
111+
e.expect(TypeError, errorProfile);
112+
}
113+
if (len != null) {
114+
if (toInt.canBeIndex(len)) {
115+
int intLen = cast.execute(toInt.asIndex(len));
116+
if (intLen < 0) {
117+
throw raiseNode.raise(TypeError, ErrorMessages.LEN_SHOULD_RETURN_MT_ZERO);
118+
}
119+
return intLen;
120+
} else {
121+
throw raiseNode.raise(TypeError, ErrorMessages.MUST_BE_INTEGER, __LEN__, len);
122+
}
101123
}
102124
}
103-
if (toInt.canBeIndex(len)) {
104-
return cast.execute(toInt.asIndex(len));
125+
Object attrLenHintObj = lenHintNode.execute(clazz);
126+
if (hasLenghtHintProfile.profile(attrLenHintObj != PNone.NO_VALUE && attrLenHintObj != PNotImplemented.NOT_IMPLEMENTED)) {
127+
Object len = null;
128+
try {
129+
len = dispatchGetattribute.executeObject(frame, attrLenHintObj, iterable);
130+
} catch (PException e) {
131+
e.expect(TypeError, errorProfile);
132+
}
133+
if (len != null) {
134+
if (toInt.canBeIndex(len)) {
135+
int intLen = cast.execute(toInt.asIndex(len));
136+
if (intLen < 0) {
137+
throw raiseNode.raise(TypeError, ErrorMessages.LENGTH_HINT_SHOULD_RETURN_MT_ZERO);
138+
}
139+
return intLen;
140+
} else {
141+
throw raiseNode.raise(TypeError, ErrorMessages.MUST_BE_INTEGER, __LENGTH_HINT__, len);
142+
}
143+
}
105144
}
106145
return -1;
107146
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ public abstract class ErrorMessages {
316316
public static final String LAZY_INITIALIZATION_FAILED = "lazy initialization of type %s failed";
317317
public static final String LEFT_BRACKET_WO_RIGHT_BRACKET_IN_ARG = "')' without '(' in argument parsing";
318318
public static final String LEN_SHOULD_RETURN_MT_ZERO = "__len__() should return >= 0";
319+
public static final String LENGTH_HINT_SHOULD_RETURN_MT_ZERO = "__length_hint__() should return >= 0";
319320
public static final String LIST_ASSIGMENT_INDEX_OUT_OF_RANGE = "list assignment index out of range";
320321
public static final String LIST_INDEX_OUT_OF_RANGE = "list index out of range";
321322
public static final String LIST_LENGTH_OUT_OF_RANGE = "list length out of range";
@@ -340,6 +341,7 @@ public abstract class ErrorMessages {
340341
public static final String MUST_BE_A_CELL = "%s must be a cell";
341342
public static final String MUST_BE_BYTE_STRING_LEGTH1_NOT_P = "must be a byte string of length 1, not %p";
342343
public static final String MUST_BE_EITHER_OR = "%s: '%s' must be either %s or %s";
344+
public static final String MUST_BE_INTEGER = "%s must be an integer, not %p";
343345
public static final String MUST_BE_NON_NEGATIVE = "%s must be non-negative";
344346
public static final String MUST_BE_NON_NEGATIVE_INTEGER = "%s must be non-negative integer";
345347
public static final String MUST_BE_NUMERIC = "must be numeric, not %p";

0 commit comments

Comments
 (0)