Commit 0bce59db authored by Fred Drake's avatar Fred Drake

Added discussion of protecting against screwing up the exception state in

an object's deallocator, including an example of how to do this.
parent f8ec822f
......@@ -449,6 +449,11 @@ will implement.
\subsection{Finalization and De-allocation}
\index{object!deallocation}
\index{deallocation, object}
\index{object!finalization}
\index{finalization, of objects}
\begin{verbatim}
destructor tp_dealloc;
\end{verbatim}
......@@ -468,6 +473,49 @@ newdatatype_dealloc(newdatatypeobject * obj)
}
\end{verbatim}
One important requirement of the deallocator function is that it
leaves any pending exceptions alone. This is important since
deallocators are frequently called as the interpreter unwinds the
Python stack; when the stack is unwound due to an exception (rather
than normal returns), nothing is done to protect the deallocators from
seeing that an exception has already been set. Any actions which a
deallocator performs which may cause additional Python code to be
executed may detect that an exception has been set. This can lead to
misleading errors from the interpreter. The proper way to protect
against this is to save a pending exception before performing the
unsafe action, and restoring it when done. This can be done using the
\cfunction{PyErr_Fetch()}\ttindex{PyErr_Fetch()} and
\cfunction{PyErr_Restore()}\ttindex{PyErr_Restore()} functions:
\begin{verbatim}
static void
my_dealloc(PyObject *obj)
{
MyObject *self = (MyObject *) obj;
PyObject *cbresult;
if (self->my_callback != NULL) {
PyObject *err_type, *err_value, *err_traceback;
int have_error = PyErr_Occurred() ? 1 : 0;
if (have_error)
PyErr_Fetch(&err_type, &err_value, &err_traceback);
cbresult = PyObject_CallObject(self->my_callback, NULL);
if (cbresult == NULL)
PyErr_WriteUnraisable();
else
Py_DECREF(cbresult);
if (have_error)
PyErr_Restore(err_type, err_value, err_traceback);
Py_DECREF(self->my_callback);
}
PyObject_DEL(obj);
}
\end{verbatim}
\subsection{Object Representation}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment