KEMBAR78
gh-133644: remove `PyWeakref_GetObject` and `PyWeakref_GET_OBJECT` by picnixz · Pull Request #133657 · python/cpython · GitHub
Skip to content

Conversation

@picnixz
Copy link
Member

@picnixz picnixz commented May 8, 2025

@vstinner
Copy link
Member

vstinner commented May 8, 2025

UPDATE: I excluded manually projects which refer to the functions without using them. I also excluded pythoncapi_compat.h file which excludes Pillow.

This change is a little bit scary: 30 projects in PyPI top 8,000 projects refer to these 2 functions:

  • PyQt5 (5.15.11)
  • PyQt6 (6.8.0)
  • amplpy (0.14.0)
  • apsw (3.48.0.0)
  • awscrt (0.23.7)
  • casadi (3.6.7)
  • catboost (1.2.7)
  • cvxpy (1.6.0)
  • gdal (3.10.1)
  • igraph (0.11.8)
  • m2crypto (0.43.0)
  • mecab_python3 (1.0.10)
  • nanobind (2.4.0)
  • psycopg2 (2.9.10)
  • psycopg2-binary (2.9.10)
  • pyarrow (19.0.0)
  • pygame (2.6.1)
  • pygraphviz (1.14)
  • pyqt5_sip (12.16.1)
  • pysqlite3 (0.5.4)
  • python_crfsuite (0.9.11)
  • sentencepiece (0.2.0)
  • sip (6.9.1)
  • sqlean_py (3.47.0)
  • tensorstore (0.1.71)
  • ufal.udpipe (1.3.1.1)
  • wxPython (4.2.2)
