This PEP proposes to deal with the current limitations of objectfinalization. The goal is to be able to define and run finalizersfor any object, regardless of their position in the object graph.
This PEP doesn’t call for any change in Python code. Objectswith existing finalizers will benefit automatically.
__del__ method.__del__ methods.While this PEP discusses CPython-specific implementation details, thechange in finalization semantics is expected to affect the Pythonecosystem as a whole. In particular, this PEP obsoletes the currentguideline that “objects with a__del__ method should not be part of areference cycle”.
The primary benefits of this PEP regard objects with finalizers, suchas objects with a__del__ method and generators with afinallyblock. Those objects can now be reclaimed when they are part of areference cycle.
The PEP also paves the way for further benefits:
The PEP doesn’t change the semantics of:
tp_dealloc function.In normal reference-counted disposal, an object’s finalizer is calledjust before the object is deallocated. If the finalizer resurrectsthe object, deallocation is aborted.
However, if the object was already finalized, then the finalizer isn’tcalled. This prevents us from finalizing zombies (see below).
Cyclic isolates are first detected by the garbage collector, and thendisposed of. The detection phase doesn’t change and won’t be describedhere. Disposal of a CI traditionally works in the following order:
tp_clear function).This PEP proposes to turn CI disposal into the following sequence (newsteps are in bold):
tp_clear function).Note
The GC doesn’t recalculate the CI after step 2 above, hence the needfor step 3 to check that the whole subgraph is still isolated.
Type objects get a newtp_finalize slot to which__del__ methodsare mapped (and reciprocally). Generators are modified to use this slot,rather thantp_del. Atp_finalize function is a normal Cfunction which will be called with a valid and alivePyObject as itsonly 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 theoriginal exception state is restored before returning to the caller.
For compatibility,tp_del is kept in the type structure. Handlingof objects with a non-NULLtp_del is unchanged: when part of a CI,they are not finalized and end up ingc.garbage. However, a non-NULLtp_del is not encountered anymore in the CPython source tree (exceptfor testing purposes).
Two new C API functions are provided to ease calling oftp_finalize,especially from custom deallocators.
On the internal side, a bit is reserved in the GC header for GC-managedobjects to signal that they were finalized. This helps avoid finalizingan object twice (and, especially, finalizing a CT object after it wasbroken by the GC).
Note
Objects which are not GC-enabled can also have atp_finalize slot.They don’t need the additional bit since theirtp_finalize functioncan only be called from the deallocator: it therefore cannot be calledtwice, except when resurrected.
Following this scheme, an object’s finalizer is always called exactlyonce, even if it was resurrected afterwards.
For CI objects, the order in which finalizers are called (step 2 above)is undefined.
It is important to explain why the proposed change is safe. Thereare two aspects to be discussed:
Let’s discuss the first issue. We will divide possible cases in twocategories:
Now for the second issue. There are three potential cases:
An implementation is available in branchfinalize of the repositoryathttp://hg.python.org/features/finalize/.
Besides running the normal Python test suite, the implementation addstest cases for various finalization possibilities including reference cycles,object resurrection and legacytp_del slots.
The implementation has also been checked to not produce any regressions onthe following test suites:
Notes about reference cycle collection and weak reference callbacks:http://hg.python.org/cpython/file/4e687d53b645/Modules/gc_weakref.txt
Generator memory leak:http://bugs.python.org/issue17468
Allow objects to decide if they can be collected by GC:http://bugs.python.org/issue9141
Module shutdown procedure based on GChttp://bugs.python.org/issue812369
This document has been placed in the public domain.
Source:https://github.com/python/peps/blob/main/peps/pep-0442.rst
Last modified:2025-02-01 08:59:27 GMT