Skip to content

gh-133644: remove PyWeakref_GetObject and PyWeakref_GET_OBJECT #133657

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
24 changes: 0 additions & 24 deletions Doc/c-api/weakref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,30 +64,6 @@ as much as it can.
.. versionadded:: 3.13


.. c:function:: PyObject* PyWeakref_GetObject(PyObject *ref)

Return a :term:`borrowed reference` to the referenced object from a weak
reference, *ref*. If the referent is no longer live, returns ``Py_None``.

.. note::

This function returns a :term:`borrowed reference` to the referenced object.
This means that you should always call :c:func:`Py_INCREF` on the object
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:: int PyWeakref_IsDead(PyObject *ref)

Test if the weak reference *ref* is dead. Returns 1 if the reference is
Expand Down
6 changes: 0 additions & 6 deletions Doc/data/refcounts.dat
Original file line number Diff line number Diff line change
Expand Up @@ -2922,12 +2922,6 @@ PyWeakref_CheckProxy:PyObject*:ob:0:
PyWeakref_CheckRef:int:::
PyWeakref_CheckRef:PyObject*:ob:0:

PyWeakref_GET_OBJECT:PyObject*::0:
PyWeakref_GET_OBJECT:PyObject*:ref:0:

PyWeakref_GetObject:PyObject*::0:
PyWeakref_GetObject:PyObject*:ref:0:

PyWeakref_GetRef:int:::
PyWeakref_GetRef:PyObject*:ref:0:
PyWeakref_GetRef:PyObject**:pobj:+1:
Expand Down
1 change: 0 additions & 1 deletion Doc/data/stable_abi.dat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Doc/deprecations/c-api-pending-removal-in-3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Pending removal in Python 3.15
* The bundled copy of ``libmpdecimal``.
* The :c:func:`!PyImport_ImportModuleNoBlock`:
Use :c:func:`PyImport_ImportModule` instead.
* :c:func:`PyWeakref_GetObject` and :c:func:`PyWeakref_GET_OBJECT`:
* :c:func:`!PyWeakref_GetObject` and :c:func:`!PyWeakref_GET_OBJECT`:
Use :c:func:`PyWeakref_GetRef` instead. 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.
Expand Down
4 changes: 2 additions & 2 deletions Doc/howto/free-threading-extensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ that return :term:`strong references <strong reference>`.
+-----------------------------------+-----------------------------------+
| :c:func:`PyDict_Next` | none (see :ref:`PyDict_Next`) |
+-----------------------------------+-----------------------------------+
| :c:func:`PyWeakref_GetObject` | :c:func:`PyWeakref_GetRef` |
| :c:func:`!PyWeakref_GetObject` | :c:func:`PyWeakref_GetRef` |
+-----------------------------------+-----------------------------------+
| :c:func:`PyWeakref_GET_OBJECT` | :c:func:`PyWeakref_GetRef` |
| :c:func:`!PyWeakref_GET_OBJECT` | :c:func:`PyWeakref_GetRef` |
+-----------------------------------+-----------------------------------+
| :c:func:`PyImport_AddModule` | :c:func:`PyImport_AddModuleRef` |
+-----------------------------------+-----------------------------------+
Expand Down
2 changes: 1 addition & 1 deletion Doc/whatsnew/3.11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2673,7 +2673,7 @@ Removed

(Contributed by Victor Stinner in :issue:`45474`.)

* Exclude :c:func:`PyWeakref_GET_OBJECT` from the limited C API. It never
* Exclude :c:func:`!PyWeakref_GET_OBJECT` from the limited C API. It never
worked since the :c:type:`!PyWeakReference` structure is opaque in the
limited C API.
(Contributed by Victor Stinner in :issue:`35134`.)
Expand Down
6 changes: 3 additions & 3 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2231,7 +2231,7 @@ New Features
(Contributed by Serhiy Storchaka in :gh:`110289`.)

* Add the :c:func:`PyWeakref_GetRef` function
as an alternative to :c:func:`PyWeakref_GetObject`
as an alternative to :c:func:`!PyWeakref_GetObject`
that returns a :term:`strong reference`
or ``NULL`` if the referent is no longer live.
(Contributed by Victor Stinner in :gh:`105927`.)
Expand Down Expand Up @@ -2516,8 +2516,8 @@ Deprecated C APIs
are just aliases to :c:type:`!wchar_t`.
(Contributed by Victor Stinner in :gh:`105156`.)

* Deprecate the :c:func:`PyWeakref_GetObject` and
:c:func:`PyWeakref_GET_OBJECT` functions,
* Deprecate the :c:func:`!PyWeakref_GetObject` and
:c:func:`!PyWeakref_GET_OBJECT` functions,
which return a :term:`borrowed reference`.
Replace them with the new :c:func:`PyWeakref_GetRef` function,
which returns a :term:`strong reference`.
Expand Down
4 changes: 4 additions & 0 deletions Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ Removed C APIs
* :c:func:`!PyImport_ImportModuleNoBlock`: deprecated alias
of :c:func:`PyImport_ImportModule`.

