]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-89653: PEP 670: Convert PyWeakref_GET_OBJECT() to function (#91785)
authorVictor Stinner <vstinner@python.org>
Thu, 21 Apr 2022 14:01:47 +0000 (16:01 +0200)
committerGitHub <noreply@github.com>
Thu, 21 Apr 2022 14:01:47 +0000 (16:01 +0200)
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

index 3623071cdb04420a22ab6775fd80fe2af9f6f002..1078fffc2e0a5fd33cfbba4a23ddfa1fea646a75 100644 (file)
@@ -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))