]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternatives (in Modules...
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>
Fri, 24 Feb 2023 21:43:03 +0000 (21:43 +0000)
committerGitHub <noreply@github.com>
Fri, 24 Feb 2023 21:43:03 +0000 (21:43 +0000)
18 files changed:
Modules/_asynciomodule.c
Modules/_io/_iomodule.c
Modules/_io/bufferedio.c
Modules/_io/fileio.c
Modules/_io/iobase.c
Modules/_io/textio.c
Modules/_io/winconsoleio.c
Modules/_lsprof.c
Modules/_sqlite/connection.c
Modules/_sqlite/cursor.c
Modules/_testcapi/heaptype.c
Modules/_testcapi/watchers.c
Modules/_testcapimodule.c
Modules/_xxinterpchannelsmodule.c
Modules/_zoneinfo.c
Modules/posixmodule.c
Modules/signalmodule.c
Modules/socketmodule.c

index 21b2ca1971f9b34be37c3080cbf9e749aca0c35e..13d98eedf32f0eb8cd6c06029ab1c8ff8f7b7f24 100644 (file)
@@ -1422,7 +1422,6 @@ _asyncio_Future__make_cancelled_error_impl(FutureObj *self)
 static void
 FutureObj_finalize(FutureObj *fut)
 {
-    PyObject *error_type, *error_value, *error_traceback;
     PyObject *context;
     PyObject *message = NULL;
     PyObject *func;
@@ -1434,7 +1433,7 @@ FutureObj_finalize(FutureObj *fut)
     fut->fut_log_tb = 0;
 
     /* Save the current exception, if any. */
-    PyErr_Fetch(&error_type, &error_value, &error_traceback);
+    PyObject *exc = PyErr_GetRaisedException();
 
     context = PyDict_New();
     if (context == NULL) {
@@ -1476,7 +1475,7 @@ finally:
     Py_XDECREF(message);
 
     /* Restore the saved exception. */
-    PyErr_Restore(error_type, error_value, error_traceback);
+    PyErr_SetRaisedException(exc);
 }
 
 static PyMethodDef FutureType_methods[] = {
@@ -2491,14 +2490,13 @@ TaskObj_finalize(TaskObj *task)
     PyObject *context;
     PyObject *message = NULL;
     PyObject *func;
-    PyObject *error_type, *error_value, *error_traceback;
 
     if (task->task_state != STATE_PENDING || !task->task_log_destroy_pending) {
         goto done;
     }
 
     /* Save the current exception, if any. */
-    PyErr_Fetch(&error_type, &error_value, &error_traceback);
+    PyObject *exc = PyErr_GetRaisedException();
 
     context = PyDict_New();
     if (context == NULL) {
@@ -2541,7 +2539,7 @@ finally:
     Py_XDECREF(message);
 
     /* Restore the saved exception. */
-    PyErr_Restore(error_type, error_value, error_traceback);
+    PyErr_SetRaisedException(exc);
 
 done:
     FutureObj_finalize((FutureObj*)task);
@@ -2766,8 +2764,6 @@ task_step_impl(asyncio_state *state, TaskObj *task, PyObject *exc)
     }
 
     if (gen_status == PYGEN_RETURN || gen_status == PYGEN_ERROR) {
-        PyObject *et, *ev, *tb;
-
         if (result != NULL) {
             /* The error is StopIteration and that means that
                the underlying coroutine has resolved */
@@ -2794,52 +2790,39 @@ task_step_impl(asyncio_state *state, TaskObj *task, PyObject *exc)
 
         if (PyErr_ExceptionMatches(state->asyncio_CancelledError)) {
             /* CancelledError */
-            PyErr_Fetch(&et, &ev, &tb);
-            assert(et);
-            PyErr_NormalizeException(&et, &ev, &tb);
-            if (tb != NULL) {
-                PyException_SetTraceback(ev, tb);
-                Py_DECREF(tb);
-            }
-            Py_XDECREF(et);
+
+            PyObject *exc = PyErr_GetRaisedException();
+            assert(exc);
 
             FutureObj *fut = (FutureObj*)task;
             /* transfer ownership */
-            fut->fut_cancelled_exc = ev;
+            fut->fut_cancelled_exc = exc;
 
             return future_cancel(state, fut, NULL);
         }
 
         /* Some other exception; pop it and call Task.set_exception() */
-        PyErr_Fetch(&et, &ev, &tb);
-        assert(et);
-        PyErr_NormalizeException(&et, &ev, &tb);
-        if (tb != NULL) {
-            PyException_SetTraceback(ev, tb);
-        }
+        PyObject *exc = PyErr_GetRaisedException();
+        assert(exc);
 
-        o = future_set_exception(state, (FutureObj*)task, ev);
+        o = future_set_exception(state, (FutureObj*)task, exc);
         if (!o) {
             /* An exception in Task.set_exception() */
-            Py_DECREF(et);
-            Py_XDECREF(tb);
-            Py_XDECREF(ev);
+            Py_DECREF(exc);
             goto fail;
         }
         assert(o == Py_None);
         Py_DECREF(o);
 
-        if (PyErr_GivenExceptionMatches(et, PyExc_KeyboardInterrupt) ||
-            PyErr_GivenExceptionMatches(et, PyExc_SystemExit))
+        if (PyErr_GivenExceptionMatches(exc, PyExc_KeyboardInterrupt) ||
+            PyErr_GivenExceptionMatches(exc, PyExc_SystemExit))
         {
             /* We've got a KeyboardInterrupt or a SystemError; re-raise it */
-            PyErr_Restore(et, ev, tb);
+            PyErr_SetRaisedException(exc);
             goto fail;
         }
 
-        Py_DECREF(et);
-        Py_XDECREF(tb);
-        Py_XDECREF(ev);
+        Py_DECREF(exc);
 
         Py_RETURN_NONE;
     }
@@ -3059,10 +3042,9 @@ task_step(asyncio_state *state, TaskObj *task, PyObject *exc)
     res = task_step_impl(state, task, exc);
 
     if (res == NULL) {
-        PyObject *et, *ev, *tb;
-        PyErr_Fetch(&et, &ev, &tb);
+        PyObject *exc = PyErr_GetRaisedException();
         leave_task(state, task->task_loop, (PyObject*)task);
-        _PyErr_ChainExceptions(et, ev, tb); /* Normalizes (et, ev, tb) */
+        _PyErr_ChainExceptions1(exc);
         return NULL;
     }
     else {
@@ -3079,7 +3061,6 @@ task_step(asyncio_state *state, TaskObj *task, PyObject *exc)
 static PyObject *
 task_wakeup(TaskObj *task, PyObject *o)
 {
-    PyObject *et, *ev, *tb;
     PyObject *result;
     assert(o);
 
@@ -3111,18 +3092,12 @@ task_wakeup(TaskObj *task, PyObject *o)
         /* exception raised */
     }
 
-    PyErr_Fetch(&et, &ev, &tb);
-    assert(et);
-    PyErr_NormalizeException(&et, &ev, &tb);
-    if (tb != NULL) {
-        PyException_SetTraceback(ev, tb);
-    }
+    PyObject *exc = PyErr_GetRaisedException();
+    assert(exc);
 
-    result = task_step(state, task, ev);
+    result = task_step(state, task, exc);
 
-    Py_DECREF(et);
-    Py_XDECREF(tb);
-    Py_XDECREF(ev);
+    Py_DECREF(exc);
 
     return result;
 }
index 55b6535eb34b66a8e5846992b8f2d27fe5962de3..d8d836b8382eb18367c3da4b75f7727cd7dc2905 100644 (file)
@@ -437,10 +437,9 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
 
   error:
     if (result != NULL) {
-        PyObject *exc, *val, *tb, *close_result;
-        PyErr_Fetch(&exc, &val, &tb);
-        close_result = PyObject_CallMethodNoArgs(result, &_Py_ID(close));
-        _PyErr_ChainExceptions(exc, val, tb);
+        PyObject *exc = PyErr_GetRaisedException();
+        PyObject *close_result = PyObject_CallMethodNoArgs(result, &_Py_ID(close));
+        _PyErr_ChainExceptions1(exc);
         Py_XDECREF(close_result);
         Py_DECREF(result);
     }
index 56491f097100c036699fefcee04ef5b477c7ca9a..960026707fc5ed7133a5dfa6aedc79858749df99 100644 (file)
@@ -472,12 +472,13 @@ buffered_closed_get(buffered *self, void *context)
 static PyObject *
 buffered_close(buffered *self, PyObject *args)
 {
-    PyObject *res = NULL, *exc = NULL, *val, *tb;
+    PyObject *res = NULL;
     int r;
 
     CHECK_INITIALIZED(self)
-    if (!ENTER_BUFFERED(self))
+    if (!ENTER_BUFFERED(self)) {
         return NULL;
+    }
 
     r = buffered_closed(self);
     if (r < 0)
@@ -497,12 +498,16 @@ buffered_close(buffered *self, PyObject *args)
     /* flush() will most probably re-take the lock, so drop it first */
     LEAVE_BUFFERED(self)
     res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush));
-    if (!ENTER_BUFFERED(self))
+    if (!ENTER_BUFFERED(self)) {
         return NULL;
-    if (res == NULL)
-        PyErr_Fetch(&exc, &val, &tb);
-    else
+    }
+    PyObject *exc = NULL;
+    if (res == NULL) {
+        exc = PyErr_GetRaisedException();
+    }
+    else {
         Py_DECREF(res);
+    }
 
     res = PyObject_CallMethodNoArgs(self->raw, &_Py_ID(close));
 
@@ -512,7 +517,7 @@ buffered_close(buffered *self, PyObject *args)
     }
 
     if (exc != NULL) {
-        _PyErr_ChainExceptions(exc, val, tb);
+        _PyErr_ChainExceptions1(exc);
         Py_CLEAR(res);
     }
 
@@ -637,17 +642,14 @@ _set_BlockingIOError(const char *msg, Py_ssize_t written)
 static Py_ssize_t *
 _buffered_check_blocking_error(void)
 {
-    PyObject *t, *v, *tb;
-    PyOSErrorObject *err;
-
-    PyErr_Fetch(&t, &v, &tb);
-    if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
-        PyErr_Restore(t, v, tb);
+    PyObject *exc = PyErr_GetRaisedException();
+    if (exc == NULL || !PyErr_GivenExceptionMatches(exc, PyExc_BlockingIOError)) {
+        PyErr_SetRaisedException(exc);
         return NULL;
     }
-    err = (PyOSErrorObject *) v;
+    PyOSErrorObject *err = (PyOSErrorObject *)exc;
     /* TODO: sanity check (err->written >= 0) */
-    PyErr_Restore(t, v, tb);
+    PyErr_SetRaisedException(exc);
     return &err->written;
 }
 
@@ -749,13 +751,11 @@ _buffered_init(buffered *self)
 int
 _PyIO_trap_eintr(void)
 {
-    PyObject *typ, *val, *tb;
-    PyOSErrorObject *env_err;
-    if (!PyErr_ExceptionMatches(PyExc_OSError))
+    if (!PyErr_ExceptionMatches(PyExc_OSError)) {
         return 0;
-    PyErr_Fetch(&typ, &val, &tb);
-    PyErr_NormalizeException(&typ, &val, &tb);
-    env_err = (PyOSErrorObject *) val;
+    }
+    PyObject *exc = PyErr_GetRaisedException();
+    PyOSErrorObject *env_err = (PyOSErrorObject *)exc;
     assert(env_err != NULL);
     if (env_err->myerrno != NULL) {
         assert(EINTR > 0 && EINTR < INT_MAX);
@@ -764,14 +764,12 @@ _PyIO_trap_eintr(void)
         int myerrno = PyLong_AsLongAndOverflow(env_err->myerrno, &overflow);
         PyErr_Clear();
         if (myerrno == EINTR) {
-            Py_DECREF(typ);
-            Py_DECREF(val);
-            Py_XDECREF(tb);
+            Py_DECREF(exc);
             return 1;
         }
     }
     /* This silences any error set by PyObject_RichCompareBool() */
-    PyErr_Restore(typ, val, tb);
+    PyErr_SetRaisedException(exc);
     return 0;
 }
 
@@ -2228,15 +2226,17 @@ bufferedrwpair_writable(rwpair *self, PyObject *Py_UNUSED(ignored))
 static PyObject *
 bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored))
 {
-    PyObject *exc = NULL, *val, *tb;
+    PyObject *exc = NULL;
     PyObject *ret = _forward_call(self->writer, &_Py_ID(close), NULL);
-    if (ret == NULL)
-        PyErr_Fetch(&exc, &val, &tb);
-    else
+    if (ret == NULL) {
+        exc = PyErr_GetRaisedException();
+    }
+    else {
         Py_DECREF(ret);
+    } 
     ret = _forward_call(self->reader, &_Py_ID(close), NULL);
     if (exc != NULL) {
-        _PyErr_ChainExceptions(exc, val, tb);
+        _PyErr_ChainExceptions1(exc);
         Py_CLEAR(ret);
     }
     return ret;
index f424fb8439d7a875f2d5f51c44115431904fe2b8..35a498ce5a83544f687a3396b059fe58cb5705e6 100644 (file)
@@ -88,14 +88,13 @@ static PyObject *
 fileio_dealloc_warn(fileio *self, PyObject *source)
 {
     if (self->fd >= 0 && self->closefd) {
-        PyObject *exc, *val, *tb;
-        PyErr_Fetch(&exc, &val, &tb);
+        PyObject *exc = PyErr_GetRaisedException();
         if (PyErr_ResourceWarning(source, 1, "unclosed file %R", source)) {
             /* Spurious errors can appear at shutdown */
             if (PyErr_ExceptionMatches(PyExc_Warning))
                 PyErr_WriteUnraisable((PyObject *) self);
         }
-        PyErr_Restore(exc, val, tb);
+        PyErr_SetRaisedException(exc);
     }
     Py_RETURN_NONE;
 }
@@ -140,7 +139,7 @@ _io_FileIO_close_impl(fileio *self)
 /*[clinic end generated code: output=7737a319ef3bad0b input=f35231760d54a522]*/
 {
     PyObject *res;
-    PyObject *exc, *val, *tb;
+    PyObject *exc;
     int rc;
     res = PyObject_CallMethodOneArg((PyObject*)&PyRawIOBase_Type,
                                      &_Py_ID(close), (PyObject *)self);
@@ -148,20 +147,25 @@ _io_FileIO_close_impl(fileio *self)
         self->fd = -1;
         return res;
     }
-    if (res == NULL)
-        PyErr_Fetch(&exc, &val, &tb);
+    if (res == NULL) {
+        exc = PyErr_GetRaisedException();
+    }
     if (self->finalizing) {
         PyObject *r = fileio_dealloc_warn(self, (PyObject *) self);
-        if (r)
+        if (r) {
             Py_DECREF(r);
-        else
+        }
+        else {
             PyErr_Clear();
+        }
     }
     rc = internal_close(self);
-    if (res == NULL)
-        _PyErr_ChainExceptions(exc, val, tb);
-    if (rc < 0)
+    if (res == NULL) {
+        _PyErr_ChainExceptions1(exc);
+    }
+    if (rc < 0) {
         Py_CLEAR(res);
+    }
     return res;
 }
 
@@ -487,10 +491,9 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
     if (!fd_is_own)
         self->fd = -1;
     if (self->fd >= 0) {
-        PyObject *exc, *val, *tb;
-        PyErr_Fetch(&exc, &val, &tb);
+        PyObject *exc = PyErr_GetRaisedException();
         internal_close(self);
-        _PyErr_ChainExceptions(exc, val, tb);
+        _PyErr_ChainExceptions1(exc);
     }
 
  done:
index 7b9391ec54d7324bbea04c5756314b069e4eb2d1..682ed000eb1fd928e3953f3de9c5b87b69efd091 100644 (file)
@@ -220,7 +220,6 @@ static PyObject *
 _io__IOBase_close_impl(PyObject *self)
 /*[clinic end generated code: output=63c6a6f57d783d6d input=f4494d5c31dbc6b7]*/
 {
-    PyObject *res, *exc, *val, *tb;
     int rc, closed = iobase_is_closed(self);
 
     if (closed < 0) {
@@ -230,11 +229,11 @@ _io__IOBase_close_impl(PyObject *self)
         Py_RETURN_NONE;
     }
 
-    res = PyObject_CallMethodNoArgs(self, &_Py_ID(flush));
+    PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(flush));
 
-    PyErr_Fetch(&exc, &val, &tb);
+    PyObject *exc = PyErr_GetRaisedException();
     rc = PyObject_SetAttr(self, &_Py_ID(__IOBase_closed), Py_True);
