From: Victor Stinner Date: Thu, 21 Apr 2022 14:01:47 +0000 (+0200) Subject: gh-89653: PEP 670: Convert PyWeakref_GET_OBJECT() to function (#91785) X-Git-Tag: v3.11.0b1~271 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1a2b282f201073d5153e737568c833af6f1b349e;p=thirdparty%2FPython%2Fcpython.git gh-89653: PEP 670: Convert PyWeakref_GET_OBJECT() to function (#91785) 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. --- diff --git a/Include/cpython/weakrefobject.h b/Include/cpython/weakrefobject.h index 3623071cdb04..1078fffc2e0a 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))