* :c:func:`!PyWeakref_GetObject` and :c:macro:`!PyWeakref_GET_OBJECT`:
use :c:func:`PyWeakref_GetRef` instead. The |pythoncapi_compat_project|
can be used to get :c:func:`!PyWeakref_GetRef` on Python 3.12 and older.

The following functions are removed in favor of :c:func:`PyConfig_Get`.
The |pythoncapi_compat_project| can be used to get :c:func:`!PyConfig_Get`
on Python 3.13 and older.
Expand Down
17 changes: 0 additions & 17 deletions Include/cpython/weakrefobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,3 @@ PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self);

// Test if a weak reference is dead.
PyAPI_FUNC(int) PyWeakref_IsDead(PyObject *ref);

Py_DEPRECATED(3.13) static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj)
{
PyWeakReference *ref = _PyWeakref_CAST(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))
1 change: 0 additions & 1 deletion Include/weakrefobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ PyAPI_FUNC(PyObject *) PyWeakref_NewRef(PyObject *ob,
PyObject *callback);
PyAPI_FUNC(PyObject *) PyWeakref_NewProxy(PyObject *ob,
PyObject *callback);
Py_DEPRECATED(3.13) PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref);

#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030D0000
PyAPI_FUNC(int) PyWeakref_GetRef(PyObject *ref, PyObject **pobj);
Expand Down
2 changes: 1 addition & 1 deletion Misc/NEWS.d/3.11.0a2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1188,7 +1188,7 @@ context objects can now be disabled.
.. nonce: Z0Zk_m
.. section: C API

Exclude :c:func:`PyWeakref_GET_OBJECT` from the limited C API. It never
Exclude :c:func:`!PyWeakref_GET_OBJECT` from the limited C API. It never
worked since the :c:type:`!PyWeakReference` structure is opaque in the
limited C API.

Expand Down
6 changes: 3 additions & 3 deletions Misc/NEWS.d/3.13.0a1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6458,8 +6458,8 @@ Victor Stinner.
.. nonce: GRxZtI
.. section: C API

Deprecate the :c:func:`PyWeakref_GetObject` and
:c:func:`PyWeakref_GET_OBJECT` functions: use the new
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.

..
Expand All @@ -6470,7 +6470,7 @@ Deprecate the :c:func:`PyWeakref_GetObject` and
.. section: C API

Add :c:func:`PyWeakref_GetRef` function: similar to
:c:func:`PyWeakref_GetObject` but returns a :term:`strong reference`, or
:c:func:`!PyWeakref_GetObject` but returns a :term:`strong reference`, or
``NULL`` if the referent is no longer live. Patch by Victor Stinner.

..
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Remove deprecated function :c:func:`!PyWeakref_GetObject` and macro
:c:macro:`!PyWeakref_GET_OBJECT`. Use :c:func:`PyWeakref_GetRef` instead.
Patch by Bénédikt Tran.
1 change: 1 addition & 0 deletions Misc/stable_abi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1599,6 +1599,7 @@
added = '3.2'
[function.PyWeakref_GetObject]
added = '3.2'
abi_only = true
[function.PyWeakref_NewProxy]
added = '3.2'
[function.PyWeakref_NewRef]
Expand Down
14 changes: 2 additions & 12 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2207,9 +2207,8 @@ test_macros(PyObject *self, PyObject *Py_UNUSED(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
// Get the function (removed in 3.15) from the stable ABI.
PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *);

// Create a new heap type, create an instance of this type, and delete the
// type. This object supports weak references.
Expand Down Expand Up @@ -2250,19 +2249,12 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
ref = PyWeakref_GetObject(weakref); // borrowed ref
assert(ref == obj);

// test PyWeakref_GET_OBJECT(), reference is alive
ref = PyWeakref_GET_OBJECT(weakref); // borrowed ref
assert(ref == obj);

// delete the referenced object: clear the weakref
assert(Py_REFCNT(obj) == 1);
Py_DECREF(obj);

assert(PyWeakref_IsDead(weakref));

// test PyWeakref_GET_OBJECT(), reference is dead
assert(PyWeakref_GET_OBJECT(weakref) == Py_None);

// test PyWeakref_GetRef(), reference is dead
ref = UNINITIALIZED_PTR;
assert(PyWeakref_GetRef(weakref, &ref) == 0);
Expand Down Expand Up @@ -2313,8 +2305,6 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
Py_DECREF(weakref);

Py_RETURN_NONE;

_Py_COMP_DIAG_POP
}

struct simpletracer_data {
Expand Down
3 changes: 2 additions & 1 deletion Objects/weakrefobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,8 @@ PyWeakref_GetRef(PyObject *ref, PyObject **pobj)
}


PyObject *
/* removed in 3.15, but kept for stable ABI compatibility */
PyAPI_FUNC(PyObject *)
PyWeakref_GetObject(PyObject *ref)
{
if (ref == NULL || !PyWeakref_Check(ref)) {
Expand Down
Loading