diff options
author | Victor Stinner <vstinner@python.org> | 2022-04-21 14:01:47 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-21 14:01:47 (GMT) |
commit | 1a2b282f201073d5153e737568c833af6f1b349e (patch) | |
tree | 81040c44144273aa43c8ad8e5420871b40f6f871 /Include/cpython | |
parent | f2b4e458b3327130e46edb4efe8e1847de09efc5 (diff) | |
download | cpython-1a2b282f201073d5153e737568c833af6f1b349e.zip cpython-1a2b282f201073d5153e737568c833af6f1b349e.tar.gz cpython-1a2b282f201073d5153e737568c833af6f1b349e.tar.bz2 |
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.
Diffstat (limited to 'Include/cpython')
-rw-r--r-- | Include/cpython/weakrefobject.h | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/Include/cpython/weakrefobject.h b/Include/cpython/weakrefobject.h index 3623071..1078fff 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)) |