Update pyside2/shiboken2 and sip4 to Python 3.12

These are both Python QT 5 modules, which have issues with Python 3.12
that are fixed in never versions, yet many packages depend on them.

Sip4 was as simple as installing and switching over to setuptools (to
replace the now removed distutils).

pyside/shiboken was much more involved. I ended up pulling the required
patches from the Ubuntu release repositories. The existing patch to fix
clang's include headers needed an update as well, but was still
required.

There is some unsightly find-and-replace going on to replace distutils
with setuptools. This is because, although setuptools now creates the
"distutils" import module, it has to be itself imported first before
that can happen. I Used this widespread find-and-replace as it does
function properly, and should be extremly flexable for future versions
(no needing to update patches on each release).
This commit is contained in:
Mitchell Pleune 2024-07-16 13:09:15 -04:00
parent c1c8cbe79b
commit b65dfc3161
16 changed files with 1238 additions and 49 deletions

View File

@ -0,0 +1,28 @@
From: =?utf-8?q?Cristi=C3=A1n_Maureira-Fredes?=
<Cristian.Maureira-Fredes@qt.io>
Date: Tue, 10 Oct 2023 15:52:09 +0200
Subject: Final details to enable 3.12 wheel compatibility
Change-Id: I0252c4e73e8c214ef8aa418ddf88bc452c0fdf53
Pick-to: 6.6
Task-number: PYSIDE-2230
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
(cherry picked from commit 6c7bb7b6e1008909e49bc04d2a48024309a784cc)
---
build_scripts/config.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build_scripts/config.py b/build_scripts/config.py
index 5fc23d4..fb27394 100644
--- a/build_scripts/config.py
+++ b/build_scripts/config.py
@@ -138,7 +138,7 @@ class Config(object):
setup_kwargs['zip_safe'] = False
setup_kwargs['cmdclass'] = cmd_class_dict
setup_kwargs['version'] = package_version
- setup_kwargs['python_requires'] = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <3.12"
+ setup_kwargs['python_requires'] = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <3.13"
if quiet:
# Tells distutils / setuptools to be quiet, and only print warnings or errors.

View File

@ -0,0 +1,41 @@
From: Dmitry Shachnev <mitya57@debian.org>
Date: Sun, 4 Feb 2024 00:29:00 +0300
Subject: Modify sendCommand signatures to use 0 as default value
The original default value was QNodeCommand::CommandId(), and shiboken
copies it verbatim from the header file, however it does not work because
we do not generate "using namespace Qt3DCore;".
0 is the same as QNodeCommand::CommandId().
---
sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml b/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml
index 8696a12..310595f 100644
--- a/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml
+++ b/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml
@@ -58,6 +58,11 @@
<object-type name="QAspectJob"/>
<object-type name="QBackendNode">
<enum-type name="Mode"/>
+ <modify-function signature="sendCommand(const QString&amp;,const QVariant&amp;,unsigned long long)">
+ <modify-argument index="3">
+ <replace-default-expression with="0"/>
+ </modify-argument>
+ </modify-function>
</object-type>
<!-- TODO: Solve issues related to windows and a unresolved
external symbol
@@ -82,6 +87,11 @@
</object-type>
<object-type name="QNode">
<enum-type name="PropertyTrackingMode"/>
+ <modify-function signature="sendCommand(const QString&amp;,const QVariant&amp;,unsigned long long)">
+ <modify-argument index="3">
+ <replace-default-expression with="0"/>
+ </modify-argument>
+ </modify-function>
</object-type>
<object-type name="QNodeCommand" since="5.10"/>
<object-type name="QNodeCreatedChangeBase"/>

View File

@ -0,0 +1,37 @@
From: Christian Tismer <tismer@stackless.com>
Date: Tue, 14 Feb 2023 14:46:22 +0100
Subject: Python 3.12: Fix the structure of class property
There is a PySide bug in Python 3.10 already: The structure for
classproperty derives from the property structure. This was extended
in Python 3.10, already, but the type generation check was made more
exhaustive in Python 3.12 and recognized that.
This change is only for making the compiler/C API happy.
In order to use the extension field, it is necessary to do a runtime
check because of the Limited API.
Task-number: PYSIDE-2230
Change-Id: I88dcaa11589ff41852f08fa2defa5200a0dd4eb6
Reviewed-by: Adrian Herrmann <adrian.herrmann@qt.io>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
(cherry picked from commit edfd9a5ad174a48f8d7da511dc6a1c69e931a418)
---
sources/pyside2/libpyside/feature_select.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/sources/pyside2/libpyside/feature_select.cpp b/sources/pyside2/libpyside/feature_select.cpp
index 3011b35..b9e1470 100644
--- a/sources/pyside2/libpyside/feature_select.cpp
+++ b/sources/pyside2/libpyside/feature_select.cpp
@@ -671,6 +671,11 @@ typedef struct {
PyObject *prop_set;
PyObject *prop_del;
PyObject *prop_doc;
+#if PY_VERSION_HEX >= 0x030A0000
+ // Note: This is a problem with Limited API: We have no direct access.
+ // You need to pick it from runtime info.
+ PyObject *prop_name;
+#endif
int getter_doc;
} propertyobject;

View File

