Skip to content

Commit f13072b

Browse files
authored
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.
1 parent 0361556 commit f13072b

File tree

6 files changed

+50
-1
lines changed

6 files changed

+50
-1
lines changed

Doc/c-api/gcsupport.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,24 @@ Constructors for container types must conform to two rules:
6060
followed by the :c:member:`~PyTypeObject.tp_traverse` handler become valid, usually near the
6161
end of the constructor.
6262
63+
.. c:function:: int PyObject_GC_IsTracked(PyObject *op)
64+
65+
Returns 1 if the object type of *op* implements the GC protocol and *op* is being
66+
currently tracked by the garbage collector and 0 otherwise.
67+
68+
This is analogous to the Python function :func:`gc.is_tracked`.
69+
70+
.. versionadded:: 3.9
71+
72+
73+
.. c:function:: int PyObject_GC_IsFinalized(PyObject *op)
74+
75+
Returns 1 if the object type of *op* implements the GC protocol and *op* has been
76+
already finalized by the garbage collector and 0 otherwise.
77+
78+
This is analogous to the Python function :func:`gc.is_finalized`.
79+
80+
.. versionadded:: 3.9
6381
6482
Similarly, the deallocator for the object must conform to a similar pair of
6583
rules:

Doc/whatsnew/3.9.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,13 @@ Build and C API Changes
564564
Windows.
565565
(Contributed by Zackery Spytz in :issue:`8901`.)
566566

567+
* Add the functions :c:func:`PyObject_GC_IsTracked` and
568+
:c:func:`PyObject_GC_IsFinalized` to the public API to allow to query if
569+
Python objects are being currently tracked or have been already finalized by
570+
the garbage collector respectively. (Contributed by Pablo Galindo in
571+
:issue:`40241`.)
572+
573+
567574
Deprecated
568575
==========
569576

Include/objimpl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ PyAPI_FUNC(void) PyObject_GC_Del(void *);
186186
#define PyObject_GC_NewVar(type, typeobj, n) \
187187
( (type *) _PyObject_GC_NewVar((typeobj), (n)) )
188188

189+
PyAPI_FUNC(int) PyObject_GC_IsTracked(PyObject *);
190+
PyAPI_FUNC(int) PyObject_GC_IsFinalized(PyObject *);
189191

190192
/* Utility macro to help write tp_traverse functions.
191193
* To use this macro, the tp_traverse function must name its arguments
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Add the functions :c:func:`PyObject_GC_IsTracked` and
2+
:c:func:`PyObject_GC_IsFinalized` to the public API to allow to query if
3+
Python objects are being currently tracked or have been already finalized by
4+
the garbage collector respectively. Patch by Pablo Galindo.

Modules/_testcapimodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3588,7 +3588,7 @@ slot_tp_del(PyObject *self)
35883588
_Py_NewReference(self);
35893589
Py_SET_REFCNT(self, refcnt);
35903590
}
3591-
assert(!PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self));
3591+
assert(!PyType_IS_GC(Py_TYPE(self)) || PyObject_GC_IsTracked(self));
35923592
/* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased
35933593
_Py_RefTotal, so we need to undo that. */
35943594
#ifdef Py_REF_DEBUG

Modules/gcmodule.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2312,3 +2312,21 @@ PyObject_GC_Del(void *op)
23122312
}
23132313
PyObject_FREE(g);
23142314
}
2315+
2316+
int
2317+
PyObject_GC_IsTracked(PyObject* obj)
2318+
{
2319+
if (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj)) {
2320+
return 1;
2321+
}
2322+
return 0;
2323+
}
2324+
2325+
int
2326+
PyObject_GC_IsFinalized(PyObject *obj)
2327+
{
2328+
if (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(AS_GC(obj))) {
2329+
return 1;
2330+
}
2331+
return 0;
2332+
}

0 commit comments

Comments
 (0)