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.
|
scheme.
|
||||||
|
|
||||||
Cyclic isolate (CI)
|
Cyclic isolate (CI)
|
||||||
A reference cycle in which no object is referenced from outside the
|
A standalone subgraph of objects in which no object is referenced
|
||||||
cycle *and* whose objects are still in a usable, non-broken state:
|
from the outside, containing one or several reference cycles, *and*
|
||||||
they can access each other from their respective finalizers.
|
whose objects are still in a usable, non-broken state: they can
|
||||||
|
access each other from their respective finalizers.
|
||||||
|
|
||||||
Cyclic garbage collector (GC)
|
Cyclic garbage collector (GC)
|
||||||
A device able to detect cyclic isolates and turn them into cyclic
|
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.
|
reference counts dropping to zero.
|
||||||
|
|
||||||
Cyclic trash (CT)
|
Cyclic trash (CT)
|
||||||
A reference cycle, or former reference cycle, in which no object
|
A former cyclic isolate whose objects have started being cleared
|
||||||
is referenced from outside the cycle *and* whose objects have
|
by the GC. Objects in cyclic trash are potential zombies; if they
|
||||||
started being cleared by the GC. Objects in cyclic trash are
|
are accessed by Python code, the symptoms can vary from weird
|
||||||
potential zombies; if they are accessed by Python code, the symptoms
|
AttributeErrors to crashes.
|
||||||
can vary from weird AttributeErrors to crashes.
|
|
||||||
|
|
||||||
Zombie / broken object
|
Zombie / broken object
|
||||||
An object part of cyclic trash. The term stresses that the 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
|
(as a side-effect of clearing references); this collection is
|
||||||
finished.
|
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
|
C-level changes
|
||||||
===============
|
===============
|
||||||
|
|
||||||
Type objects get a new ``tp_finalize`` slot to which ``__del__`` methods
|
Type objects get a new ``tp_finalize`` slot to which ``__del__`` methods
|
||||||
are bound. Generators are also modified to use this slot, rather than
|
are mapped (and reciprocally). Generators are modified to use this slot,
|
||||||
``tp_del``. At the C level, a ``tp_finalize`` function is a normal
|
rather than ``tp_del``. A ``tp_finalize`` function is a normal C
|
||||||
function which will be called with a regular, alive object as its only
|
function which will be called with a valid and alive ``PyObject`` as its
|
||||||
argument. It should not attempt to revive or collect the object.
|
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
|
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,
|
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
|
``tp_del`` is not encountered anymore in the CPython source tree (except
|
||||||
for testing purposes).
|
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
|
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
|
objects to signal that they were finalized. This helps avoid finalizing
|
||||||
an object twice (and, especially, finalizing a CT object after it was
|
an object twice (and, especially, finalizing a CT object after it was
|
||||||
broken by the GC).
|
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
|
Discussion
|
||||||
==========
|
==========
|
||||||
|
@ -186,7 +201,7 @@ Predictability
|
||||||
|
|
||||||
Following this scheme, an object's finalizer is always called exactly
|
Following this scheme, an object's finalizer is always called exactly
|
||||||
once. The only exception is if an object is resurrected: the finalizer
|
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)
|
For CI objects, the order in which finalizers are called (step 2 above)
|
||||||
is undefined.
|
is undefined.
|
||||||
|
|
Loading…
Reference in New Issue