* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.