diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2022-07-11 13:17:32 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-11 13:17:32 (GMT) |
commit | 91176d38836cceb0d8e6d8cf5dfe7fe089b821ae (patch) | |
tree | 1a4475de8eb34f4bcbcb696a7f2ea08f8484df4a /Modules | |
parent | 8464e4ae8300d6e600cd192884552ab634155625 (diff) | |
download | cpython-91176d38836cceb0d8e6d8cf5dfe7fe089b821ae.zip cpython-91176d38836cceb0d8e6d8cf5dfe7fe089b821ae.tar.gz cpython-91176d38836cceb0d8e6d8cf5dfe7fe089b821ae.tar.bz2 |
[3.11] bpo-45924: Fix asyncio incorrect traceback when future's exception is raised multiple times (GH-30274) (#94747)
Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_asynciomodule.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 5fa7223..eae468d 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -70,6 +70,7 @@ typedef enum { PyObject *prefix##_context0; \ PyObject *prefix##_callbacks; \ PyObject *prefix##_exception; \ + PyObject *prefix##_exception_tb; \ PyObject *prefix##_result; \ PyObject *prefix##_source_tb; \ PyObject *prefix##_cancel_msg; \ @@ -495,6 +496,7 @@ future_init(FutureObj *fut, PyObject *loop) Py_CLEAR(fut->fut_callbacks); Py_CLEAR(fut->fut_result); Py_CLEAR(fut->fut_exception); + Py_CLEAR(fut->fut_exception_tb); Py_CLEAR(fut->fut_source_tb); Py_CLEAR(fut->fut_cancel_msg); Py_CLEAR(fut->fut_cancelled_exc); @@ -601,7 +603,9 @@ future_set_exception(FutureObj *fut, PyObject *exc) } assert(!fut->fut_exception); + assert(!fut->fut_exception_tb); fut->fut_exception = exc_val; + fut->fut_exception_tb = PyException_GetTraceback(exc_val); fut->fut_state = STATE_FINISHED; if (future_schedule_callbacks(fut) == -1) { @@ -656,8 +660,16 @@ future_get_result(FutureObj *fut, PyObject **result) fut->fut_log_tb = 0; if (fut->fut_exception != NULL) { + PyObject *tb = fut->fut_exception_tb; + if (tb == NULL) { + tb = Py_None; + } + if (PyException_SetTraceback(fut->fut_exception, tb) < 0) { + return -1; + } Py_INCREF(fut->fut_exception); *result = fut->fut_exception; + Py_CLEAR(fut->fut_exception_tb); return 1; } @@ -799,6 +811,7 @@ FutureObj_clear(FutureObj *fut) Py_CLEAR(fut->fut_callbacks); Py_CLEAR(fut->fut_result); Py_CLEAR(fut->fut_exception); + Py_CLEAR(fut->fut_exception_tb); Py_CLEAR(fut->fut_source_tb); Py_CLEAR(fut->fut_cancel_msg); Py_CLEAR(fut->fut_cancelled_exc); @@ -815,6 +828,7 @@ FutureObj_traverse(FutureObj *fut, visitproc visit, void *arg) Py_VISIT(fut->fut_callbacks); Py_VISIT(fut->fut_result); Py_VISIT(fut->fut_exception); + Py_VISIT(fut->fut_exception_tb); Py_VISIT(fut->fut_source_tb); Py_VISIT(fut->fut_cancel_msg); Py_VISIT(fut->fut_cancelled_exc); |