@@ -449,6 +449,11 @@ \section{Type Methods
449449
450450\subsection {Finalization and De-allocation }
451451
452+ \index {object!deallocation}
453+ \index {deallocation, object}
454+ \index {object!finalization}
455+ \index {finalization, of objects}
456+
452457\begin {verbatim }
453458 destructor tp_dealloc;
454459\end {verbatim }
@@ -468,6 +473,49 @@ \subsection{Finalization and De-allocation}
468473}
469474\end {verbatim }
470475
476+ One important requirement of the deallocator function is that it
477+ leaves any pending exceptions alone. This is important since
478+ deallocators are frequently called as the interpreter unwinds the
479+ Python stack; when the stack is unwound due to an exception (rather
480+ than normal returns), nothing is done to protect the deallocators from
481+ seeing that an exception has already been set. Any actions which a
482+ deallocator performs which may cause additional Python code to be
483+ executed may detect that an exception has been set. This can lead to
484+ misleading errors from the interpreter. The proper way to protect
485+ against this is to save a pending exception before performing the
486+ unsafe action, and restoring it when done. This can be done using the
487+ \cfunction {PyErr_Fetch()}\ttindex {PyErr_Fetch()} and
488+ \cfunction {PyErr_Restore()}\ttindex {PyErr_Restore()} functions:
489+
490+ \begin {verbatim }
491+ static void
492+ my_dealloc(PyObject *obj)
493+ {
494+ MyObject *self = (MyObject *) obj;
495+ PyObject *cbresult;
496+
497+ if (self->my_callback != NULL) {
498+ PyObject *err_type, *err_value, *err_traceback;
499+ int have_error = PyErr_Occurred() ? 1 : 0;
500+
501+ if (have_error)
502+ PyErr_Fetch(&err_type, &err_value, &err_traceback);
503+
504+ cbresult = PyObject_CallObject(self->my_callback, NULL);
505+ if (cbresult == NULL)
506+ PyErr_WriteUnraisable();
507+ else
508+ Py_DECREF(cbresult);
509+
510+ if (have_error)
511+ PyErr_Restore(err_type, err_value, err_traceback);
512+
513+ Py_DECREF(self->my_callback);
514+ }
515+ PyObject_DEL(obj);
516+ }
517+ \end {verbatim }
518+
471519
472520\subsection {Object Representation }
473521
0 commit comments