Buildroot Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [Buildroot] [PATCH 1/1] package/python-pyqt5: fix build with python-3.15
@ 2026-10-04 12:44 Bernd Kuhls
  2026-10-10  8:26 ` Thomas Petazzoni via buildroot
  0 siblings, 1 reply; 2+ messages in thread
From: Bernd Kuhls @ 2026-10-04 12:44 UTC (permalink / raw)
  To: buildroot; +Cc: James Hilliard

Please note that the upstream repo is private so we used the Debian
mirror as source for patch 0003 which is marked as a cherry-pick by
upstream.

Other mirrors are not updated: https://github.com/baoboa/pyqt5/issues/76

Signed-off-by: Bernd Kuhls <bernd@kuhls.net>
---
 .../0003-Support-for-Python-v3.15.patch       | 185 ++++++++++++++++++
 ...4-configure.py-remove-Py_LIMITED_API.patch |  37 ++++
 2 files changed, 222 insertions(+)
 create mode 100644 package/python-pyqt5/0003-Support-for-Python-v3.15.patch
 create mode 100644 package/python-pyqt5/0004-configure.py-remove-Py_LIMITED_API.patch

diff --git a/package/python-pyqt5/0003-Support-for-Python-v3.15.patch b/package/python-pyqt5/0003-Support-for-Python-v3.15.patch
new file mode 100644
index 0000000000..ec39817b6d
--- /dev/null
+++ b/package/python-pyqt5/0003-Support-for-Python-v3.15.patch
@@ -0,0 +1,185 @@
+From: Phil Thompson <phil@riverbankcomputing.com>
+Date: Mon, 13 Jul 2026 16:38:52 +0100
+Subject: Support for Python v3.15
+
+The project can now be built with Python v3.15 (where the limited ABI
+version targeted will be v3.13).
+
+(cherry picked from commit 3aa6092c44cd17a3afcd9f8ca879c4e40d2662d1)
+
+Upstream: https://salsa.debian.org/python-team/packages/pyqt5/-/blob/1c7499d1d4d79737ae367ec263a9be71ce2b76ee/debian/patches/Support-for-Python-v3.15.patch
+
+Signed-off-by: Bernd Kuhls <bernd@kuhls.net>
+---
+ project.py                             |  8 +++++++
+ qpy/QtCore/qpycore_pyqtproperty.cpp    |  2 +-
+ qpy/QtCore/qpycore_pyqtslot.cpp        | 44 ++++++++++++++++++++++++++--------
+ qpy/QtCore/qpycore_qobject_helpers.cpp | 11 +++++----
+ 4 files changed, 49 insertions(+), 16 deletions(-)
+
+diff --git a/project.py b/project.py
+index 9a3721f..f2143ac 100644
+--- a/project.py
++++ b/project.py
+@@ -111,6 +111,14 @@ del find_qt
+ 
+         return dunder_init
+ 
++    def get_limited_abi_version(self):
++        """ Return the version number of the limited ABI to use. """
++
++        # We use PyWeakref_GetObject() which was removed from the limited API
++        # in Python v3.15.  It's replacement, PyWeakref_GetRef() was added to
++        # the limited ABI in Python v3.13.
++        return (3, 13, 0) if sys.hexversion >= 0x030f0000 else None
++
+     def get_options(self):
+         """ Return the sequence of configurable options. """
+ 
+diff --git a/qpy/QtCore/qpycore_pyqtproperty.cpp b/qpy/QtCore/qpycore_pyqtproperty.cpp
+index d173d51..0245134 100644
+--- a/qpy/QtCore/qpycore_pyqtproperty.cpp
++++ b/qpy/QtCore/qpycore_pyqtproperty.cpp
+@@ -575,7 +575,7 @@ static PyObject *pyqtProperty_reset(PyObject *self, PyObject *reset)
+ static qpycore_pyqtProperty *clone(qpycore_pyqtProperty *orig)
+ {
+     qpycore_pyqtProperty *pp = (qpycore_pyqtProperty *)PyType_GenericNew(
+-            Py_TYPE(orig), 0, 0);
++            Py_TYPE((PyObject *)orig), 0, 0);
+ 
+     if (pp)
+     {
+diff --git a/qpy/QtCore/qpycore_pyqtslot.cpp b/qpy/QtCore/qpycore_pyqtslot.cpp
+index 26f4022..22a7d0c 100644
+--- a/qpy/QtCore/qpycore_pyqtslot.cpp
++++ b/qpy/QtCore/qpycore_pyqtslot.cpp
+@@ -101,7 +101,9 @@ PyQtSlot::Result PyQtSlot::invoke(void **qargs, PyObject *self, void *result,
+     else
+     {
+         // Use the value we have if one wasn't supplied.
+-        if (!self)
++        if (self)
++            Py_INCREF(self);
++        else
+             self = instance();
+ 
+         // If self is NULL then we didn't have a method in the first place.
+@@ -112,12 +114,18 @@ PyQtSlot::Result PyQtSlot::invoke(void **qargs, PyObject *self, void *result,
+ 
+         // See if the instance has gone (which isn't an error).
+         if (self == Py_None)
++        {
++            Py_DECREF(self);
+             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_DECREF(self);
+             return PyQtSlot::Ignored;
++        }
+ 
+         sipMethodDef callable_m;
+ 
+@@ -128,6 +136,7 @@ PyQtSlot::Result PyQtSlot::invoke(void **qargs, PyObject *self, void *result,
+ #endif
+ 
+         callable = sipFromMethod(&callable_m);
++        Py_DECREF(self);
+     }
+ 
+     // Convert the C++ arguments to Python objects.
+@@ -188,12 +197,11 @@ bool PyQtSlot::operator==(PyObject *callable) const
+         if (other)
+             return false;
+ 
+-        return (mfunc == callable_m.pm_function
+-                && instance() == callable_m.pm_self
+-#if PY_MAJOR_VERSION < 3
+-                && mclass == callable_m.pm_class
+-#endif
+-                );
++        PyObject *instance_obj = instance();
++        bool res = (mfunc == callable_m.pm_function && instance_obj == callable_m.pm_self);
++        Py_XDECREF(instance_obj);
++
++        return res;
+     }
+ 
+     if (!other)
+@@ -214,14 +222,30 @@ bool PyQtSlot::operator==(PyObject *callable) const
+ }
+ 
+ 
+-// Get the instance object.
++// Get a strong reference to the instance object, otherwise return NULL or a
++// strong reference to Py_None.
+ PyObject *PyQtSlot::instance() const
+ {
++    PyObject *instance_obj;
++
+     // Use the weak reference if possible.
+     if (mself_wr)
+-        return PyWeakref_GetObject(mself_wr);
++    {
++#if PY_VERSION_HEX >= 0x030f0000
++        if (PyWeakref_GetRef(mself_wr, &instance_obj) < 0)
++            instance_obj = NULL;
++#else
++        instance_obj = PyWeakref_GetObject(mself_wr);
++        Py_XINCREF(instance_obj);
++#endif
++    }
++    else
++    {
++        instance_obj = mself;
++        Py_XINCREF(instance_obj);
++    }
+ 
+-    return mself;
++    return instance_obj;
+ }
+ 
+ 
+diff --git a/qpy/QtCore/qpycore_qobject_helpers.cpp b/qpy/QtCore/qpycore_qobject_helpers.cpp
+index f72105c..7b756ec 100644
+--- a/qpy/QtCore/qpycore_qobject_helpers.cpp
++++ b/qpy/QtCore/qpycore_qobject_helpers.cpp
+@@ -50,7 +50,7 @@ static int qt_metacall_worker(sipSimpleWrapper *pySelf, PyTypeObject *pytype,
+ const QMetaObject *qpycore_qobject_metaobject(sipSimpleWrapper *pySelf,
+         sipTypeDef *base)
+ {
+-    sipWrapperType *wt = (pySelf ? (sipWrapperType *)Py_TYPE(pySelf) : 0);
++    sipWrapperType *wt = (pySelf ? (sipWrapperType *)Py_TYPE((PyObject *)pySelf) : 0);
+ 
+     return qpycore_get_qmetaobject(wt, base);
+ }
+@@ -64,7 +64,8 @@ int qpycore_qobject_qt_metacall(sipSimpleWrapper *pySelf, sipTypeDef *base,
+     if (!pySelf)
+         return -1;
+ 
+-    return qt_metacall_worker(pySelf, Py_TYPE(pySelf), base, _c, _id, _a);
++    return qt_metacall_worker(pySelf, Py_TYPE((PyObject *)pySelf), base, _c,
++            _id, _a);
+ }
+ 
+ 
+@@ -236,13 +237,13 @@ bool qpycore_qobject_qt_metacast(sipSimpleWrapper *pySelf,
+ 
+     // We only need to look at the MRO if the object is a wrapped type (rather
+     // than a user sub-class).
+-    if (base_pytype != Py_TYPE(pySelf))
++    if (base_pytype != Py_TYPE((PyObject *)pySelf))
+     {
+         PyObject *mro;
+ 
+ #if PY_VERSION_HEX >= 0x03040000
+-        mro = PyObject_GetAttr((PyObject *)Py_TYPE(pySelf),
+-                qpycore_dunder_mro);
++        mro = PyObject_GetAttr(
++                (PyObject *)Py_TYPE((PyObject *)pySelf), qpycore_dunder_mro);
+         Q_ASSERT(mro);
+ #else
+         mro = Py_TYPE(pySelf)->tp_mro;
diff --git a/package/python-pyqt5/0004-configure.py-remove-Py_LIMITED_API.patch b/package/python-pyqt5/0004-configure.py-remove-Py_LIMITED_API.patch
new file mode 100644
index 0000000000..f3af7b7fa5
--- /dev/null
+++ b/package/python-pyqt5/0004-configure.py-remove-Py_LIMITED_API.patch
@@ -0,0 +1,37 @@
+From 2fbf73d6678e956a6240a6518371ea4bde158bb6 Mon Sep 17 00:00:00 2001
+From: Bernd Kuhls <bernd@kuhls.net>
+Date: Sun, 4 Oct 2026 14:34:24 +0200
+Subject: [PATCH] configure.py: remove Py_LIMITED_API
+
+PyWeakref_GetRef is needed since python 3.15 and used by patch 0003 to
+fix build errors, but PyWeakref_GetRef is only available when
+Py_LIMITED_API+0 >= 0x030D0000:
+https://github.com/python/cpython/blob/v3.15.0rc3/Include/weakrefobject.h#L32
+
+To fix the build error we remove the define set by configure.py.
+
+Upstream: not applicable, file was removed upstream:
+https://salsa.debian.org/python-team/packages/pyqt5/-/blob/debian/5.15.11+dfsg-7/ChangeLog#L33
+
+Signed-off-by: Bernd Kuhls <bernd@kuhls.net>
+---
+ configure.py | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/configure.py b/configure.py
+index a3450ca3..14e4e925 100644
+--- a/configure.py
++++ b/configure.py
+@@ -2673,9 +2673,6 @@ target.files = $$PY_MODULE
+ 
+     if metadata.qpy_lib:
+         # This is the easiest way to make sure it is set for handwritten code.
+-        if not target_config.py_debug:
+-            pro_lines.append('DEFINES += Py_LIMITED_API=0x03040000')
+-
+         pro_lines.append('INCLUDEPATH += %s' %
+                 qmake_quote(os.path.relpath(source_path('qpy', mname), mname)))
+ 
+-- 
+2.47.3
+
-- 
2.47.3

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [Buildroot] [PATCH 1/1] package/python-pyqt5: fix build with python-3.15
  2026-10-04 12:44 [Buildroot] [PATCH 1/1] package/python-pyqt5: fix build with python-3.15 Bernd Kuhls
@ 2026-10-10  8:26 ` Thomas Petazzoni via buildroot
  0 siblings, 0 replies; 2+ messages in thread
From: Thomas Petazzoni via buildroot @ 2026-10-10  8:26 UTC (permalink / raw)
  To: Bernd Kuhls; +Cc: buildroot, James Hilliard

On Sun, Oct 04, 2026 at 02:44:07PM +0200, Bernd Kuhls wrote:
> Please note that the upstream repo is private so we used the Debian
> mirror as source for patch 0003 which is marked as a cherry-pick by
> upstream.
> 
> Other mirrors are not updated: https://github.com/baoboa/pyqt5/issues/76
> 
> Signed-off-by: Bernd Kuhls <bernd@kuhls.net>

Applied to master, thanks!

Best regards,

Thomas Petazzoni
-- 
Thomas Petazzoni, co-owner and CEO, Bootlin
Embedded Linux and Kernel engineering and training
https://bootlin.com
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-10-13 17:57 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-04 12:44 [Buildroot] [PATCH 1/1] package/python-pyqt5: fix build with python-3.15 Bernd Kuhls
2026-10-10  8:26 ` Thomas Petazzoni via buildroot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox