Skip to content

bpo-39322: Add gc.is_finalized to check if an object has been finalised by the gc #17989

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Doc/library/gc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,27 @@ The :mod:`gc` module provides the following functions:
.. versionadded:: 3.1


.. function:: is_finalized(obj)

Returns ``True`` if the given object has been finalized by the
garbage collector, ``False`` otherwise. ::

>>> x = None
>>> class Lazarus:
... def __del__(self):
... global x
... x = self
...
>>> lazarus = Lazarus()
>>> gc.is_finalized(lazarus)
False
>>> del lazarus
>>> gc.is_finalized(x)
True

.. versionadded:: 3.9


.. function:: freeze()

Freeze all the objects tracked by gc - move them to a permanent generation
Expand Down
4 changes: 4 additions & 0 deletions Doc/whatsnew/3.9.rst
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ When the garbage collector makes a collection in which some objects resurrect
been executed), do not block the collection of all objects that are still
unreachable. (Contributed by Pablo Galindo and Tim Peters in :issue:`38379`.)

Added a new function :func:`gc.is_finalized` to check if an object has been
finalized by the garbage collector. (Contributed by Pablo Galindo in
:issue:`39322`.)

imaplib
-------

Expand Down
18 changes: 18 additions & 0 deletions Lib/test/test_gc.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,24 @@ class UserIntSlots(int):
self.assertFalse(gc.is_tracked(UserFloatSlots()))
self.assertFalse(gc.is_tracked(UserIntSlots()))

def test_is_finalized(self):
# Objects not tracked by the always gc return false
self.assertFalse(gc.is_finalized(3))

storage = []
class Lazarus:
def __del__(self):
storage.append(self)

lazarus = Lazarus()
self.assertFalse(gc.is_finalized(lazarus))

del lazarus
gc.collect()

lazarus = storage.pop()
self.assertTrue(gc.is_finalized(lazarus))

def test_bug1055820b(self):
# Corresponds to temp2b.py in the bug report.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Added a new function :func:`gc.is_finalized` to check if an object has been
finalized by the garbage collector. Patch by Pablo Galindo.
11 changes: 10 additions & 1 deletion Modules/clinic/gcmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions Modules/gcmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1869,6 +1869,25 @@ gc_is_tracked(PyObject *module, PyObject *obj)
return result;
}

/*[clinic input]
gc.is_finalized

obj: object
/

Returns true if the object has been already finalized by the GC.
[clinic start generated code]*/

static PyObject *
gc_is_finalized(PyObject *module, PyObject *obj)
/*[clinic end generated code: output=e1516ac119a918ed input=201d0c58f69ae390]*/
{
if (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(AS_GC(obj))) {
Py_RETURN_TRUE;
}
Py_RETURN_FALSE;
}

/*[clinic input]
gc.freeze

Expand Down Expand Up @@ -1961,6 +1980,7 @@ static PyMethodDef GcMethods[] = {
GC_GET_OBJECTS_METHODDEF
GC_GET_STATS_METHODDEF
GC_IS_TRACKED_METHODDEF
GC_IS_FINALIZED_METHODDEF
{"get_referrers", gc_get_referrers, METH_VARARGS,
gc_get_referrers__doc__},
{"get_referents", gc_get_referents, METH_VARARGS,
Expand Down