-    _PyErr_ChainExceptions(exc, val, tb);
+    _PyErr_ChainExceptions1(exc);
     if (rc < 0) {
         Py_CLEAR(res);
     }
@@ -252,11 +251,10 @@ static void
 iobase_finalize(PyObject *self)
 {
     PyObject *res;
-    PyObject *error_type, *error_value, *error_traceback;
     int closed;
 
     /* Save the current exception, if any. */
-    PyErr_Fetch(&error_type, &error_value, &error_traceback);
+    PyObject *exc = PyErr_GetRaisedException();
 
     /* If `closed` doesn't exist or can't be evaluated as bool, then the
        object is probably in an unusable state, so ignore. */
@@ -297,7 +295,7 @@ iobase_finalize(PyObject *self)
     }
 
     /* Restore the saved exception. */
-    PyErr_Restore(error_type, error_value, error_traceback);
+    PyErr_SetRaisedException(exc);
 }
 
 int
index fbf0bf46840374f3f2e680507a83dcc2917f5745..3ff84cb623af743c80da186476a31a45cc478f3e 100644 (file)
@@ -2827,11 +2827,10 @@ finally:
 
 fail:
     if (saved_state) {
-        PyObject *type, *value, *traceback;
-        PyErr_Fetch(&type, &value, &traceback);
+        PyObject *exc = PyErr_GetRaisedException();
         res = PyObject_CallMethodOneArg(
                 self->decoder, &_Py_ID(setstate), saved_state);
-        _PyErr_ChainExceptions(type, value, traceback);
+        _PyErr_ChainExceptions1(exc);
         Py_DECREF(saved_state);
         Py_XDECREF(res);
     }
