(original) (raw)
changeset: 103040:4d531711cbc7 branch: 3.5 parent: 103036:756c27efe193 user: Benjamin Peterson benjamin@python.org date: Mon Sep 05 10:14:54 2016 -0700 files: Lib/test/test_coroutines.py Misc/NEWS Objects/genobject.c description: do not allow _PyGen_Finalize to fail (closes #27811) Patch from Armin Rigo. diff -r 756c27efe193 -r 4d531711cbc7 Lib/test/test_coroutines.py --- a/Lib/test/test_coroutines.py Mon Sep 05 00:01:34 2016 -0400 +++ b/Lib/test/test_coroutines.py Mon Sep 05 10:14:54 2016 -0700 @@ -1565,6 +1565,14 @@ finally: aw.close() + def test_fatal_coro_warning(self): + # Issue 27811 + async def func(): pass + with warnings.catch_warnings(): + warnings.filterwarnings("error") + func() + support.gc_collect() + class CoroAsyncIOCompatTest(unittest.TestCase): diff -r 756c27efe193 -r 4d531711cbc7 Misc/NEWS --- a/Misc/NEWS Mon Sep 05 00:01:34 2016 -0400 +++ b/Misc/NEWS Mon Sep 05 10:14:54 2016 -0700 @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #27811: Fix a crash when a coroutine that has not been awaited is + finalized with warnings-as-errors enabled. + - Issue #27587: Fix another issue found by PVS-Studio: Null pointer check after use of 'def' in _PyState_AddModule(). Initial patch by Christian Heimes. diff -r 756c27efe193 -r 4d531711cbc7 Objects/genobject.c --- a/Objects/genobject.c Mon Sep 05 00:01:34 2016 -0400 +++ b/Objects/genobject.c Mon Sep 05 10:14:54 2016 -0700 @@ -24,18 +24,6 @@ PyObject *res; PyObject *error_type, *error_value, *error_traceback; - /* If `gen` is a coroutine, and if it was never awaited on, - issue a RuntimeWarning. */ - if (gen->gi_code != NULL - && ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE - && gen->gi_frame != NULL - && gen->gi_frame->f_lasti == -1 - && !PyErr_Occurred() - && PyErr_WarnFormat(PyExc_RuntimeWarning, 1, - "coroutine '%.50S' was never awaited", - gen->gi_qualname)) - return; - if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL) /* Generator isn't paused, so no need to close */ return; @@ -43,7 +31,20 @@ /* Save the current exception, if any. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); - res = gen_close(gen, NULL); + /* If `gen` is a coroutine, and if it was never awaited on, + issue a RuntimeWarning. */ + if (gen->gi_code != NULL + && ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE + && gen->gi_frame->f_lasti == -1 + && !PyErr_Occurred() + && PyErr_WarnFormat(PyExc_RuntimeWarning, 1, + "coroutine '%.50S' was never awaited", + gen->gi_qualname)) { + res = NULL; /* oops, exception */ + } + else { + res = gen_close(gen, NULL); + } if (res == NULL) PyErr_WriteUnraisable(self); /benjamin@python.org