Fix a definition and add some clarifications
This commit is contained in:
parent
b5146db1e9
commit
3feda9aad7
41
pep-0442.txt
41
pep-0442.txt
|
@ -41,9 +41,10 @@ Reference cycle
|
|||
scheme.
|
||||
|
||||
Cyclic isolate (CI)
|
||||
A reference cycle in which no object is referenced from outside the
|
||||
cycle *and* whose objects are still in a usable, non-broken state:
|
||||
they can access each other from their respective finalizers.
|
||||
A standalone subgraph of objects in which no object is referenced
|
||||
from the outside, containing one or several reference cycles, *and*
|
||||
whose objects are still in a usable, non-broken state: they can
|
||||
access each other from their respective finalizers.
|
||||
|
||||
Cyclic garbage collector (GC)
|
||||
A device able to detect cyclic isolates and turn them into cyclic
|
||||
|
@ -52,11 +53,10 @@ Cyclic garbage collector (GC)
|
|||
reference counts dropping to zero.
|
||||
|
||||
Cyclic trash (CT)
|
||||
A reference cycle, or former reference cycle, in which no object
|
||||
is referenced from outside the cycle *and* whose objects have
|
||||
started being cleared by the GC. Objects in cyclic trash are
|
||||
potential zombies; if they are accessed by Python code, the symptoms
|
||||
can vary from weird AttributeErrors to crashes.
|
||||
A former cyclic isolate whose objects have started being cleared
|
||||
by the GC. Objects in cyclic trash are potential zombies; if they
|
||||
are accessed by Python code, the symptoms can vary from weird
|
||||
AttributeErrors to crashes.
|
||||
|
||||
Zombie / broken object
|
||||
An object part of cyclic trash. The term stresses that the object
|
||||
|
@ -156,15 +156,21 @@ steps are in bold):
|
|||
(as a side-effect of clearing references); this collection is
|
||||
finished.
|
||||
|
||||
.. note::
|
||||
The GC doesn't recalculate the CI after step 2 above, hence the need
|
||||
for step 3 to check that the whole subgraph is still isolated.
|
||||
|
||||
|
||||
C-level changes
|
||||
===============
|
||||
|
||||
Type objects get a new ``tp_finalize`` slot to which ``__del__`` methods
|
||||
are bound. Generators are also modified to use this slot, rather than
|
||||
``tp_del``. At the C level, a ``tp_finalize`` function is a normal
|
||||
function which will be called with a regular, alive object as its only
|
||||
argument. It should not attempt to revive or collect the object.
|
||||
are mapped (and reciprocally). Generators are modified to use this slot,
|
||||
rather than ``tp_del``. A ``tp_finalize`` function is a normal C
|
||||
function which will be called with a valid and alive ``PyObject`` as its
|
||||
only argument. It doesn't need to manipulate the object's reference count,
|
||||
as this will be done by the caller. However, it must ensure that the
|
||||
original exception state is restored before returning to the caller.
|
||||
|
||||
For compatibility, ``tp_del`` is kept in the type structure. Handling
|
||||
of objects with a non-NULL ``tp_del`` is unchanged: when part of a CI,
|
||||
|
@ -172,11 +178,20 @@ they are not finalized and end up in ``gc.garbage``. However, a non-NULL
|
|||
``tp_del`` is not encountered anymore in the CPython source tree (except
|
||||
for testing purposes).
|
||||
|
||||
Two new C API functions are provided to ease calling of ``tp_finalize``,
|
||||
especially from custom deallocators.
|
||||
|
||||
On the internal side, a bit is reserved in the GC header for GC-managed
|
||||
objects to signal that they were finalized. This helps avoid finalizing
|
||||
an object twice (and, especially, finalizing a CT object after it was
|
||||
broken by the GC).
|
||||
|
||||
.. note::
|
||||
Objects which are not GC-enabled can also have a ``tp_finalize`` slot.
|
||||
They don't need the additional bit since their ``tp_finalize`` function
|
||||
can only be called from the deallocator: it therefore cannot be called
|
||||
twice, except when resurrected.
|
||||
|
||||
|
||||
Discussion
|
||||
==========
|
||||
|
@ -186,7 +201,7 @@ Predictability
|
|||
|
||||
Following this scheme, an object's finalizer is always called exactly
|
||||
once. The only exception is if an object is resurrected: the finalizer
|
||||
will be called again later.
|
||||
will be called again when the object becomes unreachable again.
|
||||
|
||||
For CI objects, the order in which finalizers are called (step 2 above)
|
||||
is undefined.
|
||||
|
|
Loading…
Reference in New Issue