mirror of
https://github.com/python/cpython.git
synced 2025-09-18 22:50:26 +00:00
gh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternatives (in Objects/) (#102218)
This commit is contained in:
parent
b097925858
commit
11a2c6ce51
8 changed files with 51 additions and 106 deletions
|
@ -69,8 +69,6 @@ void
|
|||
_PyGen_Finalize(PyObject *self)
|
||||
{
|
||||
PyGenObject *gen = (PyGenObject *)self;
|
||||
PyObject *res = NULL;
|
||||
PyObject *error_type, *error_value, *error_traceback;
|
||||
|
||||
if (gen->gi_frame_state >= FRAME_COMPLETED) {
|
||||
/* Generator isn't paused, so no need to close */
|
||||
|
@ -82,23 +80,22 @@ _PyGen_Finalize(PyObject *self)
|
|||
PyObject *finalizer = agen->ag_origin_or_finalizer;
|
||||
if (finalizer && !agen->ag_closed) {
|
||||
/* Save the current exception, if any. */
|
||||
PyErr_Fetch(&error_type, &error_value, &error_traceback);
|
||||
|
||||
res = PyObject_CallOneArg(finalizer, self);
|
||||
PyObject *exc = PyErr_GetRaisedException();
|
||||
|
||||
PyObject *res = PyObject_CallOneArg(finalizer, self);
|
||||
if (res == NULL) {
|
||||
PyErr_WriteUnraisable(self);
|
||||
} else {
|
||||
Py_DECREF(res);
|
||||
}
|
||||
/* Restore the saved exception. */
|
||||
PyErr_Restore(error_type, error_value, error_traceback);
|
||||
PyErr_SetRaisedException(exc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the current exception, if any. */
|
||||
PyErr_Fetch(&error_type, &error_value, &error_traceback);
|
||||
PyObject *exc = PyErr_GetRaisedException();
|
||||
|
||||
/* If `gen` is a coroutine, and if it was never awaited on,
|
||||
issue a RuntimeWarning. */
|
||||
|
@ -109,20 +106,19 @@ _PyGen_Finalize(PyObject *self)
|
|||
_PyErr_WarnUnawaitedCoroutine((PyObject *)gen);
|
||||
}
|
||||
else {
|
||||
res = gen_close(gen, NULL);
|
||||
}
|
||||
|
||||
if (res == NULL) {
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_WriteUnraisable(self);
|
||||
PyObject *res = gen_close(gen, NULL);
|
||||
if (res == NULL) {
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_WriteUnraisable(self);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Py_DECREF(res);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Py_DECREF(res);
|
||||
}
|
||||
|
||||
/* Restore the saved exception. */
|
||||
PyErr_Restore(error_type, error_value, error_traceback);
|
||||
PyErr_SetRaisedException(exc);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -648,39 +644,11 @@ _PyGen_SetStopIterationValue(PyObject *value)
|
|||
int
|
||||
_PyGen_FetchStopIterationValue(PyObject **pvalue)
|
||||
{
|
||||
PyObject *et, *ev, *tb;
|
||||
PyObject *value = NULL;
|
||||
|
||||
if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
|
||||
PyErr_Fetch(&et, &ev, &tb);
|
||||
if (ev) {
|
||||
/* exception will usually be normalised already */
|
||||
if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
|
||||
value = Py_NewRef(((PyStopIterationObject *)ev)->value);
|
||||
Py_DECREF(ev);
|
||||
} else if (et == PyExc_StopIteration && !PyTuple_Check(ev)) {
|
||||
/* Avoid normalisation and take ev as value.
|
||||
*
|
||||
* Normalization is required if the value is a tuple, in
|
||||
* that case the value of StopIteration would be set to
|
||||
* the first element of the tuple.
|
||||
*
|
||||
* (See _PyErr_CreateException code for details.)
|
||||
*/
|
||||
value = ev;
|
||||
} else {
|
||||
/* normalisation required */
|
||||
PyErr_NormalizeException(&et, &ev, &tb);
|
||||
if (!PyObject_TypeCheck(ev, (PyTypeObject *)PyExc_StopIteration)) {
|
||||
PyErr_Restore(et, ev, tb);
|
||||
return -1;
|
||||
}
|
||||
value = Py_NewRef(((PyStopIterationObject *)ev)->value);
|
||||
Py_DECREF(ev);
|
||||
}
|
||||
}
|
||||
Py_XDECREF(et);
|
||||
Py_XDECREF(tb);
|
||||
PyObject *exc = PyErr_GetRaisedException();
|
||||
value = Py_NewRef(((PyStopIterationObject *)exc)->value);
|
||||
Py_DECREF(exc);
|
||||
} else if (PyErr_Occurred()) {
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue