Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions graalpython/com.oracle.graal.python.test/src/tests/test_builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ def test_divmod_complex(self):
self.assertRaises(TypeError, divmod, 10, c2)
self.assertRaises(TypeError, divmod, c1, 10)

def test_aiter_type_errors(self):
class BadAIter:
def __aiter__(self):
return object()

async def async_for_none():
async for _ in None:
pass

with self.assertRaisesRegex(TypeError, "'NoneType' object is not an async iterable"):
aiter(None)
with self.assertRaisesRegex(TypeError, "'int' object is not an async iterable"):
aiter(1)
with self.assertRaisesRegex(TypeError, r"aiter\(\) returned not an async iterator of type 'object'"):
aiter(BadAIter())
with self.assertRaisesRegex(TypeError, "'async for' requires an object with __aiter__ method, got NoneType"):
async_for_none().send(None)

def test_getitem_typeerror(self):
a = object()
try:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@
import com.oracle.graal.python.compiler.Compiler;
import com.oracle.graal.python.compiler.ParserCallbacksImpl;
import com.oracle.graal.python.lib.IteratorExhausted;
import com.oracle.graal.python.lib.PyAIterCheckNode;
import com.oracle.graal.python.lib.PyBytesCheckNode;
import com.oracle.graal.python.lib.PyCallableCheckNode;
import com.oracle.graal.python.lib.PyEvalGetGlobals;
Expand Down Expand Up @@ -223,7 +224,6 @@
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
import com.oracle.graal.python.nodes.builtins.ListNodes;
import com.oracle.graal.python.nodes.builtins.ListNodes.ConstructListNode;
import com.oracle.graal.python.nodes.bytecode.GetAIterNode;
import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode;
import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode;
import com.oracle.graal.python.nodes.call.CallDispatchers;
Expand Down Expand Up @@ -2598,8 +2598,22 @@ static Object doGeneric(VirtualFrame frame, Object asyncIter, Object defaultValu
public abstract static class AIter extends PythonUnaryBuiltinNode {
@Specialization
static Object doGeneric(VirtualFrame frame, Object arg,
@Cached GetAIterNode aiter) {
return aiter.execute(frame, arg);
@Bind Node inliningTarget,
@Cached GetObjectSlotsNode getSlots,
@Cached CallSlotUnaryNode callSlot,
@Cached PyAIterCheckNode checkNode,
@Cached GetClassNode getClassNode,
@Cached PRaiseNode raiseNode) {
TpSlots slots = getSlots.execute(inliningTarget, arg);
if (slots.am_aiter() == null) {
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.OBJECT_NOT_ASYNC_ITERABLE, arg);
}
Object asyncIterator = callSlot.execute(frame, inliningTarget, slots.am_aiter(), arg);
if (!checkNode.execute(inliningTarget, asyncIterator)) {
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.AITER_RETURNED_NOT_ASYNC_ITERATOR,
getClassNode.execute(inliningTarget, asyncIterator));
}
return asyncIterator;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1362,9 +1362,11 @@ public abstract class ErrorMessages {

public static final TruffleString INDEX_EXCEEDS_INT = tsLiteral("index exceeds integer size");
public static final TruffleString X_NOT_IN_SEQUENCE = tsLiteral("sequence.index(x): x not in sequence");
public static final TruffleString ASYNC_FOR_NO_AITER = tsLiteral("'async for' requires object with __aiter__ method, got %N");
public static final TruffleString ASYNC_FOR_NO_AITER = tsLiteral("'async for' requires an object with __aiter__ method, got %N");
public static final TruffleString OBJECT_NOT_ASYNC_ITERABLE = tsLiteral("'%p' object is not an async iterable");
public static final TruffleString ASYNC_FOR_NO_ANEXT_INITIAL = tsLiteral("'async for' received an object from __aiter__ that does not implement __anext__: %p");
public static final TruffleString ASYNC_FOR_NO_ANEXT_ITERATION = tsLiteral("'async for' requires an iterator with __anext__ method, got %p");
public static final TruffleString AITER_RETURNED_NOT_ASYNC_ITERATOR = tsLiteral("aiter() returned not an async iterator of type '%N'");

public static final TruffleString CANNOT_REUSE_ASEND = tsLiteral("cannot reuse already awaited __anext__()/asend()");
public static final TruffleString OBJECT_NOT_ASYNCGEN = tsLiteral("'%p' object is not an async generator");
Expand Down
Loading