@ -0,0 +1,298 @@
From: Christian Tismer <tismer@stackless.com>
Date: Tue, 14 Feb 2023 14:46:22 +0100
Subject: 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 <Friedemann.Kleint@qt.io>
(cherry picked from commit 441ffbd4fc622e67acd81e9c1c6d3a0b0fbcacf0)
---
build_scripts/config.py | 3 +-
sources/pyside2/PySide2/support/generate_pyi.py | 8 ++++--
sources/pyside2/libpyside/feature_select.cpp | 10 ++++---
sources/pyside2/libpyside/pysideproperty.cpp | 4 +--
sources/pyside2/libpyside/pysidesignal.cpp | 4 +--
sources/pyside2/tests/QtWidgets/bug_662.py | 3 +-
sources/pyside2/tests/signals/bug_79.py | 5 ++++
sources/shiboken2/libshiboken/pep384impl.cpp | 33 ++++++++++++++++++++++
sources/shiboken2/libshiboken/pep384impl.h | 8 ++++++
.../shiboken2/libshiboken/signature/signature.cpp | 2 +-
.../libshiboken/signature/signature_helper.cpp | 6 ++--
.../shibokensupport/signature/errorhandler.py | 6 ++++
sources/shiboken2/tests/samplebinding/enum_test.py | 2 +-
13 files changed, 78 insertions(+), 16 deletions(-)
diff --git a/build_scripts/config.py b/build_scripts/config.py
index f2b4c40..5fc23d4 100644
--- a/build_scripts/config.py
+++ b/build_scripts/config.py
@@ -94,7 +94,8 @@ 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',
]
self.setup_script_dir = None
diff --git a/sources/pyside2/PySide2/support/generate_pyi.py b/sources/pyside2/PySide2/support/generate_pyi.py
index 1956533..fd05b1f 100644
--- a/sources/pyside2/PySide2/support/generate_pyi.py
+++ b/sources/pyside2/PySide2/support/generate_pyi.py
@@ -116,8 +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
# this became _way_ too much.
diff --git a/sources/pyside2/libpyside/feature_select.cpp b/sources/pyside2/libpyside/feature_select.cpp
index b9e1470..533c09d 100644
--- a/sources/pyside2/libpyside/feature_select.cpp
+++ b/sources/pyside2/libpyside/feature_select.cpp
@@ -358,7 +358,8 @@ static bool SelectFeatureSetSubtype(PyTypeObject *type, PyObject *select_id)
* 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(PyTypeObject *type)
* 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;
@@ -721,11 +723,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;
diff --git a/sources/pyside2/libpyside/pysideproperty.cpp b/sources/pyside2/libpyside/pysideproperty.cpp
index 86909d3..d2e2c68 100644
--- a/sources/pyside2/libpyside/pysideproperty.cpp
+++ b/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);
diff --git a/sources/pyside2/libpyside/pysidesignal.cpp b/sources/pyside2/libpyside/pysidesignal.cpp
index 6824a71..f15d7aa 100644
--- a/sources/pyside2/libpyside/pysidesignal.cpp
+++ b/sources/pyside2/libpyside/pysidesignal.cpp
@@ -670,8 +670,8 @@ void updateSourceObject(PyObject *source)
Py_ssize_t pos = 0;
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 *>(PyObject_New(PySideSignalInstance, PySideSignalInstanceTypeF())));
instanceInitialize(signalInstance.cast<PySideSignalInstance *>(), key, reinterpret_cast<PySideSignal *>(value), source, 0);
diff --git a/sources/pyside2/tests/QtWidgets/bug_662.py b/sources/pyside2/tests/QtWidgets/bug_662.py
index 7fb97de..ec0e6f9 100644
--- a/sources/pyside2/tests/QtWidgets/bug_662.py
+++ b/sources/pyside2/tests/QtWidgets/bug_662.py
@@ -40,7 +40,8 @@ from PySide2.QtWidgets import QTextEdit, QApplication
import sys
class testQTextBlock(unittest.TestCase):
- def tesIterator(self):
+
+ def testIterator(self):
edit = QTextEdit()
cursor = edit.textCursor()
fmt = QTextCharFormat()
diff --git a/sources/pyside2/tests/signals/bug_79.py b/sources/pyside2/tests/signals/bug_79.py
index ca25fb3..b70c8c5 100644
--- a/sources/pyside2/tests/signals/bug_79.py
+++ b/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):
diff --git a/sources/shiboken2/libshiboken/pep384impl.cpp b/sources/shiboken2/libshiboken/pep384impl.cpp
index d12dae3..fed2716 100644
--- a/sources/shiboken2/libshiboken/pep384impl.cpp
+++ b/sources/shiboken2/libshiboken/pep384impl.cpp
@@ -810,6 +810,39 @@ init_PepRuntime()
PepRuntime_38_flag = 1;
}
+#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 <static type>.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
+}
+
/*****************************************************************************
*
* Module Initialization
diff --git a/sources/shiboken2/libshiboken/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h
index a870d6b..440784e 100644
--- a/sources/shiboken2/libshiboken/pep384impl.h
+++ b/sources/shiboken2/libshiboken/pep384impl.h
@@ -567,6 +567,14 @@ extern LIBSHIBOKEN_API PyObject *PepMapping_Items(PyObject *o);
extern LIBSHIBOKEN_API int PepRuntime_38_flag;
+/*****************************************************************************
+ *
+ * Runtime support for Python 3.12 incompatibility
+ *
+ */
+
+LIBSHIBOKEN_API PyObject *PepType_GetDict(PyTypeObject *type);
+
/*****************************************************************************
*
* Module Initialization
diff --git a/sources/shiboken2/libshiboken/signature/signature.cpp b/sources/shiboken2/libshiboken/signature/signature.cpp
index 191af3d..f817e47 100644
--- a/sources/shiboken2/libshiboken/signature/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature/signature.cpp
@@ -482,7 +482,7 @@ static PyObject *adjustFuncName(const char *func_name)
// Find the feature flags
auto type = reinterpret_cast<PyTypeObject *>(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;
diff --git a/sources/shiboken2/libshiboken/signature/signature_helper.cpp b/sources/shiboken2/libshiboken/signature/signature_helper.cpp
index 0246ec6..05eaa14 100644
--- a/sources/shiboken2/libshiboken/signature/signature_helper.cpp
+++ b/sources/shiboken2/libshiboken/signature/signature_helper.cpp
@@ -105,7 +105,8 @@ int add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **doc_descr)
*/
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 *obtype)
* We also check for hidden methods, see below.
*/
auto *type = reinterpret_cast<PyTypeObject *>(obtype);
- PyObject *dict = type->tp_dict;
+ AutoDecRef tpDict(PepType_GetDict(type));
+ auto *dict = tpDict.object();
PyMethodDef *meth = type->tp_methods;
if (meth == nullptr)
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py
index 47ab89a..3e1266c 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py
@@ -113,6 +113,12 @@ def seterror_argument(args, func_name, info):
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())
diff --git a/sources/shiboken2/tests/samplebinding/enum_test.py b/sources/shiboken2/tests/samplebinding/enum_test.py
index 0beb720..f2606a4 100644
--- a/sources/shiboken2/tests/samplebinding/enum_test.py
+++ b/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.'''

View File

@ -1,5 +1,6 @@
{
python,
pythonAtLeast,
fetchurl,
lib,
stdenv,
@ -11,18 +12,51 @@
}:
stdenv.mkDerivation rec {
pname = "pyside2";
version = "5.15.11";
version = "5.15.14";
src = fetchurl {
url = "https://download.qt.io/official_releases/QtForPython/pyside2/PySide2-${version}-src/pyside-setup-opensource-src-${version}.tar.xz";
sha256 = "sha256-2lZ807eFTSegtK/j6J3osvmLem1XOTvlbx/BP3cPryk=";
hash = "sha256-MmURlPamt7zkLwTmixQBrSCH5HiaTI8/uGSehhicY3I=";
};
patches = [ ./dont_ignore_optional_modules.patch ];
patches = [
./nix_compile_cflags.patch
./Final-details-to-enable-3.12-wheel-compatibility.patch
./Python-3.12-Fix-the-structure-of-class-property.patch
./Support-running-PySide-on-Python-3.12.patch
./shiboken2-clang-Fix-and-simplify-resolveType-helper.patch
./shiboken2-clang-Fix-build-with-clang-16.patch
./shiboken2-clang-Fix-clashes-between-type-name-and-enumera.patch
./shiboken2-clang-Record-scope-resolution-of-arguments-func.patch
./shiboken2-clang-Remove-typedef-expansion.patch
./shiboken2-clang-Suppress-class-scope-look-up-for-paramete.patch
./shiboken2-clang-Write-scope-resolution-for-all-parameters.patch
./dont_ignore_optional_modules.patch
./Modify-sendCommand-signatures.patch
];
postPatch = ''
cd sources/pyside2
'';
postPatch =
(lib.optionalString (pythonAtLeast "3.12") ''
substituteInPlace \
ez_setup.py \
build_scripts/main.py \
build_scripts/options.py \
build_scripts/utils.py \
build_scripts/wheel_override.py \
build_scripts/wheel_utils.py \
sources/pyside2/CMakeLists.txt \
--replace-fail "from distutils" "import setuptools; from distutils"
substituteInPlace \
build_scripts/config.py \
build_scripts/main.py \
build_scripts/options.py \
build_scripts/setup_runner.py \
build_scripts/utils.py \
--replace-fail "import distutils" "import setuptools; import distutils"
'')
+ ''
cd sources/pyside2
'';
cmakeFlags = [
"-DBUILD_TESTS=OFF"
@ -36,6 +70,7 @@ stdenv.mkDerivation rec {
ninja
qt5.qmake
python
python.pkgs.setuptools
];
buildInputs =

View File

@ -0,0 +1,23 @@
diff --git a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
index add278a..2626eb6 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
@@ -349,11 +349,15 @@ QByteArrayList emulatedCompilerOptions()
// Append the c++ include paths since Clang is unable to find
// <type_traits> etc (g++ 11.3).
- const HeaderPaths gppPaths = gppInternalIncludePaths(compilerFromCMake(QStringLiteral("g++")));
+ const HeaderPaths gppPaths = gppInternalIncludePaths(QStringLiteral("g++"));
for (const HeaderPath &h : gppPaths) {
- if (h.path.contains("c++")
- || h.path.contains("sysroot")) { // centOS
+ // PySide2 requires that Qt headers are not -isystem
+ // https://bugreports.qt.io/browse/PYSIDE-787
+ if (!h.path.contains("-qt")) {
+ // add using -isystem
headerPaths.append(h);
+ } else {
+ headerPaths.append({h.path, HeaderType::Standard});
}
}
#else

View File

@ -0,0 +1,88 @@
From: Friedemann Kleint <Friedemann.Kleint@qt.io>
Date: Tue, 25 Apr 2023 10:00:39 +0200
Subject: shiboken2/clang: Fix and simplify resolveType() helper
The function had a bug which only manifested with clang 16:
"type" should have been assigned the type of the cursor
obtained from clang_getTypeDeclaration(). With this, the complicated
lookup code in getBaseClass() can be removed.
Task-number: PYSIDE-2288
Pick-to: 6.5
Change-Id: I861e30451b3f4af2ec0c2e4ffa4179a429854533
Reviewed-by: Christian Tismer <tismer@stackless.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
---
.../ApiExtractor/clangparser/clangbuilder.cpp | 39 ++++++++++------------
1 file changed, 18 insertions(+), 21 deletions(-)
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
index e8e5bcf..1b4c81c 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
@@ -627,6 +627,9 @@ long clang_EnumDecl_isScoped4(BaseVisitor *bv, const CXCursor &cursor)
#endif // CLANG_NO_ENUMDECL_ISSCOPED
// Resolve declaration and type of a base class
+// Note: TypeAliasTemplateDecl ("using QVector<T>=QList<T>") is automatically
+// resolved by clang_getTypeDeclaration(), but it stops at
+// TypeAliasDecl / TypedefDecl.
struct TypeDeclaration
{
@@ -634,19 +637,23 @@ struct TypeDeclaration
CXCursor declaration;
};
+static inline bool isTypeAliasDecl(const CXCursor &cursor)
+{
+ const auto kind = clang_getCursorKind(cursor);
+ return kind == CXCursor_TypeAliasDecl || kind == CXCursor_TypedefDecl;
+}
+
static TypeDeclaration resolveBaseSpecifier(const CXCursor &cursor)
{
Q_ASSERT(clang_getCursorKind(cursor) == CXCursor_CXXBaseSpecifier);
CXType inheritedType = clang_getCursorType(cursor);
CXCursor decl = clang_getTypeDeclaration(inheritedType);
- if (inheritedType.kind != CXType_Unexposed) {
- while (true) {
- auto kind = clang_getCursorKind(decl);
- if (kind != CXCursor_TypeAliasDecl && kind != CXCursor_TypedefDecl)
- break;
- inheritedType = clang_getTypedefDeclUnderlyingType(decl);
- decl = clang_getTypeDeclaration(inheritedType);
- }
+ auto resolvedType = clang_getCursorType(decl);
+ if (resolvedType.kind != CXType_Invalid && resolvedType.kind != inheritedType.kind)
+ inheritedType = resolvedType;
+ while (isTypeAliasDecl(decl)) {
+ inheritedType = clang_getTypedefDeclUnderlyingType(decl);
+ decl = clang_getTypeDeclaration(inheritedType);
}
return {inheritedType, decl};
}
@@ -656,20 +663,10 @@ void BuilderPrivate::addBaseClass(const CXCursor &cursor)
{
Q_ASSERT(clang_getCursorKind(cursor) == CXCursor_CXXBaseSpecifier);
// Note: spelling has "struct baseClass", use type
- QString baseClassName;
const auto decl = resolveBaseSpecifier(cursor);
- if (decl.type.kind == CXType_Unexposed) {
- // The type is unexposed when the base class is a template type alias:
- // "class QItemSelection : public QList<X>" where QList is aliased to QVector.
- // Try to resolve via code model.
- TypeInfo info = createTypeInfo(decl.type);
- auto parentScope = m_scopeStack.at(m_scopeStack.size() - 2); // Current is class.
- auto resolved = TypeInfo::resolveType(info, parentScope);
- if (resolved != info)
- baseClassName = resolved.toString();
- }
- if (baseClassName.isEmpty())
- baseClassName = getTypeName(decl.type);
+ QString baseClassName = getTypeName(decl.type);
+ if (baseClassName.startsWith(u"std::")) // Simplify "std::" types
+ baseClassName = createTypeInfo(decl.type).toString();
auto it = m_cursorClassHash.constFind(decl.declaration);
const CodeModel::AccessPolicy access = accessPolicy(clang_getCXXAccessSpecifier(cursor));

View File

@ -0,0 +1,108 @@
From: Friedemann Kleint <Friedemann.Kleint@qt.io>
Date: Tue, 25 Apr 2023 14:01:45 +0200
Subject: shiboken2/clang: Fix build with clang 16
clang 16 returns more elaborated types instead of fully qualified type
names. Qualify elaborated types when retrieving the type name.
[ChangeLog][shiboken6] Support for libclang version 16 has been added.
Task-number: PYSIDE-2288
Pick-to: 6.5 5.15
Change-Id: Ibd428280180967f11d82a72159e744c016afc927
Reviewed-by: Christian Tismer <tismer@stackless.com>
(cherry picked from commit 44ef1859214c66861a251d4a0faf5c38dc050850)
---
.../ApiExtractor/clangparser/clangbuilder.cpp | 2 +-
.../ApiExtractor/clangparser/clangutils.cpp | 23 ++++++++++++++++++++++
.../ApiExtractor/clangparser/clangutils.h | 1 +
.../shiboken2/ApiExtractor/tests/testtemplates.cpp | 3 +--
4 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
index 332f1da..ed1e15d 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
@@ -524,7 +524,7 @@ TypeInfo BuilderPrivate::createTypeInfoHelper(const CXType &type) const
typeInfo.setConstant(clang_isConstQualifiedType(nestedType) != 0);
typeInfo.setVolatile(clang_isVolatileQualifiedType(nestedType) != 0);
- QString typeName = getTypeName(nestedType);
+ QString typeName = getResolvedTypeName(nestedType);
while (TypeInfo::stripLeadingConst(&typeName)
|| TypeInfo::stripLeadingVolatile(&typeName)) {
}
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
index 57271ef..295ede3 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
@@ -130,6 +130,23 @@ QString getCursorDisplayName(const CXCursor &cursor)
return result;
}
+static inline bool isBuiltinType(CXTypeKind kind)
+{
+ return kind >= CXType_FirstBuiltin && kind <= CXType_LastBuiltin;
+}
+
+// Resolve elaborated types occurring with clang 16
+static CXType resolveType(const CXType &type)
+{
+ if (!isBuiltinType(type.kind)) {
+ CXCursor decl = clang_getTypeDeclaration(type);
+ auto resolvedType = clang_getCursorType(decl);
+ if (resolvedType.kind != CXType_Invalid && resolvedType.kind != type.kind)
+ return resolvedType;
+ }
+ return type;
+}
+
QString getTypeName(const CXType &type)
{
CXString typeSpelling = clang_getTypeSpelling(type);
@@ -138,6 +155,12 @@ QString getTypeName(const CXType &type)
return result;
}
+// Resolve elaborated types occurring with clang 16
+QString getResolvedTypeName(const CXType &type)
+{
+ return getTypeName(resolveType(type));
+}
+
Diagnostic::Diagnostic(const QString &m, const CXCursor &c, CXDiagnosticSeverity s)
: message(m), source(Other), severity(s)
{
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.h b/sources/shiboken2/ApiExtractor/clangparser/clangutils.h
index f7c230a..aacaf63 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangutils.h
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangutils.h
@@ -52,6 +52,7 @@ QString getCursorKindName(CXCursorKind cursorKind);
QString getCursorSpelling(const CXCursor &cursor);
QString getCursorDisplayName(const CXCursor &cursor);
QString getTypeName(const CXType &type);
+QString getResolvedTypeName(const CXType &type);
inline QString getCursorTypeName(const CXCursor &cursor)
{ return getTypeName(clang_getCursorType(cursor)); }
inline QString getCursorResultTypeName(const CXCursor &cursor)
diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
index 9f929c4..fbc5c4c 100644
--- a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
@@ -236,7 +236,6 @@ struct List {
const AbstractMetaFunction *erase = list->findFunction(QStringLiteral("erase"));
QVERIFY(erase);
QCOMPARE(erase->arguments().size(), 1);
- QEXPECT_FAIL("", "Clang: Some other code changes the parameter type", Abort);
QCOMPARE(erase->arguments().at(0)->type()->cppSignature(), QLatin1String("List::Iterator"));
}
@@ -389,7 +388,7 @@ typedef BaseTemplateClass<TypeOne> TypeOneClass;
const ComplexTypeEntry* oneType = one->typeEntry();
const ComplexTypeEntry* baseType = base->typeEntry();
QCOMPARE(oneType->baseContainerType(), baseType);
- QCOMPARE(one->baseClassNames(), QStringList(QLatin1String("BaseTemplateClass<TypeOne>")));
+ QCOMPARE(one->baseClassNames(), QStringList(QLatin1String("NSpace::BaseTemplateClass<NSpace::TypeOne>")));
QVERIFY(one->hasTemplateBaseClassInstantiations());
AbstractMetaTypeList instantiations = one->templateBaseClassInstantiations();

View File

@ -0,0 +1,92 @@
From: Friedemann Kleint <Friedemann.Kleint@qt.io>
Date: Tue, 25 Apr 2023 15:30:30 +0200
Subject: shiboken2/clang: Fix clashes between type name and enumeration
values
Remove all constant and enum value type entries found in the type lookup
unless it is looking for template arguments; where it may be a
non-type template argument.
Task-number: PYSIDE-2288
Pick-to: 6.5 5.15
Change-Id: If0609ce0d0223f551ed6dee1d1e0ea3ef49d6917
Reviewed-by: Christian Tismer <tismer@stackless.com>
(cherry picked from commit e22f717153a5e9855531f45c0bf82ff2461a3f7e)
---
.../shiboken2/ApiExtractor/abstractmetabuilder.cpp | 21 +++++++++++++++++++--
.../shiboken2/ApiExtractor/abstractmetabuilder.h | 3 ++-
.../shiboken2/ApiExtractor/typesystem_typedefs.h | 1 +
3 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 5a413ec..2f34e16 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -2144,6 +2144,13 @@ static bool isNumber(const QString &s)
[](QChar c) { return c.isDigit(); });
}
+// A type entry relevant only for non type template "X<5>"
+static bool isNonTypeTemplateArgument(const TypeEntryCPtr &te)
+{
+ const auto type = te->type();
+ return type == TypeEntry::EnumValue || type == TypeEntry::ConstantValueType;
+}
+
AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei,
AbstractMetaClass *currentClass,
AbstractMetaBuilderPrivate *d,
@@ -2271,7 +2278,15 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
typeInfo.clearInstantiations();
}
- const TypeEntries types = findTypeEntries(qualifiedName, name, currentClass, d);
+ TypeEntries types = findTypeEntries(qualifiedName, name, currentClass, d);
+ if (!flags.testFlag(AbstractMetaBuilder::TemplateArgument)) {
+ // Avoid clashes between QByteArray and enum value QMetaType::QByteArray
+ // unless we are looking for template arguments.
+ auto end = std::remove_if(types.begin(), types.end(),
+ isNonTypeTemplateArgument);
+ types.erase(end, types.end());
+ }
+
if (types.isEmpty()) {
if (errorMessageIn) {
*errorMessageIn =
@@ -2293,7 +2308,9 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
const auto &templateArguments = typeInfo.instantiations();
for (int t = 0, size = templateArguments.size(); t < size; ++t) {
const TypeInfo &ti = templateArguments.at(t);
- AbstractMetaType *targType = translateTypeStatic(ti, currentClass, d, flags, &errorMessage);
+ AbstractMetaType *targType = translateTypeStatic(ti, currentClass, d,
+ flags | AbstractMetaBuilder::TemplateArgument,
+ &errorMessage);
// For non-type template parameters, create a dummy type entry on the fly
// as is done for classes.
if (!targType) {
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
index d2dc080..8916eaf 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
@@ -93,7 +93,8 @@ public:
void setSkipDeprecated(bool value);
enum TranslateTypeFlag {
- DontResolveType = 0x1
+ DontResolveType = 0x1,
+ TemplateArgument = 0x2
};
Q_DECLARE_FLAGS(TranslateTypeFlags, TranslateTypeFlag);
diff --git a/sources/shiboken2/ApiExtractor/typesystem_typedefs.h b/sources/shiboken2/ApiExtractor/typesystem_typedefs.h
index 73f92b2..5dcc65c 100644
--- a/sources/shiboken2/ApiExtractor/typesystem_typedefs.h
+++ b/sources/shiboken2/ApiExtractor/typesystem_typedefs.h
@@ -48,6 +48,7 @@ using CodeSnipList = QVector<CodeSnip>;
using DocModificationList = QVector<DocModification>;
using FieldModificationList = QVector<FieldModification>;
using FunctionModificationList = QVector<FunctionModification>;
+using TypeEntryCPtr = const TypeEntry *;
using TypeEntries = QVector<const TypeEntry *>;
#endif // TYPESYSTEM_TYPEDEFS_H

View File

@ -0,0 +1,178 @@
From: Friedemann Kleint <Friedemann.Kleint@qt.io>
Date: Thu, 27 Apr 2023 12:44:10 +0200
Subject: shiboken2/clang: Record scope resolution of arguments/function
return
Add a flag indicating whether a type was specified with a leading "::"
(scope resolution). Such parameters previously caused the function to
rejected due to the "::TypeName" not being found. The type resolution
added for clang 16 strips these qualifiers though, so, the information
needs to be stored.
Task-number: PYSIDE-2288
Pick-to: 6.5 5.15
Change-Id: I27d27c94ec43bcc4cb3b79e6e9ce6706c749a1e9
Reviewed-by: Christian Tismer <tismer@stackless.com>
(cherry picked from commit 075d8ad4660f05e6d2583ff1c05e9987ad624bfe)
---
.../ApiExtractor/clangparser/clangbuilder.cpp | 8 ++++++--
.../ApiExtractor/clangparser/clangutils.cpp | 11 ++++++++++
.../ApiExtractor/clangparser/clangutils.h | 1 +
.../shiboken2/ApiExtractor/parser/codemodel.cpp | 24 ++++++++++++++++++++++
sources/shiboken2/ApiExtractor/parser/codemodel.h | 8 ++++++++
5 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
index ed1e15d..1b5cc5c 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
@@ -294,7 +294,9 @@ FunctionModelItem BuilderPrivate::createFunction(const CXCursor &cursor,
name = fixTypeName(name);
FunctionModelItem result(new _FunctionModelItem(m_model, name));
setFileName(cursor, result.data());
- result->setType(createTypeInfoHelper(clang_getCursorResultType(cursor)));
+ const auto type = clang_getCursorResultType(cursor);
+ result->setType(createTypeInfoHelper(type));
+ result->setScopeResolution(hasScopeResolution(type));
result->setFunctionType(t);
result->setScope(m_scope);
result->setStatic(clang_Cursor_getStorageClass(cursor) == CX_SC_Static);
@@ -1031,7 +1033,9 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
if (d->m_currentArgument.isNull() && !d->m_currentFunction.isNull()) {
const QString name = getCursorSpelling(cursor);
d->m_currentArgument.reset(new _ArgumentModelItem(d->m_model, name));
- d->m_currentArgument->setType(d->createTypeInfo(cursor));
+ const auto type = clang_getCursorType(cursor);
+ d->m_currentArgument->setScopeResolution(hasScopeResolution(type));
+ d->m_currentArgument->setType(d->createTypeInfo(type));
d->m_currentFunction->addArgument(d->m_currentArgument);
QString defaultValueExpression = d->cursorValueExpression(this, cursor);
if (!defaultValueExpression.isEmpty()) {
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
index 295ede3..ec6d228 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
@@ -155,6 +155,17 @@ QString getTypeName(const CXType &type)
return result;
}
+// Quick check for "::Type"
+bool hasScopeResolution(const CXType &type)
+{
+ CXString typeSpelling = clang_getTypeSpelling(type);
+ const QString spelling = QString::fromUtf8(clang_getCString(typeSpelling));
+ const bool result = spelling.startsWith(QLatin1String("::"))
+ || spelling.contains(QLatin1String(" ::"));
+ clang_disposeString(typeSpelling);
+ return result;
+}
+
// Resolve elaborated types occurring with clang 16
QString getResolvedTypeName(const CXType &type)
{
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.h b/sources/shiboken2/ApiExtractor/clangparser/clangutils.h
index aacaf63..33f362c 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangutils.h
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangutils.h
@@ -52,6 +52,7 @@ QString getCursorKindName(CXCursorKind cursorKind);
QString getCursorSpelling(const CXCursor &cursor);
QString getCursorDisplayName(const CXCursor &cursor);
QString getTypeName(const CXType &type);
+bool hasScopeResolution(const CXType &type);
QString getResolvedTypeName(const CXType &type);
inline QString getCursorTypeName(const CXCursor &cursor)
{ return getTypeName(clang_getCursorType(cursor)); }
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
index dea0812..ba07a01 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
@@ -1121,11 +1121,23 @@ void _ArgumentModelItem::setDefaultValue(bool defaultValue)
m_defaultValue = defaultValue;
}
+bool _ArgumentModelItem::scopeResolution() const
+{
+ return m_scopeResolution;
+}
+
+void _ArgumentModelItem::setScopeResolution(bool v)
+{
+ m_scopeResolution = v;
+}
+
#ifndef QT_NO_DEBUG_STREAM
void _ArgumentModelItem::formatDebug(QDebug &d) const
{
_CodeModelItem::formatDebug(d);
d << ", type=" << m_type;
+ if (m_scopeResolution)
+ d << ", [m_scope resolution]";
if (m_defaultValue)
d << ", defaultValue=\"" << m_defaultValueExpression << '"';
}
@@ -1200,6 +1212,16 @@ void _FunctionModelItem::setVariadics(bool isVariadics)
m_isVariadics = isVariadics;
}
+bool _FunctionModelItem::scopeResolution() const
+{
+ return m_scopeResolution;
+}
+
+void _FunctionModelItem::setScopeResolution(bool v)
+{
+ m_scopeResolution = v;
+}
+
bool _FunctionModelItem::isNoExcept() const
{
return m_exceptionSpecification == ExceptionSpecification::NoExcept;
@@ -1343,6 +1365,8 @@ void _FunctionModelItem::formatDebug(QDebug &d) const
d << " [explicit]";
if (m_isInvokable)
d << " [invokable]";
+ if (m_scopeResolution)
+ d << " [scope resolution]";
formatModelItemList(d, ", arguments=", m_arguments);
if (m_isVariadics)
d << ",...";
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.h b/sources/shiboken2/ApiExtractor/parser/codemodel.h
index b990ad9..85f298c 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.h
@@ -499,6 +499,10 @@ public:
QString defaultValueExpression() const { return m_defaultValueExpression; }
void setDefaultValueExpression(const QString &expr) { m_defaultValueExpression = expr; }
+ // Argument type has scope resolution "::ArgumentType"
+ bool scopeResolution() const;
+ void setScopeResolution(bool v);
+
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const override;
#endif
@@ -507,6 +511,7 @@ private:
TypeInfo m_type;
QString m_defaultValueExpression;
bool m_defaultValue = false;
+ bool m_scopeResolution = false;
};
class _MemberModelItem: public _CodeModelItem
@@ -623,6 +628,8 @@ public:
bool isVariadics() const;
void setVariadics(bool isVariadics);
+ bool scopeResolution() const; // Return type has scope resolution "::ReturnType"
+ void setScopeResolution(bool v);
bool isSimilar(const FunctionModelItem &other) const;
@@ -652,6 +659,7 @@ private:
uint m_isExplicit: 1;
uint m_isVariadics: 1;
uint m_isInvokable : 1; // Qt
+ uint m_scopeResolution: 1;
};
uint m_flags;
};

View File

@ -0,0 +1,101 @@
From: Friedemann Kleint <Friedemann.Kleint@qt.io>
Date: Thu, 20 Apr 2023 11:16:15 +0200
Subject: shiboken2/clang: Remove typedef expansion
The functionality will be re-added by a subsequent change
expanding elaborated types.
Task-number: PYSIDE-2288
Pick-to: 6.5 5.15
Change-Id: I3245c6dccba7de0ed1ce0e7820e1edb4567ca3c2
Reviewed-by: Christian Tismer <tismer@stackless.com>
(cherry picked from commit 24742dca014109bd3c2a9775fc15ca306ab22c9c)
---
.../ApiExtractor/clangparser/clangbuilder.cpp | 39 ----------------------
1 file changed, 39 deletions(-)
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
index 1b4c81c..332f1da 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
@@ -140,7 +140,6 @@ static bool isSigned(CXTypeKind kind)
class BuilderPrivate {
public:
using CursorClassHash = QHash<CXCursor, ClassModelItem>;
- using CursorTypedefHash = QHash<CXCursor, TypeDefModelItem>;
using TypeInfoHash = QHash<CXType, TypeInfo>;
explicit BuilderPrivate(BaseVisitor *bv) : m_baseVisitor(bv), m_model(new CodeModel)
@@ -197,9 +196,6 @@ public:
QString cursorValueExpression(BaseVisitor *bv, const CXCursor &cursor) const;
void addBaseClass(const CXCursor &cursor);
- template <class Item>
- void qualifyTypeDef(const CXCursor &typeRefCursor, const QSharedPointer<Item> &item) const;
-
bool visitHeader(const char *cFileName) const;
void setFileName(const CXCursor &cursor, _CodeModelItem *item);
@@ -213,7 +209,6 @@ public:
// classes can be correctly parented in case of forward-declared inner classes
// (QMetaObject::Connection)
CursorClassHash m_cursorClassHash;
- CursorTypedefHash m_cursorTypedefHash;
mutable TypeInfoHash m_typeInfoHash; // Cache type information
mutable QHash<QString, TemplateTypeAliasModelItem> m_templateTypeAliases;
@@ -561,7 +556,6 @@ void BuilderPrivate::addTypeDef(const CXCursor &cursor, const CXType &cxType)
item->setType(createTypeInfo(cxType));
item->setScope(m_scope);
m_scopeStack.back()->addTypeDef(item);
- m_cursorTypedefHash.insert(cursor, item);
}
void BuilderPrivate::startTemplateTypeAlias(const CXCursor &cursor)
@@ -703,31 +697,6 @@ static inline CXCursor definitionFromTypeRef(const CXCursor &typeRefCursor)
return clang_getTypeDeclaration(clang_getCursorType(typeRefCursor));
}
-// Qualify function arguments or fields that are typedef'ed from another scope:
-// enum ConversionFlag {};
-// typedef QFlags<ConversionFlag> ConversionFlags;
-// class QTextCodec {
-// enum ConversionFlag {};
-// typedef QFlags<ConversionFlag> ConversionFlags;
-// struct ConverterState {
-// explicit ConverterState(ConversionFlags);
-// ^^ qualify to QTextCodec::ConversionFlags
-// ConversionFlags m_flags;
-// ^^ ditto
-
-template <class Item> // ArgumentModelItem, VariableModelItem
-void BuilderPrivate::qualifyTypeDef(const CXCursor &typeRefCursor, const QSharedPointer<Item> &item) const
-{
- TypeInfo type = item->type();
- if (type.qualifiedName().size() == 1) { // item's type is unqualified.
- const auto it = m_cursorTypedefHash.constFind(definitionFromTypeRef(typeRefCursor));
- if (it != m_cursorTypedefHash.constEnd() && !it.value()->scope().isEmpty()) {
- type.setQualifiedName(it.value()->scope() + type.qualifiedName());
- item->setType(type);
- }
- }
-}
-
void BuilderPrivate::setFileName(const CXCursor &cursor, _CodeModelItem *item)
{
const SourceRange range = getCursorRange(cursor);
@@ -1120,14 +1089,6 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
}
break;
case CXCursor_TypeRef:
- if (!d->m_currentFunction.isNull()) {
- if (d->m_currentArgument.isNull())
- d->qualifyTypeDef(cursor, d->m_currentFunction); // return type
- else
- d->qualifyTypeDef(cursor, d->m_currentArgument);
- } else if (!d->m_currentField.isNull()) {
- d->qualifyTypeDef(cursor, d->m_currentField);
- }
break;
case CXCursor_CXXFinalAttr:
if (!d->m_currentFunction.isNull())

View File

@ -0,0 +1,96 @@
From: Friedemann Kleint <Friedemann.Kleint@qt.io>
Date: Thu, 27 Apr 2023 13:00:37 +0200
Subject: shiboken2/clang: Suppress class scope look up for parameters with
scope resolution
Add a flag to AbstractMetaBuilderPrivate::findTypeEntriesHelper()
to suppress the class scope look in case scope resolution.
Task-number: PYSIDE-2288
Pick-to: 6.5 5.15
Change-Id: I04a4810d03845fb48393c5efed3641220bd12d87
Reviewed-by: Christian Tismer <tismer@stackless.com>
---
sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp | 16 ++++++++++++----
sources/shiboken2/ApiExtractor/abstractmetabuilder.h | 3 ++-
sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h | 1 +
3 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 2f34e16..4bf4ab4 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -1845,7 +1845,10 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
return nullptr;
}
- AbstractMetaType *type = translateType(returnType, currentClass, {}, &errorMessage);
+ TranslateTypeFlags flags;
+ if (functionItem->scopeResolution())
+ flags.setFlag(AbstractMetaBuilder::NoClassScopeLookup);
+ AbstractMetaType *type = translateType(returnType, currentClass, flags, &errorMessage);
if (!type) {
const QString reason = msgUnmatchedReturnType(functionItem, errorMessage);
qCWarning(lcShiboken, "%s",
@@ -1880,7 +1883,10 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
return nullptr;
}
- AbstractMetaType *metaType = translateType(arg->type(), currentClass, {}, &errorMessage);
+ TranslateTypeFlags flags;
+ if (arg->scopeResolution())
+ flags.setFlag(AbstractMetaBuilder::NoClassScopeLookup);
+ AbstractMetaType *metaType = translateType(arg->type(), currentClass, flags, &errorMessage);
if (!metaType) {
// If an invalid argument has a default value, simply remove it
// unless the function is virtual (since the override in the
@@ -2073,11 +2079,13 @@ static const TypeEntry* findTypeEntryUsingContext(const AbstractMetaClass* metaC
// Helper for translateTypeStatic()
TypeEntries AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualifiedName,
const QString &name,
+ TranslateTypeFlags flags,
AbstractMetaClass *currentClass,
AbstractMetaBuilderPrivate *d)
{
// 5.1 - Try first using the current scope
- if (currentClass) {
+ if (currentClass != nullptr
+ && !flags.testFlag(AbstractMetaBuilder::NoClassScopeLookup)) {
if (auto type = findTypeEntryUsingContext(currentClass, qualifiedName))
return {type};
@@ -2278,7 +2286,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
typeInfo.clearInstantiations();
}
- TypeEntries types = findTypeEntries(qualifiedName, name, currentClass, d);
+ TypeEntries types = findTypeEntries(qualifiedName, name, flags, currentClass, d);
if (!flags.testFlag(AbstractMetaBuilder::TemplateArgument)) {
// Avoid clashes between QByteArray and enum value QMetaType::QByteArray
// unless we are looking for template arguments.
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
index 8916eaf..f333ad5 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
@@ -94,7 +94,8 @@ public:
enum TranslateTypeFlag {
DontResolveType = 0x1,
- TemplateArgument = 0x2
+ TemplateArgument = 0x2,
+ NoClassScopeLookup = 0x4
};
Q_DECLARE_FLAGS(TranslateTypeFlags, TranslateTypeFlag);
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
index 8468950..8ddd369 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
@@ -154,6 +154,7 @@ public:
TranslateTypeFlags flags = {},
QString *errorMessageIn = nullptr);
static TypeEntries findTypeEntries(const QString &qualifiedName, const QString &name,
+ TranslateTypeFlags flags = {},
AbstractMetaClass *currentClass = nullptr,
AbstractMetaBuilderPrivate *d = nullptr);

View File

@ -0,0 +1,62 @@
From: Friedemann Kleint <Friedemann.Kleint@qt.io>
Date: Thu, 27 Apr 2023 12:18:39 +0200
Subject: shiboken2/clang: Write scope resolution for all parameters of native
wrappers
Make sure types are correct for cases like:
- QtDBusHelper::QDBusReply::QDBusReply(::QDBusReply<void>)
- Qt3DInput*Event constructors taking the equivalent QtGui classes
(Qt3DInput::QMouseEvent(::QMouseEvent *);
[ChangeLog][shiboken6] Support for parameters/function return
types with scope resolution has been improved.
Fixes: PYSIDE-2288
Pick-to: 6.5 5.15
Change-Id: Id29758fceb88188f4cd834fbd5a7cc0ab511fb1a
Reviewed-by: Christian Tismer <tismer@stackless.com>
(cherry picked from commit dd863857436bbeeba4c0a1077f5ad16653296277)
---
sources/shiboken2/generator/generator.cpp | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/sources/shiboken2/generator/generator.cpp b/sources/shiboken2/generator/generator.cpp
index 6028282..6147b8a 100644
--- a/sources/shiboken2/generator/generator.cpp
+++ b/sources/shiboken2/generator/generator.cpp
@@ -899,21 +899,23 @@ QString Generator::translateType(const AbstractMetaType *cType,
if (index >= (s.size() - (constLen + 1))) // (VarType const) or (VarType const[*|&])
s = s.remove(index, constLen);
}
- } else if (options & Generator::ExcludeConst || options & Generator::ExcludeReference) {
+ } else {
AbstractMetaType *copyType = cType->copy();
+ if (options & Generator::ExcludeConst || options & Generator::ExcludeReference) {
+ if (options & Generator::ExcludeConst)
+ copyType->setConstant(false);
- if (options & Generator::ExcludeConst)
- copyType->setConstant(false);
-
- if (options & Generator::ExcludeReference)
- copyType->setReferenceType(NoReference);
-
+ if (options & Generator::ExcludeReference)
+ copyType->setReferenceType(NoReference);
+ }
s = copyType->cppSignature();
- if (!copyType->typeEntry()->isVoid() && !copyType->typeEntry()->isCppPrimitive())
- s.prepend(QLatin1String("::"));
+ const auto te = copyType->typeEntry();
+ if (!te->isVoid() && !te->isCppPrimitive()) { // Add scope resolution
+ const auto pos = s.indexOf(te->qualifiedCppName()); // Skip const/volatile
+ Q_ASSERT(pos >= 0);
+ s.insert(pos, QLatin1String("::"));
+ }
delete copyType;
- } else {
- s = cType->cppSignature();
}
}

View File

@ -1,5 +1,6 @@
{
python,
pythonAtLeast,
lib,
stdenv,
pyside2,
@ -7,28 +8,47 @@
qt5,
libxcrypt,
llvmPackages_15,
pythonAtLeast,
}:
stdenv.mkDerivation {
pname = "shiboken2";
inherit (pyside2) version src;
inherit (pyside2) version src patches;
patches = [ ./nix_compile_cflags.patch ];
postPatch = ''
cd sources/shiboken2
'';
postPatch =
(lib.optionalString (pythonAtLeast "3.12") ''
substituteInPlace \
ez_setup.py \
build_scripts/main.py \
build_scripts/options.py \
build_scripts/utils.py \
build_scripts/wheel_override.py \
build_scripts/wheel_utils.py \
sources/shiboken2/CMakeLists.txt \
sources/shiboken2/data/shiboken_helpers.cmake \
--replace-fail "from distutils" "import setuptools; from distutils"
substituteInPlace \
build_scripts/config.py \
build_scripts/main.py \
build_scripts/options.py \
build_scripts/setup_runner.py \
build_scripts/utils.py \
--replace-fail "import distutils" "import setuptools; import distutils"
'')
+ ''
cd sources/shiboken2
'';
CLANG_INSTALL_DIR = llvmPackages_15.libclang.out;
nativeBuildInputs = [ cmake ];
nativeBuildInputs = [
cmake
(python.withPackages (ps: with ps; [ setuptools ]))
];
buildInputs =
[
llvmPackages_15.libclang
python
python.pkgs.setuptools
qt5.qtbase
qt5.qtxmlpatterns
@ -59,6 +79,5 @@ stdenv.mkDerivation {
];
homepage = "https://wiki.qt.io/Qt_for_Python";
maintainers = with maintainers; [ gebner ];
broken = pythonAtLeast "3.12";
};
}

View File

@ -1,30 +0,0 @@
--- pyside-setup-everywhere-src-5.12.6/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp~ 2020-07-08 14:37:13.022476435 -0700
+++ pyside-setup-everywhere-src-5.12.6/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp 2020-07-08 14:37:18.271484269 -0700
@@ -330,17 +330,15 @@
}
#endif // NEED_CLANG_BUILTIN_INCLUDES
- // Append the c++ include paths since Clang is unable to find <list> etc
- // on RHEL 7 with g++ 6.3 or CentOS 7.2.
- // A fix for this has been added to Clang 5.0, so, the code can be removed
- // once Clang 5.0 is the minimum version.
- if (needsGppInternalHeaders()) {
- const HeaderPaths gppPaths = gppInternalIncludePaths(compilerFromCMake(QStringLiteral("g++")));
- for (const HeaderPath &h : gppPaths) {
- if (h.path.contains("c++")
- || h.path.contains("sysroot")) { // centOS
- headerPaths.append(h);
- }
+ const HeaderPaths gppPaths = gppInternalIncludePaths(QStringLiteral("g++"));
+ for (const HeaderPath &h : gppPaths) {
+ // PySide2 requires that Qt headers are not -isystem
+ // https://bugreports.qt.io/browse/PYSIDE-787
+ if (!h.path.contains("-qt")) {
+ // add using -isystem
+ headerPaths.append(h);
+ } else {
+ headerPaths.append({h.path, HeaderType::Standard});
}
}
#else

View File

@ -6,7 +6,9 @@
python,
isPyPy,
pythonAtLeast,
pythonOlder,
sip-module ? "sip",
setuptools,
}:
buildPythonPackage rec {
@ -14,8 +16,7 @@ buildPythonPackage rec {
version = "4.19.25";
format = "other";
# relies on distutils
disabled = isPyPy || pythonAtLeast "3.12";
disabled = isPyPy;
src = fetchurl {
url = "https://www.riverbankcomputing.com/static/Downloads/sip/${version}/sip-${version}.tar.gz";
@ -30,6 +31,12 @@ buildPythonPackage rec {
})
];
postPatch = lib.optionalString (pythonAtLeast "3.12") ''
substituteInPlace configure.py --replace-fail "from distutils" "from setuptools._distutils"
'';
propagatedBuildInputs = lib.optional (pythonAtLeast "3.12") setuptools;
configurePhase = ''
${python.executable} ./configure.py \
--sip-module ${sip-module} \
@ -40,7 +47,13 @@ buildPythonPackage rec {
enableParallelBuilding = true;
pythonImportsCheck = [
sip-module
# https://www.riverbankcomputing.com/pipermail/pyqt/2023-January/045094.html
# the import check for "sip" will fail, as it segfaults as the interperter is shutting down.
# This is an upstream bug with sip4 on python3.12, and happens in the ubuntu packages version as well.
# As the pacakge works fine until exit, just remove the import check for now.
# See discussion at https://github.com/NixOS/nixpkgs/pull/327976#discussion_r1706488319
(lib.optional (pythonOlder "3.12") sip-module)
"sipconfig"
];