-
-
Notifications
You must be signed in to change notification settings - Fork 30.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
gh-75459: Doc: C API: Improve object life cycle documentation
* Add "cyclic isolate" to the glossary. * Add a new "Object Life Cycle" page. * Illustrate the order of life cycle functions. * Document `PyObject_CallFinalizer` and `PyObject_CallFinalizerFromDealloc`. * `PyObject_Init` does not call `tp_init`. * `PyObject_New`: * also initializes the memory * does not call `tp_alloc`, `tp_new`, or `tp_init` * should not be used for GC-enabled objects * memory must be freed by `PyObject_Free` * `PyObject_GC_New` memory must be freed by `PyObject_GC_Del`. * Warn that garbage collector functions can be called from any thread. * `tp_finalize` and `tp_clear`: * Only called when there's a cyclic isolate. * Only one object in the cyclic isolate is finalized/cleared at a time. * Clearly warn that they might not be called. * They can optionally be manually called from `tp_dealloc` (via `PyObject_CallFinalizerFromDealloc` in the case of `tp_finalize`). * `tp_finalize`: * Reference `object.__del__`. * The finalizer can resurrect the object. * Suggest `PyErr_GetRaisedException` and `PyErr_SetRaisedException` instead of the deprecated `PyErr_Fetch` and `PyErr_Restore` functions. * Add links to `PyErr_GetRaisedException` and `PyErr_SetRaisedException`. * Suggest using `PyErr_WriteUnraisable` if an exception is raised during finalization. * Rename the example function from `local_finalize` to `foo_finalize` for consistency with the `tp_dealloc` documentation and as a hint that the name isn't special. * Minor wording and sylistic tweaks. * Warn that `tp_finalize` can be called during shutdown.
- Loading branch information
Showing
8 changed files
with
574 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
digraph G { | ||
graph [ | ||
fontname="svg" | ||
fontsize=10.0 | ||
layout="dot" | ||
ranksep=0.25 | ||
] | ||
node [ | ||
fontname="Courier" | ||
fontsize=10.0 | ||
] | ||
edge [ | ||
fontname="Times-Italic" | ||
fontsize=10.0 | ||
] | ||
|
||
"start" [fontname="Times-Italic" shape=plain label=< start > style=invis] | ||
"tp_alloc" [href="typeobj.html#c.PyTypeObject.tp_alloc" target="_top"] | ||
"tp_new" [href="typeobj.html#c.PyTypeObject.tp_new" target="_top"] | ||
"tp_init" [href="typeobj.html#c.PyTypeObject.tp_init" target="_top"] | ||
{ | ||
rank="same" | ||
"alive" [ | ||
fontname="Times-Italic" | ||
label=<alive, ref count > 0> | ||
shape=box | ||
] | ||
"tp_traverse" [ | ||
href="typeobj.html#c.PyTypeObject.tp_traverse" | ||
shape=octagon | ||
target="_top" | ||
] | ||
} | ||
"tp_finalize" [ | ||
href="typeobj.html#c.PyTypeObject.tp_finalize" | ||
shape=octagon | ||
target="_top" | ||
] | ||
"tp_clear" [ | ||
href="typeobj.html#c.PyTypeObject.tp_clear" | ||
shape=octagon | ||
target="_top" | ||
] | ||
"ref0" [ | ||
fontname="Times-Italic" | ||
label=<ref count == 0> | ||
ordering="in" | ||
shape=box | ||
] | ||
"tp_dealloc" [href="typeobj.html#c.PyTypeObject.tp_dealloc" target="_top"] | ||
"tp_free" [href="typeobj.html#c.PyTypeObject.tp_free" target="_top"] | ||
|
||
"start" -> "tp_alloc" | ||
"tp_alloc" -> "tp_new" | ||
"tp_new" -> "tp_init" | ||
"tp_init" -> "alive" | ||
"tp_traverse" -> "alive" | ||
"alive" -> "tp_traverse" | ||
"alive" -> "tp_clear" [label=< cyclic <br/>isolate >] | ||
"alive" -> "tp_finalize" [ | ||
dir="back" | ||
label=< resurrected > | ||
] | ||
"alive" -> "tp_finalize" [label=< cyclic <br/>isolate >] | ||
"tp_finalize" -> "tp_clear" | ||
"tp_finalize" -> "ref0" | ||
"tp_clear" -> "ref0" | ||
"tp_clear" -> "tp_dealloc" [ | ||
dir="back" | ||
label=< optional<br/>direct call > | ||
] | ||
"alive" -> "ref0" | ||
"ref0" -> "tp_dealloc" | ||
"tp_finalize" -> "tp_dealloc" [ | ||
dir="back" | ||
href="lifecycle.html#c.PyObject_CallFinalizerFromDealloc" | ||
label=< | ||
<table border="0" cellborder="0" cellpadding="0" cellspacing="0"> | ||
<tr> | ||
<td rowspan="4"> </td> | ||
<td align="left">optional call to</td> | ||
<td rowspan="4"> </td> | ||
</tr> | ||
<tr> | ||
<td align="left"><font face="Courier">PyObject_Call</font></td> | ||
</tr> | ||
<tr> | ||
<td align="left"><font face="Courier">FinalizerFrom</font></td> | ||
</tr> | ||
<tr><td align="left"><font face="Courier">Dealloc</font></td></tr> | ||
</table> | ||
> | ||
target="_top" | ||
] | ||
"tp_dealloc" -> "tp_free" [label=< directly calls >] | ||
} |
Oops, something went wrong.