]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-45711: [asyncio] Normalize exceptions immediately after Fetch, before they are...
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>
Fri, 3 Dec 2021 19:05:14 +0000 (19:05 +0000)
committerGitHub <noreply@github.com>
Fri, 3 Dec 2021 19:05:14 +0000 (19:05 +0000)
Misc/NEWS.d/next/Library/2021-12-02-17-22-06.bpo-45711.D6jsdv.rst [new file with mode: 0644]
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 (file)
index 0000000..b2b5773
--- /dev/null
@@ -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
index df6644ba248ed7afdcfc61bb3da4cb7983839675..267faacde8a1717096631f50df742b6e5613bbaa 100644 (file)
@@ -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);