Skip to content

Commit 4e65357

Browse files
committed
[GR-13574] Fix: 'CastToIndexNode' must not evaluate '__index__' twice.
PullRequest: graalpython/386
2 parents 88e7cc5 + 5a9b31a commit 4e65357

File tree

2 files changed

+20
-12
lines changed

2 files changed

+20
-12
lines changed

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

Lines changed: 11 additions & 1 deletion
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, 2019, Oracle and/or its affiliates.
22
# Copyright (C) 1996-2017 Python Software Foundation
33
#
44
# Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
@@ -138,6 +138,16 @@ class L(list): pass
138138
def test_getitem(self):
139139
l = [1, 2, 3]
140140
self.assertEqual(1, l[False])
141+
142+
class IdxObj:
143+
__cnt = 0
144+
def __index__(self):
145+
cur = self.__cnt
146+
self.__cnt += 1
147+
return cur
148+
idxObj = IdxObj()
149+
cpy = [l[idxObj], l[idxObj], l[idxObj]]
150+
self.assertEqual(cpy, l)
141151

142152
def pop_all_list(self, list):
143153
size = len(list)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToIndexNode.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,7 @@ int doPIntOvf(PInt x) {
126126

127127
@Specialization
128128
public int toInt(double x) {
129-
if (typeErrorHandler != null) {
130-
return typeErrorHandler.apply(x);
131-
}
132-
throw raise(TypeError, "'%p' object cannot be interpreted as an integer", x);
129+
return handleError("'%p' object cannot be interpreted as an integer", x);
133130
}
134131

135132
@Fallback
@@ -140,22 +137,23 @@ int doGeneric(Object x) {
140137
callIndexNode = insert(LookupAndCallUnaryNode.create(__INDEX__));
141138
}
142139
Object result = callIndexNode.executeObject(x);
143-
if (result == PNone.NONE) {
144-
if (typeErrorHandler != null) {
145-
return typeErrorHandler.apply(x);
146-
}
147-
throw raise(TypeError, "'%p' object cannot be interpreted as an integer", x);
140+
if (result == PNone.NO_VALUE) {
141+
return handleError("'%p' object cannot be interpreted as an integer", x);
148142
}
149143
if (recursiveNode == null) {
150144
CompilerDirectives.transferToInterpreterAndInvalidate();
151145
recursiveNode = insert(CastToIndexNodeGen.create(errorType, false, typeErrorHandler));
152146
}
153-
return recursiveNode.execute(callIndexNode.executeObject(x));
147+
return recursiveNode.execute(result);
154148
}
149+
return handleError("__index__ returned non-int (type %p)", x);
150+
}
151+
152+
private int handleError(String fmt, Object x) {
155153
if (typeErrorHandler != null) {
156154
return typeErrorHandler.apply(x);
157155
}
158-
throw raise(TypeError, "__index__ returned non-int (type %p)", x);
156+
throw raise(TypeError, fmt, x);
159157
}
160158

161159
public static CastToIndexNode create() {

0 commit comments

Comments
 (0)