diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst
index 44f4dce9ea02383..04781f78d23462c 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 d1f13a50335b5bf..be9cc44afdb51b6 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
+ `__ can be used to get
+ :c:func:`PyWeakref_GetRef` on Python 3.12 and older.
+ (Contributed by Victor Stinner in :gh:`105927`.)
+
Removed
-------
@@ -565,6 +573,6 @@ 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
- `_ can be used to get this
+ `__ 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 fd79fdc2dcc4688..409923863269183 100644
--- a/Include/cpython/weakrefobject.h
+++ b/Include/cpython/weakrefobject.h
@@ -36,7 +36,8 @@ PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head);
PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self);
-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 2c69f9e4564ab3f..727ba6934bbacbb 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 000000000000000..57982dc75e004a3
--- /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 d847539f6608dd2..dc8acec6c769219 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -3375,6 +3375,10 @@ check_pyimport_addmodule(PyObject *self, PyObject *args)
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 c54f663acdb66c9..f3f6c86637e9de3 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