]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-39322: Add gc.is_finalized to check if an object has been finalised by the gc...
authorPablo Galindo <Pablogsal@gmail.com>
Tue, 14 Jan 2020 12:06:45 +0000 (12:06 +0000)
committerGitHub <noreply@github.com>
Tue, 14 Jan 2020 12:06:45 +0000 (12:06 +0000)
Doc/library/gc.rst
Doc/whatsnew/3.9.rst
Lib/test/test_gc.py
Misc/NEWS.d/next/Core and Builtins/2020-01-13-15-18-13.bpo-39322.aAs-1T.rst [new file with mode: 0644]
Modules/clinic/gcmodule.c.h
Modules/gcmodule.c

index 13eda917b9a801522e2af51e7fa59e1e5985f25d..0c33c865304591ebb8d1e4b8ea6ea4d8309982f9 100644 (file)
@@ -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
index 00409af4387d83dc9b11b42a0cca79b238177d32..c94999999208d8ff3da48ff85b077697be1b94ff 100644 (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
 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
 -------
 
index c0d4a7507ae0d381d56bec6180ad1fb09ba882c0..18f8d10c5ba6ac6a106c12d85c0c915184b296db 100644 (file)
@@ -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 (file)
index 0000000..60df44c
--- /dev/null
@@ -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.
index 22d2aa4a87bcd0a4fbf1b909b20e11f95d645228..72795c66bf7284d8a666e37ae804a5756d8d02f9 100644 (file)
@@ -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]*/
index 5fef114d73ed148fde04ae87a61fa799d83582c1..4ad9d228f5acc474b00f564abf71ae2ee541408d 100644 (file)
@@ -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
 
@@ -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,