Skip to content

Commit a2ec3f0

Browse files
authored
bpo-39322: Add gc.is_finalized to check if an object has been finalised by the gc (GH-17989)
1 parent 1d1b97a commit a2ec3f0

File tree

6 files changed

+75
-1
lines changed

6 files changed

+75
-1
lines changed

Doc/library/gc.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,27 @@ The :mod:`gc` module provides the following functions:
177177
.. versionadded:: 3.1
178178

179179

180+
.. function:: is_finalized(obj)
181+
182+
Returns ``True`` if the given object has been finalized by the
183+
garbage collector, ``False`` otherwise. ::
184+
185+
>>> x = None
186+
>>> class Lazarus:
187+
... def __del__(self):
188+
... global x
189+
... x = self
190+
...
191+
>>> lazarus = Lazarus()
192+
>>> gc.is_finalized(lazarus)
193+
False
194+
>>> del lazarus
195+
>>> gc.is_finalized(x)
196+
True
197+
198+
.. versionadded:: 3.9
199+
200+
180201
.. function:: freeze()
181202

182203
Freeze all the objects tracked by gc - move them to a permanent generation

Doc/whatsnew/3.9.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ When the garbage collector makes a collection in which some objects resurrect
174174
been executed), do not block the collection of all objects that are still
175175
unreachable. (Contributed by Pablo Galindo and Tim Peters in :issue:`38379`.)
176176

177+
Added a new function :func:`gc.is_finalized` to check if an object has been
178+
finalized by the garbage collector. (Contributed by Pablo Galindo in
179+
:issue:`39322`.)
180+
177181
imaplib
178182
-------
179183

Lib/test/test_gc.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,24 @@ class UserIntSlots(int):
586586
self.assertFalse(gc.is_tracked(UserFloatSlots()))
587587
self.assertFalse(gc.is_tracked(UserIntSlots()))
588588

589+
def test_is_finalized(self):
590+
# Objects not tracked by the always gc return false
591+
self.assertFalse(gc.is_finalized(3))
592+
593+
storage = []
594+
class Lazarus:
595+
def __del__(self):
596+
storage.append(self)
597+
598+
lazarus = Lazarus()
599+
self.assertFalse(gc.is_finalized(lazarus))
600+
601+
del lazarus
602+
gc.collect()
603+
604+
lazarus = storage.pop()
605+
self.assertTrue(gc.is_finalized(lazarus))
606+
589607
def test_bug1055820b(self):
590608
# Corresponds to temp2b.py in the bug report.
591609

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Added a new function :func:`gc.is_finalized` to check if an object has been
2+
finalized by the garbage collector. Patch by Pablo Galindo.

Modules/clinic/gcmodule.c.h

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/gcmodule.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,6 +1869,25 @@ gc_is_tracked(PyObject *module, PyObject *obj)
18691869
return result;
18701870
}
18711871

1872+
/*[clinic input]
1873+
gc.is_finalized
1874+
1875+
obj: object
1876+
/
1877+
1878+
Returns true if the object has been already finalized by the GC.
1879+
[clinic start generated code]*/
1880+
1881+
static PyObject *
1882+
gc_is_finalized(PyObject *module, PyObject *obj)
1883+
/*[clinic end generated code: output=e1516ac119a918ed input=201d0c58f69ae390]*/
1884+
{
1885+
if (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(AS_GC(obj))) {
1886+
Py_RETURN_TRUE;
1887+
}
1888+
Py_RETURN_FALSE;
1889+
}
1890+
18721891
/*[clinic input]
18731892
gc.freeze
18741893
@@ -1961,6 +1980,7 @@ static PyMethodDef GcMethods[] = {
19611980
GC_GET_OBJECTS_METHODDEF
19621981
GC_GET_STATS_METHODDEF
19631982
GC_IS_TRACKED_METHODDEF
1983+
GC_IS_FINALIZED_METHODDEF
19641984
{"get_referrers", gc_get_referrers, METH_VARARGS,
19651985
gc_get_referrers__doc__},
19661986
{"get_referents", gc_get_referents, METH_VARARGS,

0 commit comments

Comments
 (0)