From 3294561a7f3a7f2d13ebc5ae8f8d83afe9ba4718 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 21 Apr 2022 14:23:21 +0200 Subject: [PATCH] gh-89653: PEP 670: Convert PyWeakref_GET_OBJECT() to function Convert the PyWeakref_GET_OBJECT() macro to a static inline function. Add an assertion to check the argument with PyWeakref_Check(). Add a macro converting the argument to PyObject* to prevent emitting new compiler warning. --- Include/cpython/weakrefobject.h | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/Include/cpython/weakrefobject.h b/Include/cpython/weakrefobject.h index 3623071cdb0442..1078fffc2e0a5f 100644 --- a/Include/cpython/weakrefobject.h +++ b/Include/cpython/weakrefobject.h @@ -36,13 +36,19 @@ PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head); PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self); -/* Explanation for the Py_REFCNT() check: when a weakref's target is part - of a long chain of deallocations which triggers the trashcan mechanism, - clearing the weakrefs can be delayed long after the target's refcount - has dropped to zero. In the meantime, code accessing the weakref will - be able to "see" the target object even though it is supposed to be - unreachable. See issue #16602. */ -#define PyWeakref_GET_OBJECT(ref) \ - (Py_REFCNT(((PyWeakReference *)(ref))->wr_object) > 0 \ - ? ((PyWeakReference *)(ref))->wr_object \ - : Py_None) +static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj) { + assert(PyWeakref_Check(ref_obj)); + PyWeakReference *ref = (PyWeakReference *)ref_obj; + PyObject *obj = ref->wr_object; + // Explanation for the Py_REFCNT() check: when a weakref's target is part + // of a long chain of deallocations which triggers the trashcan mechanism, + // clearing the weakrefs can be delayed long after the target's refcount + // has dropped to zero. In the meantime, code accessing the weakref will + // be able to "see" the target object even though it is supposed to be + // unreachable. See issue gh-60806. + if (Py_REFCNT(obj) > 0) { + return obj; + } + return Py_None; +} +#define PyWeakref_GET_OBJECT(ref) PyWeakref_GET_OBJECT(_PyObject_CAST(ref))