Mailing List Archive

bpo-45711: [asyncio] Normalize exceptions immediately after Fetch, before they are stored as StackItem, which should be normalized (GH-29890)
https://github.com/python/cpython/commit/2ff758bd1a144ee712e96ae1db91f476c3b252bb
commit: 2ff758bd1a144ee712e96ae1db91f476c3b252bb
branch: main
author: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>
committer: iritkatriel <1055913+iritkatriel@users.noreply.github.com>
date: 2021-12-03T19:05:14Z
summary:

bpo-45711: [asyncio] Normalize exceptions immediately after Fetch, before they are stored as StackItem, which should be normalized (GH-29890)

files:
A Misc/NEWS.d/next/Library/2021-12-02-17-22-06.bpo-45711.D6jsdv.rst
M Modules/_asynciomodule.c

diff --git a/Misc/NEWS.d/next/Library/2021-12-02-17-22-06.bpo-45711.D6jsdv.rst b/Misc/NEWS.d/next/Library/2021-12-02-17-22-06.bpo-45711.D6jsdv.rst
new file mode 100644
index 0000000000000..b2b57730c3ba8
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-12-02-17-22-06.bpo-45711.D6jsdv.rst
@@ -0,0 +1 @@
+Make :mod:`asyncio` normalize exceptions as soon as they are captured with :c:func:`PyErr_Fetch`, and before they are stored as an exc_info triplet. This brings :mod:`asyncio` in line with the rest of the codebase, where an exc_info triplet is always normalized.
\ No newline at end of file
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index df6644ba248ed..267faacde8a17 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -2702,6 +2702,11 @@ task_step_impl(TaskObj *task, PyObject *exc)
if (PyErr_ExceptionMatches(asyncio_CancelledError)) {
/* CancelledError */
PyErr_Fetch(&et, &ev, &tb);
+ assert(et);
+ PyErr_NormalizeException(&et, &ev, &tb);
+ if (tb != NULL) {
+ PyException_SetTraceback(ev, tb);
+ }

FutureObj *fut = (FutureObj*)task;
_PyErr_StackItem *exc_state = &fut->fut_cancelled_exc_state;
@@ -2714,14 +2719,12 @@ task_step_impl(TaskObj *task, PyObject *exc)

/* Some other exception; pop it and call Task.set_exception() */
PyErr_Fetch(&et, &ev, &tb);
-
assert(et);
- if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
- PyErr_NormalizeException(&et, &ev, &tb);
- }
+ PyErr_NormalizeException(&et, &ev, &tb);
if (tb != NULL) {
PyException_SetTraceback(ev, tb);
}
+
o = future_set_exception((FutureObj*)task, ev);
if (!o) {
/* An exception in Task.set_exception() */
@@ -2965,7 +2968,7 @@ task_step(TaskObj *task, PyObject *exc)
PyObject *et, *ev, *tb;
PyErr_Fetch(&et, &ev, &tb);
leave_task(task->task_loop, (PyObject*)task);
- _PyErr_ChainExceptions(et, ev, tb);
+ _PyErr_ChainExceptions(et, ev, tb); /* Normalizes (et, ev, tb) */
return NULL;
}
else {
@@ -3014,8 +3017,10 @@ task_wakeup(TaskObj *task, PyObject *o)
}

PyErr_Fetch(&et, &ev, &tb);
- if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
- PyErr_NormalizeException(&et, &ev, &tb);
+ assert(et);
+ PyErr_NormalizeException(&et, &ev, &tb);
+ if (tb != NULL) {
+ PyException_SetTraceback(ev, tb);
}

result = task_step(task, ev);

_______________________________________________
Python-checkins mailing list
Python-checkins@python.org
https://mail.python.org/mailman/listinfo/python-checkins