From f13072b8a89a922285737988b086beb4b06c6648 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sat, 11 Apr 2020 01:21:54 +0100 Subject: bpo-40241: Add PyObject_GC_IsTracked and PyObject_GC_IsFinalized to the public C-API (GH-19461) 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 | 18 ++++++++++++++++++ Doc/whatsnew/3.9.rst | 7 +++++++ Include/objimpl.h | 2 ++ .../C API/2020-04-10-19-43-04.bpo-40241.Xm3w-1.rst | 4 ++++ Modules/_testcapimodule.c | 2 +- Modules/gcmodule.c | 18 ++++++++++++++++++ 6 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/C API/2020-04-10-19-43-04.bpo-40241.Xm3w-1.rst diff --git a/Doc/c-api/gcsupport.rst b/Doc/c-api/gcsupport.rst index 924a7fd..4cab0f5 100644 --- a/Doc/c-api/gcsupport.rst +++ b/Doc/c-api/gcsupport.rst @@ -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: diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index e49d426..3beb721 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -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 ========== diff --git a/Include/objimpl.h b/Include/objimpl.h index 6e7549c..030d7ee 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -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 index 0000000..0ade4a5 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-04-10-19-43-04.bpo-40241.Xm3w-1.rst @@ -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. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 3cc5586..0a30fea 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -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 diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 1bc41fb..1754182 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -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; +} -- cgit v0.12