Skip to content

Commit dea5101

Browse files
1st1Yury Selivanov
authored andcommitted
bpo-28893: Set __cause__ for errors in async iteration protocol (#407)
1 parent 01e5230 commit dea5101

3 files changed

Lines changed: 44 additions & 3 deletions

File tree

‎Lib/test/test_coroutines.py‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,6 +1680,44 @@ async def foo():
16801680
warnings.simplefilter("error")
16811681
run_async(foo())
16821682

1683+
deftest_for_11(self):
1684+
classF:
1685+
def__aiter__(self):
1686+
returnself
1687+
def__anext__(self):
1688+
returnself
1689+
def__await__(self):
1690+
1/0
1691+
1692+
asyncdefmain():
1693+
asyncfor_inF():
1694+
pass
1695+
1696+
withself.assertRaisesRegex(TypeError,
1697+
'an invalid object from __anext__') asc:
1698+
main().send(None)
1699+
1700+
err=c.exception
1701+
self.assertIsInstance(err.__cause__, ZeroDivisionError)
1702+
1703+
deftest_for_12(self):
1704+
classF:
1705+
def__aiter__(self):
1706+
returnself
1707+
def__await__(self):
1708+
1/0
1709+
1710+
asyncdefmain():
1711+
asyncfor_inF():
1712+
pass
1713+
1714+
withself.assertRaisesRegex(TypeError,
1715+
'an invalid object from __aiter__') asc:
1716+
main().send(None)
1717+
1718+
err=c.exception
1719+
self.assertIsInstance(err.__cause__, ZeroDivisionError)
1720+
16831721
deftest_for_tuple(self):
16841722
classDone(Exception): pass
16851723

‎Misc/NEWS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ What's New in Python 3.6.1 release candidate 1?
1010
Core and Builtins
1111
-----------------
1212

13+
- bpo-28893: Set correct __cause__ for errors about invalid awaitables
14+
returned from __aiter__ and __anext__.
15+
1316
- bpo-29683: Fixes to memory allocation in _PyCode_SetExtra. Patch by
1417
Brian Coleman.
1518

‎Python/ceval.c‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,13 +1904,13 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
19041904

19051905
awaitable=_PyCoro_GetAwaitableIter(iter);
19061906
if (awaitable==NULL) {
1907-
SET_TOP(NULL);
1908-
PyErr_Format(
1907+
_PyErr_FormatFromCause(
19091908
PyExc_TypeError,
19101909
"'async for' received an invalid object "
19111910
"from __aiter__: %.100s",
19121911
Py_TYPE(iter)->tp_name);
19131912

1913+
SET_TOP(NULL);
19141914
Py_DECREF(iter);
19151915
goto error;
19161916
} else {
@@ -1969,7 +1969,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
19691969

19701970
awaitable=_PyCoro_GetAwaitableIter(next_iter);
19711971
if (awaitable==NULL) {
1972-
PyErr_Format(
1972+
_PyErr_FormatFromCause(
19731973
PyExc_TypeError,
19741974
"'async for' received an invalid object "
19751975
"from __anext__: %.100s",

0 commit comments

Comments
 (0)