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

This commit is contained in:
Pablo Galindo 2020-01-14 12:06:45 +00:00 committed by GitHub
parent 1d1b97ae64
commit a2ec3f07f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 75 additions and 1 deletions

View File

@ -177,6 +177,27 @@ The :mod:`gc` module provides the following functions:
.. versionadded:: 3.1 .. 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() .. function:: freeze()
Freeze all the objects tracked by gc - move them to a permanent generation Freeze all the objects tracked by gc - move them to a permanent generation

View File

@ -174,6 +174,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 been executed), do not block the collection of all objects that are still
unreachable. (Contributed by Pablo Galindo and Tim Peters in :issue:`38379`.) 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 imaplib
------- -------

View File

@ -586,6 +586,24 @@ class GCTests(unittest.TestCase):
self.assertFalse(gc.is_tracked(UserFloatSlots())) self.assertFalse(gc.is_tracked(UserFloatSlots()))
self.assertFalse(gc.is_tracked(UserIntSlots())) 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): def test_bug1055820b(self):
# Corresponds to temp2b.py in the bug report. # Corresponds to temp2b.py in the bug report.

View File

@ -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.

View File

@ -304,6 +304,15 @@ PyDoc_STRVAR(gc_is_tracked__doc__,
#define GC_IS_TRACKED_METHODDEF \ #define GC_IS_TRACKED_METHODDEF \
{"is_tracked", (PyCFunction)gc_is_tracked, METH_O, gc_is_tracked__doc__}, {"is_tracked", (PyCFunction)gc_is_tracked, METH_O, gc_is_tracked__doc__},
PyDoc_STRVAR(gc_is_finalized__doc__,
"is_finalized($module, obj, /)\n"
"--\n"
"\n"
"Returns true if the object has been already finalized by the GC.");
#define GC_IS_FINALIZED_METHODDEF \
{"is_finalized", (PyCFunction)gc_is_finalized, METH_O, gc_is_finalized__doc__},
PyDoc_STRVAR(gc_freeze__doc__, PyDoc_STRVAR(gc_freeze__doc__,
"freeze($module, /)\n" "freeze($module, /)\n"
"--\n" "--\n"
@ -373,4 +382,4 @@ gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored))
exit: exit:
return return_value; return return_value;
} }
/*[clinic end generated code: output=e40d384b1f0d513c input=a9049054013a1b77]*/ /*[clinic end generated code: output=bd6a8056989e2e69 input=a9049054013a1b77]*/

View File

@ -1869,6 +1869,25 @@ gc_is_tracked(PyObject *module, PyObject *obj)
return result; 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] /*[clinic input]
gc.freeze gc.freeze
@ -1961,6 +1980,7 @@ static PyMethodDef GcMethods[] = {
GC_GET_OBJECTS_METHODDEF GC_GET_OBJECTS_METHODDEF
GC_GET_STATS_METHODDEF GC_GET_STATS_METHODDEF
GC_IS_TRACKED_METHODDEF GC_IS_TRACKED_METHODDEF
GC_IS_FINALIZED_METHODDEF
{"get_referrers", gc_get_referrers, METH_VARARGS, {"get_referrers", gc_get_referrers, METH_VARARGS,
gc_get_referrers__doc__}, gc_get_referrers__doc__},
{"get_referents", gc_get_referents, METH_VARARGS, {"get_referents", gc_get_referents, METH_VARARGS,