pyqt6: FTBFS building against python 3.15

Maximiliano Curia <[email protected]>
Newsgroups gmane.linux.debian.devel.python
Message-ID <[email protected]>
Package: src:pyqt6
Version: 6.11.0-2
User: [email protected]
Usertags: python3.15
Tags: patch

Hi!

While rebuilding the python related packages against the python version
3.15rc1 we found that pyqt6 fails to build from source[1]. This is due
to the removal of PyWeakref_GetObject which was deprecated in python
3.13. I'm attaching a patch that's almost identical to the one needed
for pyqt5.

Please consider applying this or a similar patch in your next upload.

Happy hacking,

[1]: https://debusine.debian.net/debian/r-python-python3.15/work-request/1013759/
-- 
"Can you imagine what I would do if I could do all I can?" -- Sun Tzu
Saludos /\/\ /\ >< `/
python3.15.patch (text/x-diff, 3.8 KB)
Description: Fix build against Python 3.15 by using PyWeakref_GetRef
 PyWeakref_GetObject was deprecated in Python 3.13 and removed in Python 3.15.
 Replace its usage with PyWeakref_GetRef, properly handling strong references
 and providing a compatibility fallback for older Python versions and limited API.
Author: Maximiliano Curia <[email protected]>
Forwarded: no
Last-Update: 2026-08-19

Index: pyqt6/qpy/QtCore/qpycore_pyqtslot.cpp
===================================================================
--- pyqt6.orig/qpy/QtCore/qpycore_pyqtslot.cpp
+++ pyqt6/qpy/QtCore/qpycore_pyqtslot.cpp
@@ -24,6 +24,40 @@
 #include "qpycore_pyqtslot.h"
 
 
+#if PY_VERSION_HEX < 0x030D0000
+static inline int PyWeakref_GetRef(PyObject *ref, PyObject **pobj)
+{
+    PyObject *obj;
+
+    if (ref != NULL && !PyWeakref_Check(ref))
+    {
+        *pobj = NULL;
+        PyErr_SetString(PyExc_TypeError, "expected a weakref");
+        return -1;
+    }
+
+    obj = PyWeakref_GetObject(ref);
+    if (obj == NULL)
+    {
+        *pobj = NULL;
+        return -1;
+    }
+
+    if (obj == Py_None)
+    {
+        *pobj = NULL;
+        return 0;
+    }
+
+    Py_INCREF(obj);
+    *pobj = obj;
+    return 1;
+}
+#elif defined(Py_LIMITED_API) && Py_LIMITED_API < 0x030D0000
+extern "C" PyAPI_FUNC(int) PyWeakref_GetRef(PyObject *ref, PyObject **pobj);
+#endif
+
+
 // Create the slot for a callable.
 PyQtSlot::PyQtSlot(PyObject *callable, bool callable_is_method,
         const Chimera::Signature *slot_signature)
@@ -45,6 +79,8 @@ PyQtSlot::PyQtSlot(PyObject *callable, b
 
             // Try and create a weak reference to the instance object.
             mself_wr = PyWeakref_NewRef(mself, 0);
+            if (!mself_wr)
+                PyErr_Clear();
         }
         else
         {
@@ -96,9 +132,11 @@ PyQtSlot::Result PyQtSlot::invoke(void *
     }
     else
     {
+        PyObject *self_ref = 0;
+
         // Use the value we have if one wasn't supplied.
         if (!self)
-            self = instance();
+            self = self_ref = instance();
 
         // If self is NULL then we didn't have a method in the first place.
         // Instead we had a callable that has been cleared during garbage
@@ -108,12 +146,18 @@ PyQtSlot::Result PyQtSlot::invoke(void *
 
         // See if the instance has gone (which isn't an error).
         if (self == Py_None)
+        {
+            Py_XDECREF(self_ref);
             return PyQtSlot::Ignored;
+        }
 
         // If the receiver wraps a C++ object then ignore the call if it no
         // longer exists.
         if (!no_receiver_check && PyObject_TypeCheck(self, sipSimpleWrapper_Type) && !sipGetAddress((sipSimpleWrapper *)self))
+        {
+            Py_XDECREF(self_ref);
             return PyQtSlot::Ignored;
+        }
 
         sipMethodDef callable_m;
 
@@ -121,6 +165,8 @@ PyQtSlot::Result PyQtSlot::invoke(void *
         callable_m.pm_self = self;
 
         callable = sipFromMethod(&callable_m);
+
+        Py_XDECREF(self_ref);
     }
 
     // Convert the C++ arguments to Python objects.
@@ -181,7 +227,12 @@ bool PyQtSlot::operator==(PyObject *call
         if (other)
             return false;
 
-        return (mfunc == callable_m.pm_function && instance() == callable_m.pm_self);
+        PyObject *self = instance();
+        bool match = (mfunc == callable_m.pm_function && self == callable_m.pm_self);
+
+        Py_XDECREF(self);
+
+        return match;
     }
 
     if (!other)
@@ -207,8 +258,19 @@ PyObject *PyQtSlot::instance() const
 {
     // Use the weak reference if possible.
     if (mself_wr)
-        return PyWeakref_GetObject(mself_wr);
+    {
+        PyObject *obj = 0;
+
+        if (PyWeakref_GetRef(mself_wr, &obj) < 0)
+        {
+            PyErr_Clear();
+            return 0;
+        }
+
+        return obj;
+    }
 
+    Py_XINCREF(mself);
     return mself;
 }
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEE+JIdOnQEyG4RNSIVxxl2mbKbIyoFAmqIGwUACgkQxxl2mbKb
IypZ1A/+IAs4Pv1CYG9TiDmoKhAlL0MVJa5Dq+oykCevtcH8qNOy7zXA2N+X/IIv
d8ZIyVSIHsN13DlQ5mBjqA9xo1V1xRloBRaFiQbrIskLBp96slrgD/OfCTXQwKGG
uSlEVUYmQHsWxbwh+gndfHGivP2HbMqP7WbCG5bqaN2liTqzPoYJ1xWhdRfrnkQL
hypoTvbCdBAb6pjMx539Ch0b8+XP8F/2HaaHXFflpknXtvYoKBpHV28fpvzh7o8u
sCQoUiRccu3pgCyJru9JKU96KPtkUO4U5Sfs9ZnbLWbDKwxQOh6V+lUN+3Fw9I+C
Gpvr5XLC+g6uvgA7E/HBrq18IiDw1CMo+pb8vk8vZQ+YN+kZxnVPGyyjxOf83DyF
UDVaLpysM49JKkzuaTbbd9hvdZgIqng/MgUVo5K/xUteXbnDfkO9kclEffdLjdDq
n2FeJl7FBYS/ZKZhgleueZU889fiKb4FO0hR9VsYuvH2kB3SdOoG3yJxOwFgI/G5
CAMpjRW0FRPWMFxDnHkMalcXq9WfS327FFWerc9NY3t6nSVkr1FNeLq40zWkIDKr
lZTTJn7bAA/gg9vAwDQvaLqK4fsjFW12BIXriFqdbixnaP5FBdrNvKHQgeJEuak9
HnvVmzRlGpMi6mXLYuaEYGlTZGwjCZbeOY63cbQdXRWO9xq8+4Y=
=H8Ni
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.