Kaydet (Commit) 398ff91a authored tarafından Yury Selivanov's avatar Yury Selivanov Kaydeden (comit) GitHub

bpo-28893: Set __cause__ for errors in async iteration protocol (#407)

üst 8d26aa93
...@@ -1680,6 +1680,44 @@ class CoroutineTest(unittest.TestCase): ...@@ -1680,6 +1680,44 @@ class CoroutineTest(unittest.TestCase):
warnings.simplefilter("error") warnings.simplefilter("error")
run_async(foo()) 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): def test_for_tuple(self):
class Done(Exception): pass class Done(Exception): pass
......
...@@ -10,6 +10,9 @@ What's New in Python 3.7.0 alpha 1? ...@@ -10,6 +10,9 @@ What's New in Python 3.7.0 alpha 1?
Core and Builtins 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 - bpo-29683: Fixes to memory allocation in _PyCode_SetExtra. Patch by
Brian Coleman. Brian Coleman.
......
...@@ -1855,13 +1855,13 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) ...@@ -1855,13 +1855,13 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
awaitable = _PyCoro_GetAwaitableIter(iter); awaitable = _PyCoro_GetAwaitableIter(iter);
if (awaitable == NULL) { if (awaitable == NULL) {
SET_TOP(NULL); _PyErr_FormatFromCause(
PyErr_Format(
PyExc_TypeError, PyExc_TypeError,
"'async for' received an invalid object " "'async for' received an invalid object "
"from __aiter__: %.100s", "from __aiter__: %.100s",
Py_TYPE(iter)->tp_name); Py_TYPE(iter)->tp_name);
SET_TOP(NULL);
Py_DECREF(iter); Py_DECREF(iter);
goto error; goto error;
} else { } else {
...@@ -1920,7 +1920,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) ...@@ -1920,7 +1920,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
awaitable = _PyCoro_GetAwaitableIter(next_iter); awaitable = _PyCoro_GetAwaitableIter(next_iter);
if (awaitable == NULL) { if (awaitable == NULL) {
PyErr_Format( _PyErr_FormatFromCause(
PyExc_TypeError, PyExc_TypeError,
"'async for' received an invalid object " "'async for' received an invalid object "
"from __anext__: %.100s", "from __anext__: %.100s",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment