Skip to content

bpo-40170: Convert PyObject_IS_GC() macro to a function #19464

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Apr 14, 2020
Merged
6 changes: 6 additions & 0 deletions Doc/c-api/gcsupport.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ 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_IS_GC(PyObject *obj)

Return non-zero if the object have GC head. Return zero otherwise.

.. versionadded:: 3.9


Similarly, the deallocator for the object must conform to a similar pair of
rules:
Expand Down
4 changes: 1 addition & 3 deletions Include/cpython/objimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,7 @@ PyAPI_FUNC(Py_ssize_t) _PyGC_CollectIfEnabled(void);


/* Test if an object has a GC head */
#define PyObject_IS_GC(o) \
(PyType_IS_GC(Py_TYPE(o)) \
&& (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o)))
PyAPI_FUNC(int) PyObject_IS_GC(PyObject *obj);

/* GC information is stored BEFORE the object structure. */
typedef struct {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Convert :c:func:`PyObject_IS_GC` macro to a function to hide
implementation details: the macro test an object have GC head or not.
10 changes: 10 additions & 0 deletions Modules/gcmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2203,6 +2203,16 @@ PyObject_GC_UnTrack(void *op_raw)
}
}

/* Test if an object has a GC head */
int
PyObject_IS_GC(PyObject *obj)
{
if (PyType_IS_GC(Py_TYPE(obj))) {
return (Py_TYPE(obj)->tp_is_gc == NULL || Py_TYPE(obj)->tp_is_gc(obj));
}
return 0;
}

static PyObject *
_PyObject_GC_Alloc(int use_calloc, size_t basicsize)
{
Expand Down