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.
This commit is contained in:
Pablo Galindo 2020-04-11 01:21:54 +01:00 committed by GitHub
parent 0361556537
commit f13072b8a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 50 additions and 1 deletions

View 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 followed by the :c:member:`~PyTypeObject.tp_traverse` handler become valid, usually near the
end of the constructor. 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 Similarly, the deallocator for the object must conform to a similar pair of
rules: rules:

View File

@ -564,6 +564,13 @@ Build and C API Changes
Windows. Windows.
(Contributed by Zackery Spytz in :issue:`8901`.) (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 Deprecated
========== ==========

View File

@ -186,6 +186,8 @@ PyAPI_FUNC(void) PyObject_GC_Del(void *);
#define PyObject_GC_NewVar(type, typeobj, n) \ #define PyObject_GC_NewVar(type, typeobj, n) \
( (type *) _PyObject_GC_NewVar((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. /* Utility macro to help write tp_traverse functions.
* To use this macro, the tp_traverse function must name its arguments * To use this macro, the tp_traverse function must name its arguments

View File

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

View File

@ -3588,7 +3588,7 @@ slot_tp_del(PyObject *self)
_Py_NewReference(self); _Py_NewReference(self);
Py_SET_REFCNT(self, refcnt); 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 /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased
_Py_RefTotal, so we need to undo that. */ _Py_RefTotal, so we need to undo that. */
#ifdef Py_REF_DEBUG #ifdef Py_REF_DEBUG

View File

@ -2312,3 +2312,21 @@ PyObject_GC_Del(void *op)
} }
PyObject_FREE(g); 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;
}