Skip to content

Commit

Permalink
bpo-28893: Set __cause__ for errors in async iteration protocol (#407)
Browse files Browse the repository at this point in the history
  • Loading branch information
1st1 authored Mar 3, 2017
1 parent 8d26aa9 commit 398ff91
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 3 deletions.
38 changes: 38 additions & 0 deletions Lib/test/test_coroutines.py
Original file line number Diff line number Diff line change
Expand Up @@ -1680,6 +1680,44 @@ async def foo():
warnings.simplefilter("error")
run_async(foo())

def test_for_11(self):
class F:
def __aiter__(self):
return self
def __anext__(self):
return self
def __await__(self):
1 / 0

async def main():
async for _ in F():
pass

with self.assertRaisesRegex(TypeError,
'an invalid object from __anext__') as c:
main().send(None)

err = c.exception
self.assertIsInstance(err.__cause__, ZeroDivisionError)

def test_for_12(self):
class F:
def __aiter__(self):
return self
def __await__(self):
1 / 0

async def main():
async for _ in F():
pass

with self.assertRaisesRegex(TypeError,
'an invalid object from __aiter__') as c:
main().send(None)

err = c.exception
self.assertIsInstance(err.__cause__, ZeroDivisionError)

def test_for_tuple(self):
class Done(Exception): pass

Expand Down
3 changes: 3 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ What's New in Python 3.7.0 alpha 1?
Core and Builtins
-----------------

- bpo-28893: Set correct __cause__ for errors about invalid awaitables
returned from __aiter__ and __anext__.

- bpo-29683: Fixes to memory allocation in _PyCode_SetExtra. Patch by
Brian Coleman.

Expand Down
6 changes: 3 additions & 3 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -1855,13 +1855,13 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)

awaitable = _PyCoro_GetAwaitableIter(iter);
if (awaitable == NULL) {
SET_TOP(NULL);
PyErr_Format(
_PyErr_FormatFromCause(
PyExc_TypeError,
"'async for' received an invalid object "
"from __aiter__: %.100s",
Py_TYPE(iter)->tp_name);

SET_TOP(NULL);
Py_DECREF(iter);
goto error;
} else {
Expand Down Expand Up @@ -1920,7 +1920,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)

awaitable = _PyCoro_GetAwaitableIter(next_iter);
if (awaitable == NULL) {
PyErr_Format(
_PyErr_FormatFromCause(
PyExc_TypeError,
"'async for' received an invalid object "
"from __anext__: %.100s",
Expand Down

0 comments on commit 398ff91

Please sign in to comment.