From 7b85a7b325fde480dac46e7163062e4828f13eb2 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Mon, 29 Jan 2018 13:59:48 -0500 Subject: [PATCH] Fix tests --- Lib/test/test_coroutines.py | 96 ++++++++++++++++++++++++------------- Objects/genobject.c | 9 ++-- 2 files changed, 69 insertions(+), 36 deletions(-) diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 19a3444b6ad7a1..f3d77192ae765f 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -520,34 +520,38 @@ def test_func_3(self): async def foo(): raise StopIteration - with silence_coro_gc(): - self.assertRegex(repr(foo()), '^$') + coro = foo() + self.assertRegex(repr(coro), '^$') + coro.close() def test_func_4(self): async def foo(): raise StopIteration + coro = foo() check = lambda: self.assertRaisesRegex( TypeError, "'coroutine' object is not iterable") with check(): - list(foo()) + list(coro) with check(): - tuple(foo()) + tuple(coro) with check(): - sum(foo()) + sum(coro) with check(): - iter(foo()) + iter(coro) - with silence_coro_gc(), check(): - for i in foo(): + with check(): + for i in coro: pass - with silence_coro_gc(), check(): - [i for i in foo()] + with check(): + [i for i in coro] + + coro.close() def test_func_5(self): @types.coroutine @@ -560,8 +564,11 @@ async def foo(): check = lambda: self.assertRaisesRegex( TypeError, "'coroutine' object is not iterable") + coro = foo() with check(): - for el in foo(): pass + for el in coro: + pass + coro.close() # the following should pass without an error for el in bar(): @@ -588,35 +595,53 @@ async def foo(): def test_func_7(self): async def bar(): return 10 + coro = bar() def foo(): - yield from bar() - - with silence_coro_gc(), self.assertRaisesRegex( - TypeError, - "cannot 'yield from' a coroutine object in a non-coroutine generator"): + yield from coro + with self.assertRaisesRegex( + TypeError, + "cannot 'yield from' a coroutine object in " + "a non-coroutine generator"): list(foo()) + coro.close() + def test_func_8(self): @types.coroutine def bar(): - return (yield from foo()) + return (yield from coro) async def foo(): return 'spam' - self.assertEqual(run_async(bar()), ([], 'spam') ) + coro = foo() + self.assertEqual(run_async(bar()), ([], 'spam')) + coro.close() def test_func_9(self): - async def foo(): pass + async def foo(): + pass with self.assertWarnsRegex( - RuntimeWarning, "coroutine '.*test_func_9.*foo' was never awaited"): + RuntimeWarning, + r"coroutine '.*test_func_9.*foo' was never awaited"): foo() support.gc_collect() + with self.assertWarnsRegex( + RuntimeWarning, + r"coroutine '.*test_func_9.*foo' was never awaited"): + + with self.assertRaises(TypeError): + # See bpo-32703. + for _ in foo(): + pass + + support.gc_collect() + def test_func_10(self): N = 0 @@ -674,11 +699,14 @@ async def g(): def test_func_13(self): async def g(): pass + + coro = g() with self.assertRaisesRegex( - TypeError, - "can't send non-None value to a just-started coroutine"): + TypeError, + "can't send non-None value to a just-started coroutine"): + coro.send('spam') - g().send('spam') + coro.close() def test_func_14(self): @types.coroutine @@ -977,8 +1005,6 @@ async def bar(): return 42 async def foo(): - b = bar() - db = {'b': lambda: wrap} class DB: @@ -1023,19 +1049,21 @@ async def foo2(): def test_await_12(self): async def coro(): return 'spam' + c = coro() class Awaitable: def __await__(self): - return coro() + return c async def foo(): return await Awaitable() with self.assertRaisesRegex( - TypeError, r"__await__\(\) returned a coroutine"): - + TypeError, r"__await__\(\) returned a coroutine"): run_async(foo()) + c.close() + def test_await_13(self): class Awaitable: def __await__(self): @@ -1991,14 +2019,15 @@ def wrap(gen): finally: with self.assertWarns(DeprecationWarning): sys.set_coroutine_wrapper(None) + f.close() with self.assertWarns(DeprecationWarning): self.assertIsNone(sys.get_coroutine_wrapper()) wrapped = None - with silence_coro_gc(): - foo() + coro = foo() self.assertFalse(wrapped) + coro.close() def test_set_wrapper_2(self): with self.assertWarns(DeprecationWarning): @@ -2022,11 +2051,12 @@ async def wrap(coro): sys.set_coroutine_wrapper(wrapper) try: with silence_coro_gc(), self.assertRaisesRegex( - RuntimeError, - r"coroutine wrapper.*\.wrapper at 0x.*attempted to " - r"recursively wrap .* wrap .*"): + RuntimeError, + r"coroutine wrapper.*\.wrapper at 0x.*attempted to " + r"recursively wrap .* wrap .*"): foo() + finally: with self.assertWarns(DeprecationWarning): sys.set_coroutine_wrapper(None) diff --git a/Objects/genobject.c b/Objects/genobject.c index 1f7f286b1a357f..88b03c5ef313ca 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -44,9 +44,10 @@ _PyGen_Finalize(PyObject *self) PyObject *res = NULL; PyObject *error_type, *error_value, *error_traceback; - if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL) + if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL) { /* Generator isn't paused, so no need to close */ return; + } if (PyAsyncGen_CheckExact(self)) { PyAsyncGenObject *agen = (PyAsyncGenObject*)self; @@ -75,7 +76,8 @@ _PyGen_Finalize(PyObject *self) issue a RuntimeWarning. */ if (gen->gi_code != NULL && ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE && - gen->gi_frame->f_lasti == -1) { + gen->gi_frame->f_lasti == -1) + { _PyErr_WarnUnawaitedCoroutine((PyObject *)gen); } else { @@ -83,8 +85,9 @@ _PyGen_Finalize(PyObject *self) } if (res == NULL) { - if (PyErr_Occurred()) + if (PyErr_Occurred()) { PyErr_WriteUnraisable(self); + } } else { Py_DECREF(res);