amplpy-0.14.0.tar.gz: amplpy-0.14.0/amplpy/amplpython/cppinterface/amplpythonPYTHON_wrap.cxx: pyobj = PyWeakref_GET_OBJECT(pyobj);
amplpy-0.14.0.tar.gz: amplpy-0.14.0/amplpy/amplpython/cppinterface/amplpythonPYTHON_wrap.cxx: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
apsw-3.48.0.0.tar.gz: apsw-3.48.0.0/src/faultinject.h: #undef PyWeakref_GetObject
apsw-3.48.0.0.tar.gz: apsw-3.48.0.0/src/faultinject.h: #define PyWeakref_GetObject(...) \
apsw-3.48.0.0.tar.gz: apsw-3.48.0.0/src/faultinject.h: __auto_type _res_PyWeakref_GetObject = 0 ? PyWeakref_GetObject(__VA_ARGS__) : 0;                                                                          \
apsw-3.48.0.0.tar.gz: apsw-3.48.0.0/src/faultinject.h: _res_PyWeakref_GetObject = (typeof (_res_PyWeakref_GetObject))APSW_FaultInjectControl("PyWeakref_GetObject", __FILE__, __func__, __LINE__, #__VA_ARGS__); \
apsw-3.48.0.0.tar.gz: apsw-3.48.0.0/src/faultinject.h: if ((typeof (_res_PyWeakref_GetObject))0x1FACADE == _res_PyWeakref_GetObject)                                                                             \
apsw-3.48.0.0.tar.gz: apsw-3.48.0.0/src/faultinject.h: _res_PyWeakref_GetObject = PyWeakref_GetObject(__VA_ARGS__);                                                                                           \
apsw-3.48.0.0.tar.gz: apsw-3.48.0.0/src/faultinject.h: else if ((typeof(_res_PyWeakref_GetObject))0x2FACADE == _res_PyWeakref_GetObject)                                                                         \
apsw-3.48.0.0.tar.gz: apsw-3.48.0.0/src/faultinject.h: PyWeakref_GetObject(__VA_ARGS__);                                                                                                                     \
apsw-3.48.0.0.tar.gz: apsw-3.48.0.0/src/faultinject.h: _res_PyWeakref_GetObject = (typeof (_res_PyWeakref_GetObject))18;                                                                                     \
apsw-3.48.0.0.tar.gz: apsw-3.48.0.0/src/faultinject.h: _res_PyWeakref_GetObject;                                                                                                                                 \
apsw-3.48.0.0.tar.gz: apsw-3.48.0.0/src/pyutil.c: PyObject *obj = PyWeakref_GetObject(ref);
awscrt-0.23.7.tar.gz: awscrt-0.23.7/source/module.c: /* Use PyWeakref_GetObject() (deprecated as of Python 3.13), which gets you:
awscrt-0.23.7.tar.gz: awscrt-0.23.7/source/module.c: PyObject *obj = PyWeakref_GetObject(ref); /* borrowed reference */
awscrt-0.23.7.tar.gz: awscrt-0.23.7/source/module.h: * This is a simplified version of PyWeakref_GetRef() / PyWeakref_GetObject().
awscrt-0.23.7.tar.gz: awscrt-0.23.7/source/module.h: * - Python 3.13 adds PyWeakref_GetRef() and deprecates PyWeakref_GetObject().
casadi-3.6.7.tar.gz: casadi-3.6.7/swig/python/target/source/casadiPYTHON_wrap.cxx: pyobj = PyWeakref_GET_OBJECT(pyobj);
casadi-3.6.7.tar.gz: casadi-3.6.7/swig/python/target/source/casadiPYTHON_wrap.cxx: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
casadi-3.6.7.tar.gz: casadi-3.6.7/swig/python/target3/source/casadiPYTHON_wrap.cxx: pyobj = PyWeakref_GET_OBJECT(pyobj);
casadi-3.6.7.tar.gz: casadi-3.6.7/swig/python/target3/source/casadiPYTHON_wrap.cxx: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
catboost-1.2.7.tar.gz: catboost-1.2.7/catboost_all_src/contrib/tools/swig/Lib/python/pyrun.swg: pyobj = PyWeakref_GET_OBJECT(pyobj);
catboost-1.2.7.tar.gz: catboost-1.2.7/catboost_all_src/contrib/tools/swig/Lib/python/pyrun.swg: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
cvxpy-1.6.0.tar.gz: cvxpy-1.6.0/cvxpy/cvxcore/python/cvxcore_wrap.cxx: pyobj = PyWeakref_GET_OBJECT(pyobj);
cvxpy-1.6.0.tar.gz: cvxpy-1.6.0/cvxpy/cvxcore/python/cvxcore_wrap.cxx: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
gdal-3.10.1.tar.gz: gdal-3.10.1/extensions/gdal_array_wrap.cpp: pyobj = PyWeakref_GET_OBJECT(pyobj);
gdal-3.10.1.tar.gz: gdal-3.10.1/extensions/gdal_array_wrap.cpp: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
gdal-3.10.1.tar.gz: gdal-3.10.1/extensions/gdal_wrap.cpp: pyobj = PyWeakref_GET_OBJECT(pyobj);
gdal-3.10.1.tar.gz: gdal-3.10.1/extensions/gdal_wrap.cpp: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
gdal-3.10.1.tar.gz: gdal-3.10.1/extensions/gdalconst_wrap.c: pyobj = PyWeakref_GET_OBJECT(pyobj);
gdal-3.10.1.tar.gz: gdal-3.10.1/extensions/gdalconst_wrap.c: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
gdal-3.10.1.tar.gz: gdal-3.10.1/extensions/gnm_wrap.cpp: pyobj = PyWeakref_GET_OBJECT(pyobj);
gdal-3.10.1.tar.gz: gdal-3.10.1/extensions/gnm_wrap.cpp: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
gdal-3.10.1.tar.gz: gdal-3.10.1/extensions/ogr_wrap.cpp: pyobj = PyWeakref_GET_OBJECT(pyobj);
gdal-3.10.1.tar.gz: gdal-3.10.1/extensions/ogr_wrap.cpp: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
gdal-3.10.1.tar.gz: gdal-3.10.1/extensions/osr_wrap.cpp: pyobj = PyWeakref_GET_OBJECT(pyobj);
gdal-3.10.1.tar.gz: gdal-3.10.1/extensions/osr_wrap.cpp: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
igraph-0.11.8.tar.gz: igraph-0.11.8/src/_igraph/common.c: o=PyWeakref_GetObject(ref);
m2crypto-0.43.0.tar.gz: m2crypto-0.43.0/src/SWIG/_m2crypto_wrap.c: pyobj = PyWeakref_GET_OBJECT(pyobj);
m2crypto-0.43.0.tar.gz: m2crypto-0.43.0/src/SWIG/_m2crypto_wrap.c: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
mecab_python3-1.0.10.tar.gz: mecab_python3-1.0.10/src/MeCab/MeCab_wrap.cpp: pyobj = PyWeakref_GET_OBJECT(pyobj);
mecab_python3-1.0.10.tar.gz: mecab_python3-1.0.10/src/MeCab/MeCab_wrap.cpp: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
nanobind-2.4.0.tar.gz: nanobind-2.4.0/cmake/darwin-ld-cpython.sym: -U _PyWeakref_GetObject
nanobind-2.4.0.tar.gz: nanobind-2.4.0/cmake/darwin-ld-pypy.sym: -U _PyPyWeakref_GET_OBJECT
nanobind-2.4.0.tar.gz: nanobind-2.4.0/cmake/darwin-ld-pypy.sym: -U _PyPyWeakref_GetObject
psycopg2-2.9.10.tar.gz: psycopg2-2.9.10/psycopg/connection_int.c: if (!(py_curs = PyWeakref_GetObject(self->async_cursor))) {
psycopg2-2.9.10.tar.gz: psycopg2-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
psycopg2-2.9.10.tar.gz: psycopg2-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
psycopg2-2.9.10.tar.gz: psycopg2-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
psycopg2-2.9.10.tar.gz: psycopg2-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
psycopg2-binary-2.9.10.tar.gz: psycopg2-binary-2.9.10/psycopg/connection_int.c: if (!(py_curs = PyWeakref_GetObject(self->async_cursor))) {
psycopg2-binary-2.9.10.tar.gz: psycopg2-binary-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
psycopg2-binary-2.9.10.tar.gz: psycopg2-binary-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
psycopg2-binary-2.9.10.tar.gz: psycopg2-binary-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
psycopg2-binary-2.9.10.tar.gz: psycopg2-binary-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
pyarrow-19.0.0.tar.gz: pyarrow-19.0.0/pyarrow/src/arrow/python/extension_type.cc: PyObject* inst = PyWeakref_GET_OBJECT(type_instance_.obj());
pygame-2.6.1.tar.gz: pygame-2.6.1/src_c/surface.c: tmp = PyWeakref_GetObject(PyList_GetItem(surf->locklist, i));
pygame-2.6.1.tar.gz: pygame-2.6.1/src_c/surface.c: consumer = PyWeakref_GetObject(consumer_ref);
pygame-2.6.1.tar.gz: pygame-2.6.1/src_c/surflock.c: ref = PyWeakref_GetObject(item);
pygame-2.6.1.tar.gz: pygame-2.6.1/src_c/surflock.c: ref = PyWeakref_GetObject(item);
pygraphviz-1.14.tar.gz: pygraphviz-1.14/pygraphviz/graphviz_wrap.c: pyobj = PyWeakref_GET_OBJECT(pyobj);
pygraphviz-1.14.tar.gz: pygraphviz-1.14/pygraphviz/graphviz_wrap.c: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
PyQt5-5.15.11.tar.gz: PyQt5-5.15.11/qpy/QtCore/qpycore_pyqtslot.cpp: return PyWeakref_GetObject(mself_wr);
pyqt5_sip-12.16.1.tar.gz: pyqt5_sip-12.16.1/qtlib.c: if ((sref = PyWeakref_GetObject(slot->weakSlot)) == NULL)
PyQt6-6.8.0.tar.gz: PyQt6-6.8.0/qpy/QtCore/qpycore_pyqtslot.cpp: return PyWeakref_GetObject(mself_wr);
pysqlite3-0.5.4.tar.gz: pysqlite3-0.5.4/src/util.h: obj = PyWeakref_GetObject(ref);
python_crfsuite-0.9.11.tar.gz: python_crfsuite-0.9.11/crfsuite/swig/python/export_wrap.cpp: pyobj = PyWeakref_GET_OBJECT(pyobj);
python_crfsuite-0.9.11.tar.gz: python_crfsuite-0.9.11/crfsuite/swig/python/export_wrap.cpp: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
sentencepiece-0.2.0.tar.gz: sentencepiece-0.2.0/src/sentencepiece/sentencepiece_wrap.cxx: pyobj = PyWeakref_GET_OBJECT(pyobj);
sentencepiece-0.2.0.tar.gz: sentencepiece-0.2.0/src/sentencepiece/sentencepiece_wrap.cxx: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
sip-6.9.1.tar.gz: sip-6.9.1/sipbuild/module/source/12/qtlib.c: if ((sref = PyWeakref_GetObject(slot->weakSlot)) == NULL)
sqlean_py-3.47.0.tar.gz: sqlean_py-3.47.0/src/util.h: obj = PyWeakref_GetObject(ref);
tensorstore-0.1.71.tar.gz: tensorstore-0.1.71/python/tensorstore/garbage_collection.cc: PyObject* python_obj = PyWeakref_GET_OBJECT(weak_ref.get());
tensorstore-0.1.71.tar.gz: tensorstore-0.1.71/python/tensorstore/garbage_collection.cc: PyObject* obj = PyWeakref_GET_OBJECT(weak_ref.get());
ufal.udpipe-1.3.1.1.tar.gz: ufal.udpipe-1.3.1.1/ufal/udpipe/udpipe_python.cpp: pyobj = PyWeakref_GET_OBJECT(pyobj);
ufal.udpipe-1.3.1.1.tar.gz: ufal.udpipe-1.3.1.1/ufal/udpipe/udpipe_python.cpp: PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
wxPython-4.2.2.tar.gz: wxPython-4.2.2/sip/siplib/qtlib.c: if ((sref = PyWeakref_GetObject(slot->weakSlot)) == NULL)

@hugovk
Copy link
Member

hugovk commented May 8, 2025

  • pillow (11.1.0)

Pillow only uses PyWeakref_GetObject in pythoncapi_compat.h, where it's only used for 3.12 and older.

How does the list change if you exclude pythoncapi_compat.h?

@vstinner
Copy link
Member

vstinner commented May 8, 2025

Pillow only uses PyWeakref_GetObject in pythoncapi_compat.h, where it's only used for 3.12 and older.

Oh correct, I modified my script to exclude pythoncapi_compat.h.

How does the list change if you exclude pythoncapi_compat.h?

I modified the list to manually exclude projects which only refer to these functions without using them. I also used the updated script to exclude pythoncapi_compat.h which excludes Pillow.

The number of impacts projects moved from 38 to 27, it's better!

@kumaraditya303 kumaraditya303 removed their request for review May 21, 2025 09:40
@encukou
Copy link
Member

encukou commented Sep 22, 2025

@vstinner, could you share your script, or run it again? It looks like the situation is much better now.

@vstinner
Copy link
Member

vstinner commented Sep 22, 2025

The scripts:

A code search on PyWeakref_GetObject on PyPI top 15,000 (!) projects found 23 affected projects:

  • PyQt5 (5.15.11)
  • apsw (3.50.4.0)
  • apsw-sqlite3mc (3.50.4.0)
  • awscrt (0.28.1)
  • cffi (2.0.0)
  • cython (3.1.4)
  • dbus-python (1.4.0)
  • hunter (3.9.0)
  • igraph (0.11.9)
  • klayout (0.30.4)
  • minorminer (0.2.19)
  • passagemath_standard_no_symbolics (10.6.26)
  • psycopg2 (2.9.10)
  • psycopg2-binary (2.9.10)
  • pygame (2.6.1)
  • pyqt5_sip (12.17.0)
  • pyqt6 (6.9.1)
  • pysqlite3 (0.5.4)
  • questdb (3.0.0)
  • sip (6.12.0)
  • sqlcipher3_wheels-0.5.5.post0
  • sqlean_py (3.50.4.3)
  • wxPython (4.2.3)
apsw-3.50.4.0.tar.gz: apsw-3.50.4.0/src/faultinject.h: __auto_type _res_PyWeakref_GetObject = 0 ? PyWeakref_GetObject(__VA_ARGS__) : 0;                                                                          \
apsw-3.50.4.0.tar.gz: apsw-3.50.4.0/src/faultinject.h: _res_PyWeakref_GetObject = (typeof (_res_PyWeakref_GetObject))APSW_FaultInjectControl("PyWeakref_GetObject", __FILE__, __func__, __LINE__, #__VA_ARGS__); \
apsw-3.50.4.0.tar.gz: apsw-3.50.4.0/src/faultinject.h: if ((typeof (_res_PyWeakref_GetObject))0x1FACADE == _res_PyWeakref_GetObject)                                                                             \
apsw-3.50.4.0.tar.gz: apsw-3.50.4.0/src/faultinject.h: _res_PyWeakref_GetObject = PyWeakref_GetObject(__VA_ARGS__);                                                                                           \
apsw-3.50.4.0.tar.gz: apsw-3.50.4.0/src/faultinject.h: else if ((typeof(_res_PyWeakref_GetObject))0x2FACADE == _res_PyWeakref_GetObject)                                                                         \
apsw-3.50.4.0.tar.gz: apsw-3.50.4.0/src/faultinject.h: PyWeakref_GetObject(__VA_ARGS__);                                                                                                                     \
apsw-3.50.4.0.tar.gz: apsw-3.50.4.0/src/faultinject.h: _res_PyWeakref_GetObject = (typeof (_res_PyWeakref_GetObject))18;                                                                                     \
apsw-3.50.4.0.tar.gz: apsw-3.50.4.0/src/faultinject.h: _res_PyWeakref_GetObject;                                                                                                                                 \
apsw-3.50.4.0.tar.gz: apsw-3.50.4.0/src/pyutil.c: PyObject *obj = PyWeakref_GetObject(ref);
apsw-sqlite3mc-3.50.4.0.tar.gz: apsw-sqlite3mc-3.50.4.0/src/faultinject.h: #define PyWeakref_GetObject(...) \
apsw-sqlite3mc-3.50.4.0.tar.gz: apsw-sqlite3mc-3.50.4.0/src/faultinject.h: __auto_type _res_PyWeakref_GetObject = 0 ? PyWeakref_GetObject(__VA_ARGS__) : 0;                                                                          \
apsw-sqlite3mc-3.50.4.0.tar.gz: apsw-sqlite3mc-3.50.4.0/src/faultinject.h: _res_PyWeakref_GetObject = (typeof (_res_PyWeakref_GetObject))APSW_FaultInjectControl("PyWeakref_GetObject", __FILE__, __func__, __LINE__, #__VA_ARGS__); \
apsw-sqlite3mc-3.50.4.0.tar.gz: apsw-sqlite3mc-3.50.4.0/src/faultinject.h: if ((typeof (_res_PyWeakref_GetObject))0x1FACADE == _res_PyWeakref_GetObject)                                                                             \
apsw-sqlite3mc-3.50.4.0.tar.gz: apsw-sqlite3mc-3.50.4.0/src/faultinject.h: _res_PyWeakref_GetObject = PyWeakref_GetObject(__VA_ARGS__);                                                                                           \
apsw-sqlite3mc-3.50.4.0.tar.gz: apsw-sqlite3mc-3.50.4.0/src/faultinject.h: else if ((typeof(_res_PyWeakref_GetObject))0x2FACADE == _res_PyWeakref_GetObject)                                                                         \
apsw-sqlite3mc-3.50.4.0.tar.gz: apsw-sqlite3mc-3.50.4.0/src/faultinject.h: PyWeakref_GetObject(__VA_ARGS__);                                                                                                                     \
apsw-sqlite3mc-3.50.4.0.tar.gz: apsw-sqlite3mc-3.50.4.0/src/faultinject.h: _res_PyWeakref_GetObject = (typeof (_res_PyWeakref_GetObject))18;                                                                                     \
apsw-sqlite3mc-3.50.4.0.tar.gz: apsw-sqlite3mc-3.50.4.0/src/faultinject.h: _res_PyWeakref_GetObject;                                                                                                                                 \
apsw-sqlite3mc-3.50.4.0.tar.gz: apsw-sqlite3mc-3.50.4.0/src/pyutil.c: PyObject *obj = PyWeakref_GetObject(ref);
awscrt-0.28.1.tar.gz: awscrt-0.28.1/source/module.c: /* Use PyWeakref_GetObject() (deprecated as of Python 3.13), which gets you:
awscrt-0.28.1.tar.gz: awscrt-0.28.1/source/module.c: PyObject *obj = PyWeakref_GetObject(ref); /* borrowed reference */
awscrt-0.28.1.tar.gz: awscrt-0.28.1/source/module.h: * This is a simplified version of PyWeakref_GetRef() / PyWeakref_GetObject().
awscrt-0.28.1.tar.gz: awscrt-0.28.1/source/module.h: * - Python 3.13 adds PyWeakref_GetRef() and deprecates PyWeakref_GetObject().
cffi-2.0.0.tar.gz: cffi-2.0.0/src/c/_cffi_backend.c: PyObject *obj = PyWeakref_GetObject(ref);
cython-3.1.4.tar.gz: cython-3.1.4/Cython/Includes/cpython/weakref.pxd: PyObject *obj = PyWeakref_GetObject(ref);
cython-3.1.4.tar.gz: cython-3.1.4/Cython/Includes/cpython/weakref.pxd: PyObject* PyWeakref_GetObject(object ref) except NULL
dbus-python-1.4.0.tar.gz: dbus-python-1.4.0/dbus_bindings/dbus_bindings-internal.h: PyObject *obj = PyWeakref_GetObject(ref);
hunter-3.9.0.tar.gz: hunter-3.9.0/src/hunter/vendor/_compat.h: obj = PyWeakref_GetObject(ref);
igraph-0.11.9.tar.gz: igraph-0.11.9/src/_igraph/common.c: o=PyWeakref_GetObject(ref);
klayout-0.30.4.tar.gz: klayout-0.30.4/src/pya/pya/pyaSignalHandler.cc: PyObject *self = PyWeakref_GetObject (m_weak_self.get ());
klayout-0.30.4.tar.gz: klayout-0.30.4/src/pya/pya/pyaSignalHandler.cc: return PyWeakref_GetObject (m_weak_self.get ());
minorminer-0.2.19.tar.gz: minorminer-0.2.19/env/lib/python3.12/site-packages/Cython/Includes/cpython/weakref.pxd: PyObject* PyWeakref_GetObject(object ref) except NULL
passagemath_standard_no_symbolics-10.6.26.tar.gz: passagemath_standard_no_symbolics-10.6.26/sage/misc/weak_dict.pyx: PyObject* PyWeakref_GetObject(PyObject *ref)
passagemath_standard_no_symbolics-10.6.26.tar.gz: passagemath_standard_no_symbolics-10.6.26/sage/misc/weak_dict.pyx: cdef WeakValueDictionary D = <object> PyWeakref_GetObject(<PyObject*> self.D)
passagemath_standard_no_symbolics-10.6.26.tar.gz: passagemath_standard_no_symbolics-10.6.26/sage/misc/weak_dict.pyx: out = PyWeakref_GetObject(wr)
passagemath_standard_no_symbolics-10.6.26.tar.gz: passagemath_standard_no_symbolics-10.6.26/sage/misc/weak_dict.pyx: cdef PyObject* outref = PyWeakref_GetObject(wr)
passagemath_standard_no_symbolics-10.6.26.tar.gz: passagemath_standard_no_symbolics-10.6.26/sage/misc/weak_dict.pyx: out = PyWeakref_GetObject(wr)
passagemath_standard_no_symbolics-10.6.26.tar.gz: passagemath_standard_no_symbolics-10.6.26/sage/misc/weak_dict.pyx: out = PyWeakref_GetObject(wr)
passagemath_standard_no_symbolics-10.6.26.tar.gz: passagemath_standard_no_symbolics-10.6.26/sage/misc/weak_dict.pyx: return (wr != NULL) and (PyWeakref_GetObject(wr) != Py_None)
passagemath_standard_no_symbolics-10.6.26.tar.gz: passagemath_standard_no_symbolics-10.6.26/sage/misc/weak_dict.pyx: if PyWeakref_GetObject(wr)!=Py_None:
passagemath_standard_no_symbolics-10.6.26.tar.gz: passagemath_standard_no_symbolics-10.6.26/sage/misc/weak_dict.pyx: out = PyWeakref_GetObject(wr)
passagemath_standard_no_symbolics-10.6.26.tar.gz: passagemath_standard_no_symbolics-10.6.26/sage/misc/weak_dict.pyx: out = PyWeakref_GetObject(wr)
passagemath_standard_no_symbolics-10.6.26.tar.gz: passagemath_standard_no_symbolics-10.6.26/sage/structure/coerce_dict.pyx: from cpython.weakref cimport PyWeakref_GetObject, PyWeakref_GET_OBJECT
passagemath_standard_no_symbolics-10.6.26.tar.gz: passagemath_standard_no_symbolics-10.6.26/sage/structure/coerce_dict.pyx: cdef MonoDict md = <MonoDict>PyWeakref_GetObject(self.D)
passagemath_standard_no_symbolics-10.6.26.tar.gz: passagemath_standard_no_symbolics-10.6.26/sage/structure/coerce_dict.pyx: cdef TripleDict td = <TripleDict>PyWeakref_GetObject(self.D)
psycopg2-2.9.10.tar.gz: psycopg2-2.9.10/psycopg/connection_int.c: if (!(py_curs = PyWeakref_GetObject(self->async_cursor))) {
psycopg2-2.9.10.tar.gz: psycopg2-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
psycopg2-2.9.10.tar.gz: psycopg2-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
psycopg2-2.9.10.tar.gz: psycopg2-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
psycopg2-2.9.10.tar.gz: psycopg2-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
psycopg2-binary-2.9.10.tar.gz: psycopg2-binary-2.9.10/psycopg/connection_int.c: if (!(py_curs = PyWeakref_GetObject(self->async_cursor))) {
psycopg2-binary-2.9.10.tar.gz: psycopg2-binary-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
psycopg2-binary-2.9.10.tar.gz: psycopg2-binary-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
psycopg2-binary-2.9.10.tar.gz: psycopg2-binary-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
psycopg2-binary-2.9.10.tar.gz: psycopg2-binary-2.9.10/psycopg/cursor_type.c: && PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
pygame-2.6.1.tar.gz: pygame-2.6.1/src_c/surface.c: tmp = PyWeakref_GetObject(PyList_GetItem(surf->locklist, i));
pygame-2.6.1.tar.gz: pygame-2.6.1/src_c/surface.c: consumer = PyWeakref_GetObject(consumer_ref);
pygame-2.6.1.tar.gz: pygame-2.6.1/src_c/surflock.c: ref = PyWeakref_GetObject(item);
pygame-2.6.1.tar.gz: pygame-2.6.1/src_c/surflock.c: ref = PyWeakref_GetObject(item);
PyQt5-5.15.11.tar.gz: PyQt5-5.15.11/qpy/QtCore/qpycore_pyqtslot.cpp: return PyWeakref_GetObject(mself_wr);
pyqt5_sip-12.17.0.tar.gz: pyqt5_sip-12.17.0/qtlib.c: if ((sref = PyWeakref_GetObject(slot->weakSlot)) == NULL)
pyqt6-6.9.1.tar.gz: pyqt6-6.9.1/qpy/QtCore/qpycore_pyqtslot.cpp: return PyWeakref_GetObject(mself_wr);
pysqlite3-0.5.4.tar.gz: pysqlite3-0.5.4/src/util.h: obj = PyWeakref_GetObject(ref);
questdb-3.0.0.tar.gz: questdb-3.0.0/src/questdb/ingress.pyx: from cpython.weakref cimport PyWeakref_NewRef, PyWeakref_GetObject
questdb-3.0.0.tar.gz: questdb-3.0.0/src/questdb/ingress.pyx: sender = PyWeakref_GetObject(self._row_complete_sender)
sip-6.12.0.tar.gz: sip-6.12.0/sipbuild/module/source/12/10/qtlib.c: else if ((sref = PyWeakref_GetObject(slot -> weakSlot)) == NULL)
sip-6.12.0.tar.gz: sip-6.12.0/sipbuild/module/source/12/11/qtlib.c: else if ((sref = PyWeakref_GetObject(slot -> weakSlot)) == NULL)
sip-6.12.0.tar.gz: sip-6.12.0/sipbuild/module/source/12/12/qtlib.c: else if ((sref = PyWeakref_GetObject(slot -> weakSlot)) == NULL)
sip-6.12.0.tar.gz: sip-6.12.0/sipbuild/module/source/12/13/qtlib.c: else if ((sref = PyWeakref_GetObject(slot -> weakSlot)) == NULL)
sip-6.12.0.tar.gz: sip-6.12.0/sipbuild/module/source/12/14/qtlib.c: if ((sref = PyWeakref_GetObject(slot->weakSlot)) == NULL)
sip-6.12.0.tar.gz: sip-6.12.0/sipbuild/module/source/12/15/qtlib.c: if ((sref = PyWeakref_GetObject(slot->weakSlot)) == NULL)
sip-6.12.0.tar.gz: sip-6.12.0/sipbuild/module/source/12/16/qtlib.c: if ((sref = PyWeakref_GetObject(slot->weakSlot)) == NULL)
sip-6.12.0.tar.gz: sip-6.12.0/sipbuild/module/source/12/17/qtlib.c: if ((sref = PyWeakref_GetObject(slot->weakSlot)) == NULL)
sip-6.12.0.tar.gz: sip-6.12.0/sipbuild/module/source/12/9/qtlib.c: else if ((sref = PyWeakref_GetObject(slot -> weakSlot)) == NULL)
sqlcipher3_wheels-0.5.5.post0.tar.gz: sqlcipher3_wheels-0.5.5.post0/src/util.h: obj = PyWeakref_GetObject(ref);
sqlean_py-3.50.4.3.tar.gz: sqlean_py-3.50.4.3/src/util.h: obj = PyWeakref_GetObject(ref);
wxPython-4.2.3.tar.gz: wxPython-4.2.3/sip/siplib/qtlib.c: if ((sref = PyWeakref_GetObject(slot->weakSlot)) == NULL)

@vstinner
Copy link
Member

cython (3.1.4)

Cython is not affected, the matching line comes from a compatibility layer. It defines __Pyx_PyWeakref_GetRef macro as PyWeakref_GetRef on Python 3.13 on newer.

@encukou
Copy link
Member

encukou commented Sep 23, 2025

I found 4 projects (marked (!) below) that need a trivial change to switch away from PyWeakref_GetObject, and 4 more (marked (!!) below) where the code change wasn't readily apparent (I didn't spend much time investagating).

Others use PyWeakref_GetObject only for older Python versions; commonly to implement a backport of PyWeakref_GetRef.

  • PyQt5 (5.15.11) (!) (similar to pyqt6)
  • apsw
    • faultinject.h has generated wrappers for "all" Python C API functions
    • pyutil.c: used for backport of PyWeakref_GetRef
  • apsw-sqlite3mc - faultinject.h & pyutil.c as above
  • awscrt - #ifdef'd
  • cffi - used for backport of PyWeakref_GetRef
  • cython - not affected
  • dbus-python - used in backport_PyWeakref_GetRef
  • hunter - used for backport of PyWeakref_GetRef
  • igraph (0.11.9) (!!)
  • klayout (0.30.4) (!!)
  • minorminer - distributes a venv with Cython headers
  • passagemath_standard_no_symbolics (10.6.26) (!!)
  • psycopg2 (2.9.10) (!)
    • connection_int.c: followed by INCREF
    • cursor_type.c might slow down when switched to PyWeakref_GetRef; it does:
      PyWeakref_GetObject(self->conn->async_cursor) == (PyObject*)self)
      
      See below.
  • psycopg2-binary (!) - as psycopg2
  • pygame (!)
    • surface.c:1023 - followed by INCREF
    • surface.c:3446 - will need a DECREF
    • surflock.c:127 - a check similar to psycopg2
    • surflock.c:142 - should switch to PyWeakref_IsDead
  • pyqt5_sip - fallback for PyWeakref_GetRef
  • pyqt6 (6.9.1) (!!)
  • pysqlite3 - fallback for PyWeakref_GetRef
  • questdb (!) - should switch to PyWeakref_IsDead
  • sip - fallback for PyWeakRef_GetRef in 12/14/ (and prseumably the newer ones)
  • sqlcipher3_wheels-0.5.5.post0 - used for backport of PyWeakref_GetRef
  • sqlean_py - used for backport of PyWeakref_GetRef
  • wxPython - fallback for PyWeakref_GetRef

For psycopg2's and pygame's case, we might want to add API to check if a weakref references a given object, like this:

int PyWeakref_CheckRef(PyObject *ref, PyObject *obj);
  • return 1 if ref is a weak reference to obj
  • return 0 if it is a reference to another object, or if it is dead
  • return -1 with exception set on error
    • if ref is not a weakref, set a TypeError

But it seems this might not be widely useful.

@vstinner
Copy link
Member

@picnixz: Can you fix the merge conflict?

@picnixz
Copy link
Member Author

picnixz commented Sep 23, 2025

Yes, I was waiting for a decision to be made before fixing it. Should I understand that we want to merge this PR soon?

@encukou
Copy link
Member

encukou commented Sep 23, 2025

+1 for removing this in the first alpha.

@picnixz picnixz marked this pull request as draft September 23, 2025 15:01
@picnixz picnixz marked this pull request as ready for review September 23, 2025 15:01
@picnixz picnixz requested a review from AA-Turner as a code owner September 23, 2025 15:01
@picnixz
Copy link
Member Author

picnixz commented Sep 23, 2025

(FTR, the reason why I put my PRs into draft sometimes is because I'm worried that I messed up my merge commit. That way, I'm sure that I don't notify users by mistake)

Copy link
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, let's remove it as soon as possible in the 3.15 dev cycle.

@encukou encukou merged commit a5e0562 into python:main Sep 24, 2025
51 checks passed
@picnixz picnixz deleted the cleanup/315/deprecated-weakrefs-133644 branch September 24, 2025 09:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants