summaryrefslogtreecommitdiffstats
path: root/Include/cpython
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2022-04-21 14:01:47 (GMT)
committerGitHub <noreply@github.com>2022-04-21 14:01:47 (GMT)
commit1a2b282f201073d5153e737568c833af6f1b349e (patch)
tree81040c44144273aa43c8ad8e5420871b40f6f871 /Include/cpython
parentf2b4e458b3327130e46edb4efe8e1847de09efc5 (diff)
downloadcpython-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.h26
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))