summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2022-07-11 13:17:32 (GMT)
committerGitHub <noreply@github.com>2022-07-11 13:17:32 (GMT)
commit91176d38836cceb0d8e6d8cf5dfe7fe089b821ae (patch)
tree1a4475de8eb34f4bcbcb696a7f2ea08f8484df4a /Modules
parent8464e4ae8300d6e600cd192884552ab634155625 (diff)
downloadcpython-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.c14
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);