From c075a1974b0dce9801cb645c77faa8af612b3db5 Mon Sep 17 00:00:00 2001 From: Victor Stinner <vstinner@python.org> Date: Mon, 26 Jun 2023 12:10:53 +0200 Subject: gh-105927: Deprecate PyWeakref_GetObject() function (#106006) Deprecate PyWeakref_GetObject() and PyWeakref_GET_OBJECT() functions. --- Doc/c-api/weakref.rst | 6 ++++++ Doc/whatsnew/3.13.rst | 10 +++++++++- Include/cpython/weakrefobject.h | 3 ++- Include/weakrefobject.h | 2 +- .../next/C API/2023-06-22-00-25-55.gh-issue-105927.GRxZtI.rst | 3 +++ Modules/_testcapimodule.c | 6 ++++++ Objects/weakrefobject.c | 7 ++++++- 7 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2023-06-22-00-25-55.gh-issue-105927.GRxZtI.rst diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst index 44f4dce..04781f7 100644 --- a/Doc/c-api/weakref.rst +++ b/Doc/c-api/weakref.rst @@ -74,11 +74,17 @@ as much as it can. except when it cannot be destroyed before the last usage of the borrowed reference. + .. deprecated-removed:: 3.13 3.15 + Use :c:func:`PyWeakref_GetRef` instead. + .. c:function:: PyObject* PyWeakref_GET_OBJECT(PyObject *ref) Similar to :c:func:`PyWeakref_GetObject`, but does no error checking. + .. deprecated-removed:: 3.13 3.15 + Use :c:func:`PyWeakref_GetRef` instead. + .. c:function:: void PyObject_ClearWeakRefs(PyObject *object) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index ee8c198..b6d13a8 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -470,6 +470,14 @@ Deprecated Scheduled for removal in Python 3.15. (Contributed by Victor Stinner in :gh:`105396`.) +* Deprecate the :c:func:`PyWeakref_GetObject` and + :c:func:`PyWeakref_GET_OBJECT` functions, which return a :term:`borrowed + reference`: use the new :c:func:`PyWeakref_GetRef` function instead, it + returns a :term:`strong reference`. The `pythoncapi-compat project + <https://github.com/python/pythoncapi-compat/>`__ can be used to get + :c:func:`PyWeakref_GetRef` on Python 3.12 and older. + (Contributed by Victor Stinner in :gh:`105927`.) + Removed ------- @@ -565,7 +573,7 @@ Removed * Remove the old private, undocumented and untested ``_PyGC_FINALIZED()`` macro which was kept for backward compatibility with Python 3.8 and older: use :c:func:`PyObject_GC_IsFinalized()` instead. The `pythoncapi-compat project - <https://github.com/python/pythoncapi-compat/>`_ can be used to get this + <https://github.com/python/pythoncapi-compat/>`__ can be used to get this function on Python 3.8 and older. (Contributed by Victor Stinner in :gh:`105268`.) diff --git a/Include/cpython/weakrefobject.h b/Include/cpython/weakrefobject.h index 6bf1655..1559e2d 100644 --- a/Include/cpython/weakrefobject.h +++ b/Include/cpython/weakrefobject.h @@ -32,7 +32,8 @@ struct _PyWeakReference { vectorcallfunc vectorcall; }; -static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj) { +Py_DEPRECATED(3.13) static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj) +{ PyWeakReference *ref; PyObject *obj; assert(PyWeakref_Check(ref_obj)); diff --git a/Include/weakrefobject.h b/Include/weakrefobject.h index 2c69f9e..727ba69 100644 --- a/Include/weakrefobject.h +++ b/Include/weakrefobject.h @@ -27,7 +27,7 @@ PyAPI_FUNC(PyObject *) PyWeakref_NewRef(PyObject *ob, PyObject *callback); PyAPI_FUNC(PyObject *) PyWeakref_NewProxy(PyObject *ob, PyObject *callback); -PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref); +Py_DEPRECATED(3.13) PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref); PyAPI_FUNC(int) PyWeakref_GetRef(PyObject *ref, PyObject **pobj); diff --git a/Misc/NEWS.d/next/C API/2023-06-22-00-25-55.gh-issue-105927.GRxZtI.rst b/Misc/NEWS.d/next/C API/2023-06-22-00-25-55.gh-issue-105927.GRxZtI.rst new file mode 100644 index 0000000..57982dc --- /dev/null +++ b/Misc/NEWS.d/next/C API/2023-06-22-00-25-55.gh-issue-105927.GRxZtI.rst @@ -0,0 +1,3 @@ +Deprecate the :c:func:`PyWeakref_GetObject` and +:c:func:`PyWeakref_GET_OBJECT` functions: use the new +:c:func:`PyWeakref_GetRef` function instead. Patch by Victor Stinner. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index d847539..dc8acec 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3375,6 +3375,10 @@ error: static PyObject * test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) { + // Ignore PyWeakref_GetObject() deprecation, we test it on purpose + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + // Create a new heap type, create an instance of this type, and delete the // type. This object supports weak references. PyObject *new_type = PyObject_CallFunction((PyObject*)&PyType_Type, @@ -3463,6 +3467,8 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) Py_DECREF(weakref); Py_RETURN_NONE; + + _Py_COMP_DIAG_POP } diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index c54f663..f3f6c86 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -923,7 +923,12 @@ PyWeakref_GetObject(PyObject *ref) PyErr_BadInternalCall(); return NULL; } - return PyWeakref_GET_OBJECT(ref); + PyObject *obj = _PyWeakref_GET_REF(ref); + if (obj == NULL) { + return Py_None; + } + Py_DECREF(obj); + return obj; // borrowed reference } /* Note that there's an inlined copy-paste of handle_callback() in gcmodule.c's -- cgit v0.12