diff options
-rw-r--r-- | Doc/library/gc.rst | 21 | ||||
-rw-r--r-- | Doc/whatsnew/3.9.rst | 4 | ||||
-rw-r--r-- | Lib/test/test_gc.py | 18 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2020-01-13-15-18-13.bpo-39322.aAs-1T.rst | 2 | ||||
-rw-r--r-- | Modules/clinic/gcmodule.c.h | 11 | ||||
-rw-r--r-- | Modules/gcmodule.c | 20 |
6 files changed, 75 insertions, 1 deletions
diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst index 13eda91..0c33c86 100644 --- a/Doc/library/gc.rst +++ b/Doc/library/gc.rst @@ -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 diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 00409af..c949999 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -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 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 ------- diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py index c0d4a75..18f8d10 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@ -586,6 +586,24 @@ class GCTests(unittest.TestCase): 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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-13-15-18-13.bpo-39322.aAs-1T.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-13-15-18-13.bpo-39322.aAs-1T.rst new file mode 100644 index 0000000..60df44c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-01-13-15-18-13.bpo-39322.aAs-1T.rst @@ -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. diff --git a/Modules/clinic/gcmodule.c.h b/Modules/clinic/gcmodule.c.h index 22d2aa4..72795c6 100644 --- a/Modules/clinic/gcmodule.c.h +++ b/Modules/clinic/gcmodule.c.h @@ -304,6 +304,15 @@ PyDoc_STRVAR(gc_is_tracked__doc__, #define GC_IS_TRACKED_METHODDEF \ {"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__, "freeze($module, /)\n" "--\n" @@ -373,4 +382,4 @@ gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=e40d384b1f0d513c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bd6a8056989e2e69 input=a9049054013a1b77]*/ diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 5fef114..4ad9d22 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -1870,6 +1870,25 @@ gc_is_tracked(PyObject *module, PyObject *obj) } /*[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 Freeze all current tracked objects and ignore them for future collections. @@ -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, |