diff --git a/AsLong.patch b/AsLong.patch new file mode 100644 index 0000000..8dedc34 --- /dev/null +++ b/AsLong.patch @@ -0,0 +1,55 @@ +From 82219d035526f2e587db3adc90c03d4901bfba77 Mon Sep 17 00:00:00 2001 +From: Christian Tismer +Date: Thu, 30 Sep 2021 18:51:43 +0200 +Subject: [PATCH] pep386impl: fix a left-over from the Python 2 cleanup + +_PepLong_AsInt still existed. This may be again a +rebasing glitch. + +Found when doing the first attempt to build PySide +on PyPy with Windows :) + +Pick-to: 6.2 +Task-number: PYSIDE-535 +Change-Id: Ic0b6167bc08c9da8e0d34d6ef2d5b71c8ee548c1 +Reviewed-by: Friedemann Kleint +--- + sources/shiboken6/libshiboken/pep384impl.h | 11 ----------- + sources/shiboken6/libshiboken/sbkarrayconverter.cpp | 2 +- + 2 files changed, 1 insertion(+), 12 deletions(-) + +Index: pyside-setup-opensource-src-5.15.16/sources/shiboken2/libshiboken/pep384impl.h +=================================================================== +--- pyside-setup-opensource-src-5.15.16.orig/sources/shiboken2/libshiboken/pep384impl.h ++++ pyside-setup-opensource-src-5.15.16/sources/shiboken2/libshiboken/pep384impl.h +@@ -178,17 +178,6 @@ LIBSHIBOKEN_API const char *PepType_GetN + + /***************************************************************************** + * +- * RESOLVED: longobject.h +- * +- */ +-#ifdef Py_LIMITED_API +-LIBSHIBOKEN_API int _PepLong_AsInt(PyObject *); +-#else +-#define _PepLong_AsInt _PyLong_AsInt +-#endif +- +-/***************************************************************************** +- * + * RESOLVED: pydebug.h + * + */ +Index: pyside-setup-opensource-src-5.15.16/sources/shiboken2/libshiboken/sbkarrayconverter.cpp +=================================================================== +--- pyside-setup-opensource-src-5.15.16.orig/sources/shiboken2/libshiboken/sbkarrayconverter.cpp ++++ pyside-setup-opensource-src-5.15.16/sources/shiboken2/libshiboken/sbkarrayconverter.cpp +@@ -161,7 +161,7 @@ static void sequenceToCppIntArray(PyObje + { + auto *handle = reinterpret_cast *>(cppOut); + handle->allocate(PySequence_Size(pyIn)); +- convertPySequence(pyIn, _PepLong_AsInt, handle->data()); ++ convertPySequence(pyIn, PyLong_AsLong, handle->data()); + } + + static PythonToCppFunc sequenceToCppIntArrayCheck(PyObject *pyIn, int dim1, int /* dim2 */) diff --git a/python3-pyside2.changes b/python3-pyside2.changes index 3d2e1a2..72ddd30 100644 --- a/python3-pyside2.changes +++ b/python3-pyside2.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Thu Feb 20 13:00:44 UTC 2025 - Markéta Machová + +- Add upstream patches to fix build with Python 3.13: + * AsLong.patch + * python312.patch + ------------------------------------------------------------------- Fri Jan 26 14:34:01 UTC 2024 - Ben Greiner diff --git a/python3-pyside2.spec b/python3-pyside2.spec index fe06052..6339c4e 100644 --- a/python3-pyside2.spec +++ b/python3-pyside2.spec @@ -1,7 +1,7 @@ # # spec file for package python3-pyside2 # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -55,12 +55,16 @@ Patch1: 0001-Don-t-try-to-install-or-use-uic-rcc-designer-copies.patch Patch2: 0001-cmake-Don-t-assume-qhelpgenerator-is-in-PATH.patch # PATCH-FIX-UPSTREAM Patch3: 0001-Fix-tests-sample_privatector-sample_privatedtor-fail.patch +# PATCH-FIX-UPSTREAM +Patch4: AsLong.patch +# PATCH-FIX-UPSTREAM, adapted to older codebase +Patch5: python312.patch # Provide the PyPI names Provides: %{mypython}-PySide2 = %{version}-%{release} Provides: %{mypython}-shiboken2 = %{version}-%{release} Provides: %{mypython}-shiboken2_generator = %{version}-%{release} Requires(post): update-alternatives -Requires(postun):update-alternatives +Requires(postun): update-alternatives # SECTION common_dependencies %if 0%{?suse_version} > 1500 # boo#1210176 - PYSIDE-2268 diff --git a/python312.patch b/python312.patch new file mode 100644 index 0000000..1b6ea36 --- /dev/null +++ b/python312.patch @@ -0,0 +1,346 @@ +From 441ffbd4fc622e67acd81e9c1c6d3a0b0fbcacf0 Mon Sep 17 00:00:00 2001 +From: Christian Tismer +Date: Tue, 14 Feb 2023 14:46:22 +0100 +Subject: [PATCH] Support running PySide on Python 3.12 + +Builtin types no longer have tp_dict set. We need to +use PyType_GetDict, instead. This works without Limited API +at the moment. + +With some great cheating, this works with Limited API, too. +We emulate PyType_GetDict by tp_dict if that is not 0. +Otherwise we create an empty dict. + +Some small changes to Exception handling and longer +warm-up in leaking tests were found, too. + +Pick-to: 6.6 6.5 6.2 +Task-number: PYSIDE-2230 +Change-Id: I8a56de6208ec00979255b39b5784dfc9b4b92def +Reviewed-by: Friedemann Kleint +--- + build_scripts/config.py | 1 + + sources/pyside2/libpyside/feature_select.cpp | 10 +++-- + sources/pyside2/libpyside/pysideproperty.cpp | 4 +- + sources/pyside2/libpyside/pysidesignal.cpp | 7 +-- + sources/pyside2/tests/QtWidgets/bug_662.py | 3 +- + sources/pyside2/tests/pysidetest/enum_test.py | 19 +++++++- + sources/pyside2/tests/signals/bug_79.py | 5 +++ + sources/shiboken2/libshiboken/pep384impl.cpp | 44 ++++++++++++++++--- + sources/shiboken2/libshiboken/pep384impl.h | 8 ++++ + .../shiboken2/libshiboken/sbkfeature_base.cpp | 32 +++++++++++--- + .../shiboken2/libshiboken/sbksmartpointer.cpp | 3 +- + .../shiboken2/libshiboken/sbktypefactory.cpp | 3 +- + .../libshiboken/signature/signature.cpp | 2 +- + .../signature/signature_helper.cpp | 6 ++- + .../shibokensupport/signature/errorhandler.py | 6 +++ + .../signature/lib/pyi_generator.py | 9 +++- + .../tests/samplebinding/enum_test.py | 2 +- + 17 files changed, 133 insertions(+), 31 deletions(-) + +Index: pyside-setup-opensource-src-5.15.12/sources/pyside2/libpyside/feature_select.cpp +=================================================================== +--- pyside-setup-opensource-src-5.15.12.orig/sources/pyside2/libpyside/feature_select.cpp ++++ pyside-setup-opensource-src-5.15.12/sources/pyside2/libpyside/feature_select.cpp +@@ -358,7 +358,8 @@ static bool SelectFeatureSetSubtype(PyTy + * This is the selector for one sublass. We need to call this for + * every subclass until no more subclasses or reaching the wanted id. + */ +- if (Py_TYPE(type->tp_dict) == Py_TYPE(PyType_Type.tp_dict)) { ++ static const auto *pyTypeType_tp_dict = PepType_GetDict(&PyType_Type); ++ if (Py_TYPE(type->tp_dict) == Py_TYPE(pyTypeType_tp_dict)) { + // On first touch, we initialize the dynamic naming. + // The dict type will be replaced after the first call. + if (!replaceClassDict(type)) { +@@ -385,7 +386,8 @@ static inline PyObject *SelectFeatureSet + * Generated functions call this directly. + * Shiboken will assign it via a public hook of `basewrapper.cpp`. + */ +- if (Py_TYPE(type->tp_dict) == Py_TYPE(PyType_Type.tp_dict)) { ++ static const auto *pyTypeType_tp_dict = PepType_GetDict(&PyType_Type); ++ if (Py_TYPE(type->tp_dict) == Py_TYPE(pyTypeType_tp_dict)) { + // We initialize the dynamic features by using our own dict type. + if (!replaceClassDict(type)) + return nullptr; +@@ -716,11 +718,11 @@ static bool patch_property_impl() + // Turn `__doc__` into a computed attribute without changing writability. + auto gsp = property_getset; + auto type = &PyProperty_Type; +- auto dict = type->tp_dict; ++ AutoDecRef dict(PepType_GetDict(type)); + AutoDecRef descr(PyDescr_NewGetSet(type, gsp)); + if (descr.isNull()) + return false; +- if (PyDict_SetItemString(dict, gsp->name, descr) < 0) ++ if (PyDict_SetItemString(dict.object(), gsp->name, descr) < 0) + return false; + // Replace property_descr_get/set by slightly changed versions + return true; +Index: pyside-setup-opensource-src-5.15.12/sources/pyside2/libpyside/pysideproperty.cpp +=================================================================== +--- pyside-setup-opensource-src-5.15.12.orig/sources/pyside2/libpyside/pysideproperty.cpp ++++ pyside-setup-opensource-src-5.15.12/sources/pyside2/libpyside/pysideproperty.cpp +@@ -445,8 +445,8 @@ namespace { + + static PyObject *getFromType(PyTypeObject *type, PyObject *name) + { +- PyObject *attr = nullptr; +- attr = PyDict_GetItem(type->tp_dict, name); ++ AutoDecRef tpDict(PepType_GetDict(type)); ++ auto *attr = PyDict_GetItem(tpDict.object(), name); + if (!attr) { + PyObject *bases = type->tp_bases; + int size = PyTuple_GET_SIZE(bases); +Index: pyside-setup-opensource-src-5.15.12/sources/pyside2/libpyside/pysidesignal.cpp +=================================================================== +--- pyside-setup-opensource-src-5.15.12.orig/sources/pyside2/libpyside/pysidesignal.cpp ++++ pyside-setup-opensource-src-5.15.12/sources/pyside2/libpyside/pysidesignal.cpp +@@ -671,7 +671,8 @@ void updateSourceObject(PyObject *source + PyObject *value; + PyObject *key; + +- while (PyDict_Next(objType->tp_dict, &pos, &key, &value)) { ++ Shiboken::AutoDecRef tpDict(PepType_GetDict(objType)); ++ while (PyDict_Next(tpDict, &pos, &key, &value)) { + if (PyObject_TypeCheck(value, PySideSignalTypeF())) { + Shiboken::AutoDecRef signalInstance(reinterpret_cast(PyObject_New(PySideSignalInstance, PySideSignalInstanceTypeF()))); + instanceInitialize(signalInstance.cast(), key, reinterpret_cast(value), source, 0); +Index: pyside-setup-opensource-src-5.15.12/sources/pyside2/tests/QtWidgets/bug_662.py +=================================================================== +--- pyside-setup-opensource-src-5.15.12.orig/sources/pyside2/tests/QtWidgets/bug_662.py ++++ pyside-setup-opensource-src-5.15.12/sources/pyside2/tests/QtWidgets/bug_662.py +@@ -40,7 +40,8 @@ from PySide2.QtWidgets import QTextEdit, + import sys + + class testQTextBlock(unittest.TestCase): +- def tesIterator(self): ++ ++ def testIterator(self): + edit = QTextEdit() + cursor = edit.textCursor() + fmt = QTextCharFormat() +Index: pyside-setup-opensource-src-5.15.12/sources/pyside2/tests/signals/bug_79.py +=================================================================== +--- pyside-setup-opensource-src-5.15.12.orig/sources/pyside2/tests/signals/bug_79.py ++++ pyside-setup-opensource-src-5.15.12/sources/pyside2/tests/signals/bug_79.py +@@ -60,6 +60,11 @@ class ConnectTest(unittest.TestCase): + gc.collect() + # if this is no debug build, then we check at least that + # we do not crash any longer. ++ for idx in range(200): ++ # PYSIDE-2230: Warm-up is necessary before measuring, because ++ # the code changes the constant parts after some time. ++ o.selectionModel().destroyed.connect(self.callback) ++ o.selectionModel().destroyed.disconnect(self.callback) + if not skiptest: + total = gettotalrefcount() + for idx in range(1000): +Index: pyside-setup-opensource-src-5.15.12/sources/shiboken2/libshiboken/basewrapper.cpp +=================================================================== +--- pyside-setup-opensource-src-5.15.12.orig/sources/shiboken2/libshiboken/basewrapper.cpp ++++ pyside-setup-opensource-src-5.15.12/sources/shiboken2/libshiboken/basewrapper.cpp +@@ -1,6 +1,6 @@ + /**************************************************************************** + ** +-** Copyright (C) 2019 The Qt Company Ltd. ++** Copyright (C) 2023 The Qt Company Ltd. + ** Contact: https://www.qt.io/licensing/ + ** + ** This file is part of Qt for Python. +@@ -250,7 +250,8 @@ patch_tp_new_wrapper(PyTypeObject *type) + Py_ssize_t i, n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + type = reinterpret_cast(PyTuple_GET_ITEM(mro, i)); +- PyObject *existing = PyDict_GetItem(type->tp_dict, newMethod); ++ Shiboken::AutoDecRef tpDict(PepType_GetDict(type)); ++ PyObject *existing = PyDict_GetItem(tpDict, newMethod); + if (existing && PyCFunction_Check(existing) + && type->tp_flags & Py_TPFLAGS_HEAPTYPE) { + auto *pycf_ob = reinterpret_cast(existing); +@@ -260,7 +261,8 @@ patch_tp_new_wrapper(PyTypeObject *type) + if (existing_wrapper == old_tp_new_wrapper) { + PyObject *ob_type = reinterpret_cast(type); + Shiboken::AutoDecRef func(PyCFunction_New(tp_new_methoddef, ob_type)); +- if (func.isNull() || PyDict_SetItem(type->tp_dict, newMethod, func)) ++ Shiboken::AutoDecRef tpDict(PepType_GetDict(type)); ++ if (func.isNull() || PyDict_SetItem(tpDict, newMethod, func)) + return -1; + } + } +Index: pyside-setup-opensource-src-5.15.12/sources/shiboken2/libshiboken/pep384impl.cpp +=================================================================== +--- pyside-setup-opensource-src-5.15.12.orig/sources/shiboken2/libshiboken/pep384impl.cpp ++++ pyside-setup-opensource-src-5.15.12/sources/shiboken2/libshiboken/pep384impl.cpp +@@ -560,6 +560,39 @@ PyDict_GetItemWithError(PyObject *op, Py + } + #endif // IS_PY2 + ++#ifdef Py_LIMITED_API ++static PyObject *emulatePyType_GetDict(PyTypeObject *type) ++{ ++ if (_PepRuntimeVersion() < 0x030C00 || type->tp_dict) { ++ auto *res = type->tp_dict; ++ Py_XINCREF(res); ++ return res; ++ } ++ // PYSIDE-2230: Here we are really cheating. We don't know how to ++ // access an internal dict, and so we simply pretend ++ // it were an empty dict. This works great for our types. ++ // This was an unexpectedly simple solution :D ++ return PyDict_New(); ++} ++#endif ++ ++// PyType_GetDict: replacement for .tp_dict, which is ++// zero for builtin types since 3.12. ++PyObject *PepType_GetDict(PyTypeObject *type) ++{ ++#if !defined(Py_LIMITED_API) ++# if PY_VERSION_HEX >= 0x030C0000 ++ return PyType_GetDict(type); ++# else ++ // pre 3.12 fallback code, mimicking the addref-behavior. ++ Py_XINCREF(type->tp_dict); ++ return type->tp_dict; ++# endif ++#else ++ return emulatePyType_GetDict(type); ++#endif // Py_LIMITED_API ++} ++ + /***************************************************************************** + * + * Extra support for signature.cpp +Index: pyside-setup-opensource-src-5.15.12/sources/shiboken2/libshiboken/pep384impl.h +=================================================================== +--- pyside-setup-opensource-src-5.15.12.orig/sources/shiboken2/libshiboken/pep384impl.h ++++ pyside-setup-opensource-src-5.15.12/sources/shiboken2/libshiboken/pep384impl.h +@@ -559,6 +559,14 @@ extern LIBSHIBOKEN_API int PepRuntime_38 + + /***************************************************************************** + * ++ * Runtime support for Python 3.12 incompatibility ++ * ++ */ ++ ++LIBSHIBOKEN_API PyObject *PepType_GetDict(PyTypeObject *type); ++ ++/***************************************************************************** ++ * + * Module Initialization + * + */ +Index: pyside-setup-opensource-src-5.15.12/sources/shiboken2/libshiboken/signature/signature.cpp +=================================================================== +--- pyside-setup-opensource-src-5.15.12.orig/sources/shiboken2/libshiboken/signature/signature.cpp ++++ pyside-setup-opensource-src-5.15.12/sources/shiboken2/libshiboken/signature/signature.cpp +@@ -482,7 +482,7 @@ static PyObject *adjustFuncName(const ch + + // Find the feature flags + auto type = reinterpret_cast(obtype.object()); +- auto dict = type->tp_dict; ++ AutoDecRef dict(PepType_GetDict(type)); + int id = SbkObjectType_GetReserved(type); + id = id < 0 ? 0 : id; // if undefined, set to zero + auto lower = id & 0x01; +Index: pyside-setup-opensource-src-5.15.12/sources/shiboken2/libshiboken/signature/signature_helper.cpp +=================================================================== +--- pyside-setup-opensource-src-5.15.12.orig/sources/shiboken2/libshiboken/signature/signature_helper.cpp ++++ pyside-setup-opensource-src-5.15.12/sources/shiboken2/libshiboken/signature/signature_helper.cpp +@@ -105,7 +105,8 @@ int add_more_getsets(PyTypeObject *type, + */ + assert(PyType_Check(type)); + PyType_Ready(type); +- PyObject *dict = type->tp_dict; ++ AutoDecRef tpDict(PepType_GetDict(type)); ++ auto *dict = tpDict.object(); + for (; gsp->name != nullptr; gsp++) { + PyObject *have_descr = PyDict_GetItemString(dict, gsp->name); + if (have_descr != nullptr) { +@@ -346,7 +347,8 @@ static int _build_func_to_type(PyObject + * We also check for hidden methods, see below. + */ + auto *type = reinterpret_cast(obtype); +- PyObject *dict = type->tp_dict; ++ AutoDecRef tpDict(PepType_GetDict(type)); ++ auto *dict = tpDict.object(); + PyMethodDef *meth = type->tp_methods; + + if (meth == nullptr) +Index: pyside-setup-opensource-src-5.15.12/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py +=================================================================== +--- pyside-setup-opensource-src-5.15.12.orig/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py ++++ pyside-setup-opensource-src-5.15.12/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py +@@ -113,6 +113,12 @@ def seterror_argument(args, func_name, i + msg = "{func_name}(): {info}".format(**locals()) + err = AttributeError + return err, msg ++ if isinstance(info, Exception): ++ # PYSIDE-2230: Python 3.12 seems to always do normalization. ++ err = type(info) ++ info = info.args[0] ++ msg = f"{func_name}(): {info}" ++ return err, msg + if info and type(info) is dict: + keyword = tuple(info)[0] + msg = "{func_name}(): unsupported keyword '{keyword}'".format(**locals()) +Index: pyside-setup-opensource-src-5.15.12/sources/shiboken2/tests/samplebinding/enum_test.py +=================================================================== +--- pyside-setup-opensource-src-5.15.12.orig/sources/shiboken2/tests/samplebinding/enum_test.py ++++ pyside-setup-opensource-src-5.15.12/sources/shiboken2/tests/samplebinding/enum_test.py +@@ -95,7 +95,7 @@ class EnumTest(unittest.TestCase): + + def testEnumConstructorWithTooManyParameters(self): + '''Calling the constructor of non-extensible enum with the wrong number of parameters.''' +- self.assertRaises(TypeError, SampleNamespace.InValue, 13, 14) ++ self.assertRaises((TypeError, ValueError), SampleNamespace.InValue, 13, 14) + + def testEnumConstructorWithNonNumberParameter(self): + '''Calling the constructor of non-extensible enum with a string.''' +Index: pyside-setup-opensource-src-5.15.12/sources/pyside2/PySide2/support/generate_pyi.py +=================================================================== +--- pyside-setup-opensource-src-5.15.12.orig/sources/pyside2/PySide2/support/generate_pyi.py ++++ pyside-setup-opensource-src-5.15.12/sources/pyside2/PySide2/support/generate_pyi.py +@@ -116,7 +116,12 @@ class Formatter(Writer): + """ + def _typevar__repr__(self): + return "typing." + self.__name__ +- typing.TypeVar.__repr__ = _typevar__repr__ ++ # This is no longer necessary for modern typing versions. ++ # Ignore therefore if the repr is read-only and cannot be changed. ++ try: ++ typing.TypeVar.__repr__ = _typevar__repr__ ++ except TypeError: ++ pass + + # Adding a pattern to substitute "Union[T, NoneType]" by "Optional[T]" + # I tried hard to replace typing.Optional by a simple override, but +Index: pyside-setup-opensource-src-5.15.12/build_scripts/config.py +=================================================================== +--- pyside-setup-opensource-src-5.15.12.orig/build_scripts/config.py ++++ pyside-setup-opensource-src-5.15.12/build_scripts/config.py +@@ -94,7 +94,9 @@ class Config(object): + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', +- 'Programming Language :: Python :: 3.11' ++ 'Programming Language :: Python :: 3.11', ++ 'Programming Language :: Python :: 3.12', ++ 'Programming Language :: Python :: 3.13' + ] + + self.setup_script_dir = None +Index: pyside-setup-opensource-src-5.15.12/sources/shiboken2/tests/otherbinding/module_reload_test.py +=================================================================== +--- pyside-setup-opensource-src-5.15.12.orig/sources/shiboken2/tests/otherbinding/module_reload_test.py ++++ pyside-setup-opensource-src-5.15.12/sources/shiboken2/tests/otherbinding/module_reload_test.py +@@ -41,7 +41,8 @@ init_paths() + from py3kcompat import IS_PY3K + + if IS_PY3K: +- from imp import reload ++ # available from 3.1 ++ from importlib import reload + + orig_path = os.path.join(os.path.dirname(__file__)) + workdir = os.getcwd()