]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-40241: Add PyObject_GC_IsTracked and PyObject_GC_IsFinalized to the public C...
authorPablo Galindo <Pablogsal@gmail.com>
Sat, 11 Apr 2020 00:21:54 +0000 (01:21 +0100)
committerGitHub <noreply@github.com>
Sat, 11 Apr 2020 00:21:54 +0000 (01:21 +0100)
Add the functions PyObject_GC_IsTracked and PyObject_GC_IsFinalized to the public API to allow to query if Python objects are being currently tracked or have been already finalized by the garbage collector respectively.

Doc/c-api/gcsupport.rst
Doc/whatsnew/3.9.rst
Include/objimpl.h
Misc/NEWS.d/next/C API/2020-04-10-19-43-04.bpo-40241.Xm3w-1.rst [new file with mode: 0644]
Modules/_testcapimodule.c
Modules/gcmodule.c

index 924a7fd2fda4d563bc3e1743b9de4739c8e3197c..4cab0f544ed811bb2b4edaa645cd42f8dfe4a6b3 100644 (file)
@@ -60,6 +60,24 @@ Constructors for container types must conform to two rules:
    followed by the :c:member:`~PyTypeObject.tp_traverse` handler become valid, usually near the
    end of the constructor.
 
+.. c:function:: int PyObject_GC_IsTracked(PyObject *op)
+
+   Returns 1 if the object type of *op* implements the GC protocol and *op* is being
+   currently tracked by the garbage collector and 0 otherwise.
+
+   This is analogous to the Python function :func:`gc.is_tracked`.
+
+   .. versionadded:: 3.9
+
+
+.. c:function:: int PyObject_GC_IsFinalized(PyObject *op)
+
+   Returns 1 if the object type of *op* implements the GC protocol and *op* has been
+   already finalized by the garbage collector and 0 otherwise.
+
+   This is analogous to the Python function :func:`gc.is_finalized`.
+
+   .. versionadded:: 3.9
 
 Similarly, the deallocator for the object must conform to a similar pair of
 rules:
index e49d4264c6591623a4552f255ee3c9fa9048200c..3beb721ed318e283b587020b2bbc4ebf27236b8e 100644 (file)
@@ -564,6 +564,13 @@ Build and C API Changes
   Windows.
   (Contributed by Zackery Spytz in :issue:`8901`.)
 
+* Add the functions :c:func:`PyObject_GC_IsTracked` and
+  :c:func:`PyObject_GC_IsFinalized` to the public API to allow to query if
+  Python objects are being currently tracked or have been already finalized by
+  the garbage collector respectively. (Contributed by Pablo Galindo in
+  :issue:`40241`.)
+
+
 Deprecated
 ==========
 
index 6e7549c90d210198d1664bafcc0bff446c144d05..030d7eee29723e3e71b869edf36d15b612462bd6 100644 (file)
@@ -186,6 +186,8 @@ PyAPI_FUNC(void) PyObject_GC_Del(void *);
 #define PyObject_GC_NewVar(type, typeobj, n) \
                 ( (type *) _PyObject_GC_NewVar((typeobj), (n)) )
 
+PyAPI_FUNC(int) PyObject_GC_IsTracked(PyObject *);
+PyAPI_FUNC(int) PyObject_GC_IsFinalized(PyObject *);
 
 /* Utility macro to help write tp_traverse functions.
  * To use this macro, the tp_traverse function must name its arguments
diff --git a/Misc/NEWS.d/next/C API/2020-04-10-19-43-04.bpo-40241.Xm3w-1.rst b/Misc/NEWS.d/next/C API/2020-04-10-19-43-04.bpo-40241.Xm3w-1.rst
new file mode 100644 (file)
index 0000000..0ade4a5
--- /dev/null
@@ -0,0 +1,4 @@
+Add the functions :c:func:`PyObject_GC_IsTracked` and
+:c:func:`PyObject_GC_IsFinalized` to the public API to allow to query if
+Python objects are being currently tracked or have been already finalized by
+the garbage collector respectively. Patch by Pablo Galindo.
index 3cc558689b6c18926988610da7cf8d087e5e380f..0a30fea9e8747683c727bf95c4c1775162229f46 100644 (file)
@@ -3588,7 +3588,7 @@ slot_tp_del(PyObject *self)
         _Py_NewReference(self);
         Py_SET_REFCNT(self, refcnt);
     }
-    assert(!PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self));
+    assert(!PyType_IS_GC(Py_TYPE(self)) || PyObject_GC_IsTracked(self));
     /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased
        _Py_RefTotal, so we need to undo that. */
 #ifdef Py_REF_DEBUG
index 1bc41fb83d8a6097f746f7ecf2493d96b3b28363..17541824761a13234d41b37e4fd12448c214586d 100644 (file)
@@ -2312,3 +2312,21 @@ PyObject_GC_Del(void *op)
     }
     PyObject_FREE(g);
 }
+
+int
+PyObject_GC_IsTracked(PyObject* obj)
+{
+    if (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj)) {
+        return 1;
+    }
+    return 0;
+}
+
+int
+PyObject_GC_IsFinalized(PyObject *obj)
+{
+    if (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(AS_GC(obj))) {
+         return 1;
+    }
+    return 0;
+}