@@ -3028,24 +3027,28 @@ _io_TextIOWrapper_close_impl(textio *self)
         Py_RETURN_NONE; /* stream already closed */
     }
     else {
-        PyObject *exc = NULL, *val, *tb;
+        PyObject *exc = NULL;
         if (self->finalizing) {
             res = PyObject_CallMethodOneArg(self->buffer, &_Py_ID(_dealloc_warn),
                                             (PyObject *)self);
-            if (res)
+            if (res) {
                 Py_DECREF(res);
-            else
+            }
+            else {
                 PyErr_Clear();
+            }
         }
         res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush));
-        if (res == NULL)
-            PyErr_Fetch(&exc, &val, &tb);
-        else
+        if (res == NULL) {
+            exc = PyErr_GetRaisedException();
+        }
+        else {
             Py_DECREF(res);
+        }
 
         res = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(close));
         if (exc != NULL) {
-            _PyErr_ChainExceptions(exc, val, tb);
+            _PyErr_ChainExceptions1(exc);
             Py_CLEAR(res);
         }
         return res;
index e913d83187461742b1bc21b2c7f7b2e1c0af7808..de07b50f5ce4cbd91ad451c66d2cea6963ababda 100644 (file)
@@ -192,7 +192,7 @@ _io__WindowsConsoleIO_close_impl(winconsoleio *self)
 /*[clinic end generated code: output=27ef95b66c29057b input=68c4e5754f8136c2]*/
 {
     PyObject *res;
-    PyObject *exc, *val, *tb;
+    PyObject *exc;
     int rc;
     res = PyObject_CallMethodOneArg((PyObject*)&PyRawIOBase_Type,
                                     &_Py_ID(close), (PyObject*)self);
@@ -200,13 +200,16 @@ _io__WindowsConsoleIO_close_impl(winconsoleio *self)
         self->fd = -1;
         return res;
     }
