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.
This commit is contained in:
Victor Stinner 2022-04-21 16:01:47 +02:00 committed by GitHub
parent f2b4e458b3
commit 1a2b282f20
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -36,13 +36,19 @@ PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head);
PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self); PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self);
/* Explanation for the Py_REFCNT() check: when a weakref's target is part static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj) {
of a long chain of deallocations which triggers the trashcan mechanism, assert(PyWeakref_Check(ref_obj));
clearing the weakrefs can be delayed long after the target's refcount PyWeakReference *ref = (PyWeakReference *)ref_obj;
has dropped to zero. In the meantime, code accessing the weakref will PyObject *obj = ref->wr_object;
be able to "see" the target object even though it is supposed to be // Explanation for the Py_REFCNT() check: when a weakref's target is part
unreachable. See issue #16602. */ // of a long chain of deallocations which triggers the trashcan mechanism,
#define PyWeakref_GET_OBJECT(ref) \ // clearing the weakrefs can be delayed long after the target's refcount
(Py_REFCNT(((PyWeakReference *)(ref))->wr_object) > 0 \ // has dropped to zero. In the meantime, code accessing the weakref will
? ((PyWeakReference *)(ref))->wr_object \ // be able to "see" the target object even though it is supposed to be
: Py_None) // 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))