From: Antoine Pitrou Date: Thu, 1 Aug 2013 19:14:43 +0000 (+0200) Subject: Issue #18589: fix hyperlinking of type slots (tp_*) X-Git-Tag: v3.4.0a1~20 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a68cbfa5561434208d7a822128eeabca50bd7a29;p=python Issue #18589: fix hyperlinking of type slots (tp_*) --- a68cbfa5561434208d7a822128eeabca50bd7a29 diff --cc Doc/c-api/typeobj.rst index ea787de0a2,f8483c7d41..9b94c196ca --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@@ -465,14 -465,6 +465,14 @@@ type objects) *must* have the :attr:`ob :const:`Py_TPFLAGS_HAVE_VERSION_TAG`. + .. data:: Py_TPFLAGS_HAVE_FINALIZE + - This bit is set when the :attr:`tp_finalize` slot is present in the ++ This bit is set when the :c:member:`~PyTypeObject.tp_finalize` slot is present in the + type structure. + + .. versionadded:: 3.4 + + .. c:member:: char* PyTypeObject.tp_doc An optional pointer to a NUL-terminated C string giving the docstring for this @@@ -976,47 -968,6 +976,47 @@@ This field is not inherited; it is calculated fresh by :c:func:`PyType_Ready`. +.. c:member:: destructor PyTypeObject.tp_finalize + + An optional pointer to an instance finalization function. Its signature is + :c:type:`destructor`:: + + void tp_finalize(PyObject *) + - If :attr:`tp_finalize` is set, the interpreter calls it once when ++ If :c:member:`~PyTypeObject.tp_finalize` is set, the interpreter calls it once when + finalizing an instance. It is called either from the garbage + collector (if the instance is part of an isolated reference cycle) or + just before the object is deallocated. Either way, it is guaranteed + to be called before attempting to break reference cycles, ensuring + that it finds the object in a sane state. + - :attr:`tp_finalize` should not mutate the current exception status; ++ :c:member:`~PyTypeObject.tp_finalize` should not mutate the current exception status; + therefore, a recommended way to write a non-trivial finalizer is:: + + static void + local_finalize(PyObject *self) + { + PyObject *error_type, *error_value, *error_traceback; + + /* Save the current exception, if any. */ + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + /* ... */ + + /* Restore the saved exception. */ + PyErr_Restore(error_type, error_value, error_traceback); + } + + For this field to be taken into account (even through inheritance), + you must also set the :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit. + + This field is inherited by subtypes. + + .. versionadded:: 3.4 + + .. seealso:: "Safe object finalization" (:pep:`442`) + + .. c:member:: PyObject* PyTypeObject.tp_cache Unused. Not inherited. Internal use only. diff --cc Doc/extending/newtypes.rst index 003d666564,f65c183add..f981684164 --- a/Doc/extending/newtypes.rst +++ b/Doc/extending/newtypes.rst @@@ -157,10 -157,9 +157,10 @@@ to :const:`Py_TPFLAGS_DEFAULT`. : Py_TPFLAGS_DEFAULT, /* tp_flags */ All types should include this constant in their flags. It enables all of the -members defined by the current version of Python. +members defined until at least Python 3.3. If you need further members, +you will need to OR the corresponding flags. - We provide a doc string for the type in :attr:`tp_doc`. :: + We provide a doc string for the type in :c:member:`~PyTypeObject.tp_doc`. :: "Noddy objects", /* tp_doc */ @@@ -982,22 -980,6 +982,22 @@@ done. This can be done using the :c:fu Py_TYPE(obj)->tp_free((PyObject*)self); } +.. note:: + There are limitations to what you can safely do in a deallocator function. - First, if your type supports garbage collection (using :attr:`tp_traverse` - and/or :attr:`tp_clear`), some of the object's members can have been - cleared or finalized by the time :attr:`tp_dealloc` is called. Second, in - :attr:`tp_dealloc`, your object is in an unstable state: its reference ++ First, if your type supports garbage collection (using :c:member:`~PyTypeObject.tp_traverse` ++ and/or :c:member:`~PyTypeObject.tp_clear`), some of the object's members can have been ++ cleared or finalized by the time :c:member:`~PyTypeObject.tp_dealloc` is called. Second, in ++ :c:member:`~PyTypeObject.tp_dealloc`, your object is in an unstable state: its reference + count is equal to zero. Any call to a non-trivial object or API (as in the - example above) might end up calling :attr:`tp_dealloc` again, causing a ++ example above) might end up calling :c:member:`~PyTypeObject.tp_dealloc` again, causing a + double free and a crash. + + Starting with Python 3.4, it is recommended not to put any complex - finalization code in :attr:`tp_dealloc`, and instead use the new ++ finalization code in :c:member:`~PyTypeObject.tp_dealloc`, and instead use the new + :c:member:`~PyTypeObject.tp_finalize` type method. + + .. seealso:: + :pep:`442` explains the new finalization scheme. .. index:: single: string; object representation