-    if (res == NULL)
-        PyErr_Fetch(&exc, &val, &tb);
+    if (res == NULL) {
+        exc = PyErr_GetRaisedException();
+    }
     rc = internal_close(self);
-    if (res == NULL)
-        _PyErr_ChainExceptions(exc, val, tb);
-    if (rc < 0)
+    if (res == NULL) {
+        _PyErr_ChainExceptions1(exc);
+    }
+    if (rc < 0) {
         Py_CLEAR(res);
+    }
     return res;
 }
 
index 3237d796dc29610cfdbb539c3f9effc6497e4284..83d034ae7eed78d57ce354ab22c431f31c52d49c 100644 (file)
@@ -348,8 +348,7 @@ ptrace_enter_call(PyObject *self, void *key, PyObject *userObj)
      * exception, and some of the code under here assumes that
      * PyErr_* is its own to mess around with, so we have to
      * save and restore any current exception. */
-    PyObject *last_type, *last_value, *last_tb;
-    PyErr_Fetch(&last_type, &last_value, &last_tb);
+    PyObject *exc = PyErr_GetRaisedException();
 
     profEntry = getEntry(pObj, key);
     if (profEntry == NULL) {
@@ -374,7 +373,7 @@ ptrace_enter_call(PyObject *self, void *key, PyObject *userObj)
     initContext(pObj, pContext, profEntry);
 
 restorePyerr:
-    PyErr_Restore(last_type, last_value, last_tb);
+    PyErr_SetRaisedException(exc);
 }
 
 static void
index 4c07d5e0b61f8c090cbfab75975d8168751c3255..fb61ef82ef869bf8b109ccc0dcc66d019aa4ef1b 100644 (file)
@@ -908,7 +908,6 @@ final_callback(sqlite3_context *context)
     PyObject* function_result;
     PyObject** aggregate_instance;
     int ok;
-    PyObject *exception, *value, *tb;
 
     aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, 0);
     if (aggregate_instance == NULL) {
@@ -923,7 +922,7 @@ final_callback(sqlite3_context *context)
     }
 
     // Keep the exception (if any) of the last call to step, value, or inverse
-    PyErr_Fetch(&exception, &value, &tb);
+    PyObject *exc = PyErr_GetRaisedException();
 
     callback_context *ctx = (callback_context *)sqlite3_user_data(context);
     assert(ctx != NULL);
@@ -938,7 +937,7 @@ final_callback(sqlite3_context *context)
     }
     if (!ok) {
         int attr_err = PyErr_ExceptionMatches(PyExc_AttributeError);
-        _PyErr_ChainExceptions(exception, value, tb);
+        _PyErr_ChainExceptions1(exc);
 
         /* Note: contrary to the step, value, and inverse callbacks, SQLite
          * does _not_, as of SQLite 3.38.0, propagate errors to sqlite3_step()
@@ -949,7 +948,7 @@ final_callback(sqlite3_context *context)
                 : "user-defined aggregate's 'finalize' method raised error");
     }
     else {
-        PyErr_Restore(exception, value, tb);
+        PyErr_SetRaisedException(exc);
     }
 
 error:
@@ -2274,15 +2273,14 @@ pysqlite_connection_exit_impl(pysqlite_Connection *self, PyObject *exc_type,
         if (commit) {
             /* Commit failed; try to rollback in order to unlock the database.
              * If rollback also fails, chain the exceptions. */
-            PyObject *exc, *val, *tb;
-            PyErr_Fetch(&exc, &val, &tb);
+            PyObject *exc = PyErr_GetRaisedException();
             result = pysqlite_connection_rollback_impl(self);
             if (result == NULL) {
-                _PyErr_ChainExceptions(exc, val, tb);
+                _PyErr_ChainExceptions1(exc);
             }
             else {
                 Py_DECREF(result);
-                PyErr_Restore(exc, val, tb);
+                PyErr_SetRaisedException(exc);
             }
         }
         return NULL;
index 6f7970cf8197a252a589d63ee00a0d67bee16501..caeedbddb8d88bc1e9d664a8f73ddfe5d0203e6d 100644 (file)
@@ -705,11 +705,10 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self,
             Py_DECREF(adapted);
 
             if (rc != SQLITE_OK) {
-                PyObject *exc, *val, *tb;
-                PyErr_Fetch(&exc, &val, &tb);
+                PyObject *exc = PyErr_GetRaisedException();
                 sqlite3 *db = sqlite3_db_handle(self->st);
                 _pysqlite_seterror(state, db);
-                _PyErr_ChainExceptions(exc, val, tb);
+                _PyErr_ChainExceptions1(exc);
                 return;
             }
         }
@@ -765,11 +764,10 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self,
             Py_DECREF(adapted);
 
             if (rc != SQLITE_OK) {
-                PyObject *exc, *val, *tb;
-                PyErr_Fetch(&exc, &val, &tb);
+                PyObject *exc = PyErr_GetRaisedException();
                 sqlite3 *db = sqlite3_db_handle(self->st);
                 _pysqlite_seterror(state, db);
-                _PyErr_ChainExceptions(exc, val, tb);
+                _PyErr_ChainExceptions1(exc);
                 return;
            }
         }
index 39639f7ed048f263b44bd6dacb870f9052c00081..df2a061ed82b068201785a8dd23a4c74c69a2e1e 100644 (file)
@@ -623,16 +623,15 @@ heapctypesubclasswithfinalizer_init(PyObject *self, PyObject *args, PyObject *kw
 static void
 heapctypesubclasswithfinalizer_finalize(PyObject *self)
 {
-    PyObject *error_type, *error_value, *error_traceback, *m;
     PyObject *oldtype = NULL, *newtype = NULL, *refcnt = NULL;
 
     /* Save the current exception, if any. */
-    PyErr_Fetch(&error_type, &error_value, &error_traceback);
+    PyObject *exc = PyErr_GetRaisedException();
 
     if (_testcapimodule == NULL) {
         goto cleanup_finalize;
     }
-    m = PyState_FindModule(_testcapimodule);
+    PyObject *m = PyState_FindModule(_testcapimodule);
     if (m == NULL) {
         goto cleanup_finalize;
     }
@@ -667,7 +666,7 @@ cleanup_finalize:
     Py_XDECREF(refcnt);
 
     /* Restore the saved exception. */
-    PyErr_Restore(error_type, error_value, error_traceback);
+    PyErr_SetRaisedException(exc);
 }
 
 static PyType_Slot HeapCTypeSubclassWithFinalizer_slots[] = {
index 2e8fe1dbf78651a29151586bd9a8f016ed4c799a..d9ace632768ae878b1e5730e7b3015b64374f025 100644 (file)
@@ -389,16 +389,15 @@ allocate_too_many_code_watchers(PyObject *self, PyObject *args)
         watcher_ids[i] = watcher_id;
         num_watchers++;
     }
-    PyObject *type, *value, *traceback;
-    PyErr_Fetch(&type, &value, &traceback);
+    PyObject *exc = PyErr_GetRaisedException();
     for (int i = 0; i < num_watchers; i++) {
         if (PyCode_ClearWatcher(watcher_ids[i]) < 0) {
             PyErr_WriteUnraisable(Py_None);
             break;
         }
     }
-    if (type) {
-        PyErr_Restore(type, value, traceback);
+    if (exc) {
+        PyErr_SetRaisedException(exc);
         return NULL;
     }
     else if (PyErr_Occurred()) {
@@ -578,16 +577,15 @@ allocate_too_many_func_watchers(PyObject *self, PyObject *args)
         watcher_ids[i] = watcher_id;
         num_watchers++;
     }
-    PyObject *type, *value, *traceback;
-    PyErr_Fetch(&type, &value, &traceback);
+    PyObject *exc = PyErr_GetRaisedException();
     for (int i = 0; i < num_watchers; i++) {
         if (PyFunction_ClearWatcher(watcher_ids[i]) < 0) {
             PyErr_WriteUnraisable(Py_None);
             break;
         }
     }
-    if (type) {
-        PyErr_Restore(type, value, traceback);
+    if (exc) {
+        PyErr_SetRaisedException(exc);
         return NULL;
     }
     else if (PyErr_Occurred()) {
index 6bb424282a875d168bc3a400c5933adb48c2f7f0..fc716a3564d39adee966d7fbb4e072db3764893f 100644 (file)
@@ -1611,19 +1611,18 @@ static void
 slot_tp_del(PyObject *self)
 {
     PyObject *del, *res;
-    PyObject *error_type, *error_value, *error_traceback;
 
     /* Temporarily resurrect the object. */
     assert(Py_REFCNT(self) == 0);
     Py_SET_REFCNT(self, 1);
 
     /* Save the current exception, if any. */
-    PyErr_Fetch(&error_type, &error_value, &error_traceback);
+    PyObject *exc = PyErr_GetRaisedException();
 
     PyObject *tp_del = PyUnicode_InternFromString("__tp_del__");
     if (tp_del == NULL) {
         PyErr_WriteUnraisable(NULL);
-        PyErr_Restore(error_type, error_value, error_traceback);
+        PyErr_SetRaisedException(exc);
         return;
     }
     /* Execute __del__ method, if any. */
@@ -1638,7 +1637,7 @@ slot_tp_del(PyObject *self)
     }
 
     /* Restore the saved exception. */
-    PyErr_Restore(error_type, error_value, error_traceback);
+    PyErr_SetRaisedException(exc);
 
     /* Undo the temporary resurrection; can't use DECREF here, it would
      * cause a recursive call.
index 60538c318748647ca7d3e26414ef8d1ce1b42c4a..a0cd4a2363fb53afcbb888d813057fecfb9c0f56 100644 (file)
@@ -100,9 +100,9 @@ add_new_type(PyObject *mod, PyType_Spec *spec, crossinterpdatafunc shared)
 static int
 _release_xid_data(_PyCrossInterpreterData *data, int ignoreexc)
 {
-    PyObject *exctype, *excval, *exctb;
+    PyObject *exc;
     if (ignoreexc) {
-        PyErr_Fetch(&exctype, &excval, &exctb);
+        exc = PyErr_GetRaisedException();
     }
     int res = _PyCrossInterpreterData_Release(data);
     if (res < 0) {
@@ -125,7 +125,7 @@ _release_xid_data(_PyCrossInterpreterData *data, int ignoreexc)
         }
     }
     if (ignoreexc) {
-        PyErr_Restore(exctype, excval, exctb);
+        PyErr_SetRaisedException(exc);
     }
     return res;
 }
index 6e1a37611b61521f90bec716f148bca1852b7dc9..c215a75b804fdb3eb53c3f87ef72fee9650f563a 100644 (file)
@@ -270,10 +270,9 @@ error:
     Py_CLEAR(self);
 cleanup:
     if (file_obj != NULL) {
-        PyObject *exc, *val, *tb;
-        PyErr_Fetch(&exc, &val, &tb);
+        PyObject *exc = PyErr_GetRaisedException();
         PyObject *tmp = PyObject_CallMethod(file_obj, "close", NULL);
-        _PyErr_ChainExceptions(exc, val, tb);
+        _PyErr_ChainExceptions1(exc);
         if (tmp == NULL) {
             Py_CLEAR(self);
         }
index 51aa89ef715a19715d508fe8c8fc5d343f3c59d4..6ea216b3bf5e79ecbfaff92e006849bd22170a85 100644 (file)
@@ -14759,10 +14759,9 @@ ScandirIterator_exit(ScandirIterator *self, PyObject *args)
 static void
 ScandirIterator_finalize(ScandirIterator *iterator)
 {
-    PyObject *error_type, *error_value, *error_traceback;
 
     /* Save the current exception, if any. */
-    PyErr_Fetch(&error_type, &error_value, &error_traceback);
+    PyObject *exc = PyErr_GetRaisedException();
 
     if (!ScandirIterator_is_closed(iterator)) {
         ScandirIterator_closedir(iterator);
@@ -14779,7 +14778,7 @@ ScandirIterator_finalize(ScandirIterator *iterator)
     path_cleanup(&iterator->path);
 
     /* Restore the saved exception. */
-    PyErr_Restore(error_type, error_value, error_traceback);
+    PyErr_SetRaisedException(exc);
 }
 
 static void
index 44a5ecf63e9d1ee1d763e900c9f66ea1fbfcaa99..cd26eca351c0ed5162bc50cb4ba58dc46f7611d0 100644 (file)
@@ -234,14 +234,13 @@ signal_default_int_handler_impl(PyObject *module, int signalnum,
 static int
 report_wakeup_write_error(void *data)
 {
-    PyObject *exc, *val, *tb;
     int save_errno = errno;
     errno = (int) (intptr_t) data;
-    PyErr_Fetch(&exc, &val, &tb);
+    PyObject *exc = PyErr_GetRaisedException();
     PyErr_SetFromErrno(PyExc_OSError);
     _PyErr_WriteUnraisableMsg("when trying to write to the signal wakeup fd",
                               NULL);
-    PyErr_Restore(exc, val, tb);
+    PyErr_SetRaisedException(exc);
     errno = save_errno;
     return 0;
 }
@@ -252,14 +251,13 @@ report_wakeup_send_error(void* data)
 {
     int send_errno = (int) (intptr_t) data;
 
-    PyObject *exc, *val, *tb;
-    PyErr_Fetch(&exc, &val, &tb);
+    PyObject *exc = PyErr_GetRaisedException();
     /* PyErr_SetExcFromWindowsErr() invokes FormatMessage() which
        recognizes the error codes used by both GetLastError() and
        WSAGetLastError */
     PyErr_SetExcFromWindowsErr(PyExc_OSError, send_errno);
     _PyErr_WriteUnraisableMsg("when trying to send to the signal wakeup fd", NULL);
-    PyErr_Restore(exc, val, tb);
+    PyErr_SetRaisedException(exc);
     return 0;
 }
 #endif   /* MS_WINDOWS */
index 2d300f19436b1a08e364aae641666cabf707cc2a..00608be38f61bb6c46093f2c403a30dff6f17487 100644 (file)
@@ -5175,10 +5175,9 @@ static void
 sock_finalize(PySocketSockObject *s)
 {
     SOCKET_T fd;
-    PyObject *error_type, *error_value, *error_traceback;
 
     /* Save the current exception, if any. */
-    PyErr_Fetch(&error_type, &error_value, &error_traceback);
+    PyObject *exc = PyErr_GetRaisedException();
 
     if (s->sock_fd != INVALID_SOCKET) {
         if (PyErr_ResourceWarning((PyObject *)s, 1, "unclosed %R", s)) {
@@ -5202,7 +5201,7 @@ sock_finalize(PySocketSockObject *s)
     }
 
     /* Restore the saved exception. */
-    PyErr_Restore(error_type, error_value, error_traceback);
+    PyErr_SetRaisedException(exc);
 }
 
 static void