Skip to content

Commit

Permalink
gh-89653: PEP 670: Convert PyWeakref_GET_OBJECT() to function (#91785)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
vstinner authored Apr 21, 2022
1 parent f2b4e45 commit 1a2b282
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions Include/cpython/weakrefobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))

0 comments on commit 1a2b282

Please sign in to comment.