diff options
author | Yury Selivanov <yselivanov@gmail.com> | 2017-03-03 03:20:00 (GMT) |
---|---|---|
committer | Yury Selivanov <yury@magic.io> | 2017-03-03 03:28:07 (GMT) |
commit | dea5101ae101aefed14de98e6bb1658f4cae8712 (patch) | |
tree | d64ec52013fc547f9420c82c065e09d340703d1b | |
parent | 01e5230ef0b28658cf7311be199363eda98808bd (diff) | |
download | cpython-dea5101ae101aefed14de98e6bb1658f4cae8712.zip cpython-dea5101ae101aefed14de98e6bb1658f4cae8712.tar.gz cpython-dea5101ae101aefed14de98e6bb1658f4cae8712.tar.bz2 |
bpo-28893: Set __cause__ for errors in async iteration protocol (#407)
-rw-r--r-- | Lib/test/test_coroutines.py | 38 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Python/ceval.c | 6 |
3 files changed, 44 insertions, 3 deletions
diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 78439a2..b4c7b5b 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -1680,6 +1680,44 @@ class CoroutineTest(unittest.TestCase): 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 @@ -10,6 +10,9 @@ What's New in Python 3.6.1 release candidate 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. diff --git a/Python/ceval.c b/Python/ceval.c index 02bc67e..9cac771 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1904,13 +1904,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 { @@ -1969,7 +1969,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", |