aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Fält <simo.falt@qt.io>2023-05-25 11:19:39 +0300
committerSimo Fält <simo.falt@qt.io>2023-05-25 11:19:39 +0300
commit40fdea15e6545292212ea6c4acc78c3b2975cbd8 (patch)
treea2209393036458904f52cc418c708a20abcc1fac
parentd8f02ce77a4143aa4e7e6c4f7892e6a943c46b3c (diff)
parent63d49d3651257452b9be3982cac573971995e230 (diff)
Merge tag 'v5.15.6-lts' into tqtc/lts-5.15-opensourcev5.15.6-lts-lgpl
Qt For Python Release 5.15.6 Change-Id: I7a6874dfca79fbc46f5a6101e713b0c1dde9a640
-rw-r--r--build_history/blacklist.txt3
-rw-r--r--coin/dependencies.yaml2
-rw-r--r--dist/changes-5.15.634
-rw-r--r--sources/pyside2/PySide2/QtNetwork/typesystem_network.xml2
-rw-r--r--sources/pyside2/PySide2/glue/qtcore.cpp108
-rw-r--r--sources/pyside2/PySide2/support/generate_pyi.py17
-rw-r--r--sources/pyside2/PySide2/templates/core_common.xml27
-rw-r--r--sources/pyside2/libpyside/feature_select.cpp20
-rw-r--r--sources/pyside2/libpyside/pyside.cpp16
-rw-r--r--sources/pyside2/libpyside/pyside.h5
-rw-r--r--sources/pyside2/pyside_version.py2
-rw-r--r--sources/pyside2/tests/QtCore/CMakeLists.txt1
-rw-r--r--sources/pyside2/tests/QtCore/feature_with_uic/__init__.py29
-rw-r--r--sources/pyside2/tests/QtCore/feature_with_uic/window.py81
-rw-r--r--sources/pyside2/tests/QtCore/feature_with_uic/window.ui62
-rw-r--r--sources/pyside2/tests/QtCore/feature_with_uic_test.py76
-rw-r--r--sources/pyside2/tests/QtCore/qobject_parent_test.py30
-rw-r--r--sources/pyside2/tests/QtCore/qsettings_test.py16
-rw-r--r--sources/pyside2/tests/QtCore/translation_test.py13
-rw-r--r--sources/pyside2/tests/pysidetest/embedding_test.py7
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp2
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.cpp7
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.h7
-rw-r--r--sources/shiboken2/libshiboken/bindingmanager.cpp3
-rw-r--r--sources/shiboken2/libshiboken/embed/signature_bootstrap.py87
-rw-r--r--sources/shiboken2/libshiboken/sbkenum.cpp1
-rw-r--r--sources/shiboken2/libshiboken/signature/signature_globals.cpp2
-rw-r--r--sources/shiboken2/shiboken_version.py2
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py2
-rw-r--r--tools/create_changelog.py13
30 files changed, 592 insertions, 85 deletions
diff --git a/build_history/blacklist.txt b/build_history/blacklist.txt
index 2a2a5d4c4..827191a27 100644
--- a/build_history/blacklist.txt
+++ b/build_history/blacklist.txt
@@ -93,3 +93,6 @@
# Open GL functions failures on macOS (2/2020)
[registry::existence_test]
darwin
+# Incomplehensible effect with feature switching on 3.6, qApp.process_events()
+[QtCore::feature_with_uic_test]
+ py3.6
diff --git a/coin/dependencies.yaml b/coin/dependencies.yaml
index af5c36172..8c4ec7b68 100644
--- a/coin/dependencies.yaml
+++ b/coin/dependencies.yaml
@@ -1,6 +1,6 @@
product_dependency:
../../qt/tqtc-qt5.git:
- ref: "743ae9f98d7cc67c4956886209f39fcd5a28466f"
+ ref: "59ff9ceecedadc98c798305ee038b750876092da"
dependency_source: supermodule
dependencies: [
"../../qt/qt3d",
diff --git a/dist/changes-5.15.6 b/dist/changes-5.15.6
new file mode 100644
index 000000000..091adf2cf
--- /dev/null
+++ b/dist/changes-5.15.6
@@ -0,0 +1,34 @@
+Qt for Python 5.15.6 is a bug-fix release.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+https://doc.qt.io/qtforpython/
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* PySide2 *
+****************************************************************************
+
+ * [PYSIDE-131] The `tr` function now works also for
+ PySide derived Python class instances with the right context.
+ * [PYSIDE-1619][PYSIDE-1609] Fixed several crashes on QObject.findChild
+ and QSettings.value
+ * [PYSIDE-1639][PYSIDE-1640] Fixed locks on QInputDialog and QAbstractSocket.
+
+****************************************************************************
+* Shiboken2 *
+****************************************************************************
+
+ * [PYSIDE-1621] Embedding of supporting Python files
+ is now completely virtual. No FS files are involved any longer.
+ * [PYSIDE-1626] Coexistence of different feature
+ selections works now, especially for UIC files and inheritance.
+
diff --git a/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml b/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml
index dc60a509d..d91f07801 100644
--- a/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml
+++ b/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml
@@ -80,6 +80,8 @@
<modify-function signature="disconnectFromHost()" allow-thread="yes"/>
<modify-function signature="waitForConnected(int)" allow-thread="yes"/>
<modify-function signature="waitForDisconnected(int)" allow-thread="yes"/>
+ <modify-function signature="waitForBytesWritten(int)" allow-thread="yes"/>
+ <modify-function signature="waitForReadyRead(int)" allow-thread="yes"/>
</object-type>
<value-type name="QDnsDomainNameRecord"/>
diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp
index 306a2239c..78de3d5d5 100644
--- a/sources/pyside2/PySide2/glue/qtcore.cpp
+++ b/sources/pyside2/PySide2/glue/qtcore.cpp
@@ -76,7 +76,7 @@ if (kwds || numArgs > 1) {
PyTypeObject *typeObj = reinterpret_cast<PyTypeObject*>(%PYARG_3);
-if (typeObj) {
+if (typeObj && !Shiboken::ObjectType::checkType(typeObj)) {
if (typeObj == &PyList_Type) {
QByteArray out_ba = out.toByteArray();
if (!out_ba.isEmpty()) {
@@ -122,8 +122,14 @@ if (typeObj) {
Py_INCREF(Py_False);
%PYARG_0 = Py_False;
}
+ } else {
+ // TODO: PyDict_Type and PyTuple_Type
+ PyErr_SetString(PyExc_TypeError,
+ "Invalid type parameter.\n"
+ "\tUse 'list', 'bytes', 'str', 'int', 'float', 'bool', "
+ "or a Qt-derived type");
+ return nullptr;
}
- // TODO: PyDict_Type and PyTuple_Type
}
else {
if (!out.isValid()) {
@@ -793,12 +799,35 @@ qRegisterMetaType<QVector<int> >("QVector<int>");
// @snippet qobject-metaobject
// @snippet qobject-findchild-1
+static bool _findChildTypeMatch(const QObject *child, PyTypeObject *desiredType)
+{
+ auto *pyChildType = PySide::getTypeForQObject(child);
+ return pyChildType != nullptr && PyType_IsSubtype(pyChildType, desiredType);
+}
+
+static inline bool _findChildrenComparator(const QObject *child,
+ const QRegularExpression &name)
+{
+ return name.match(child->objectName()).hasMatch();
+}
+
+static inline bool _findChildrenComparator(const QObject *child,
+ const QString &name)
+{
+ return name.isNull() || name == child->objectName();
+}
+
+static inline bool _findChildrenComparator(const QObject *child,
+ const QRegExp &name)
+{
+ return name.indexIn(child->objectName()) != -1;
+}
+
static QObject *_findChildHelper(const QObject *parent, const QString &name, PyTypeObject *desiredType)
{
for (auto *child : parent->children()) {
- Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject *](child));
- if (PyType_IsSubtype(Py_TYPE(pyChild), desiredType)
- && (name.isNull() || name == child->objectName())) {
+ if (_findChildrenComparator(child, name)
+ && _findChildTypeMatch(child, desiredType)) {
return child;
}
}
@@ -811,28 +840,15 @@ static QObject *_findChildHelper(const QObject *parent, const QString &name, PyT
return nullptr;
}
-static inline bool _findChildrenComparator(const QObject *&child, const QRegExp &name)
-{
- return name.indexIn(child->objectName()) != -1;
-}
-
-static inline bool _findChildrenComparator(const QObject *&child, const QRegularExpression &name)
-{
- return name.match(child->objectName()).hasMatch();
-}
-
-static inline bool _findChildrenComparator(const QObject *&child, const QString &name)
-{
- return name.isNull() || name == child->objectName();
-}
-
-template<typename T>
+template<typename T> // QString/QRegularExpression/QRegExp
static void _findChildrenHelper(const QObject *parent, const T& name, PyTypeObject *desiredType, PyObject *result)
{
for (const auto *child : parent->children()) {
- Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject *](child));
- if (PyType_IsSubtype(Py_TYPE(pyChild), desiredType) && _findChildrenComparator(child, name))
+ if (_findChildrenComparator(child, name)
+ && _findChildTypeMatch(child, desiredType)) {
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject *](child));
PyList_Append(result, pyChild);
+ }
_findChildrenHelper(child, name, desiredType, result);
}
}
@@ -848,19 +864,41 @@ QObject *child = _findChildHelper(%CPPSELF, %2, reinterpret_cast<PyTypeObject *>
_findChildrenHelper(%CPPSELF, %2, reinterpret_cast<PyTypeObject *>(%PYARG_1), %PYARG_0);
// @snippet qobject-findchildren
+//////////////////////////////////////////////////////////////////////////////
+// PYSIDE-131: Use the class name as context where the calling function is
+// living. Derived Python classes have the wrong context.
+//
+// The original patch uses Python introspection to look up the current
+// function (from the frame stack) in the class __dict__ along the mro.
+//
+// The problem is that looking into the frame stack works for Python
+// functions, only. For including builtin function callers, the following
+// approach turned out to be much simpler:
+//
+// Walk the __mro__
+// - translate the string
+// - if the translated string is changed:
+// - return the translation.
+
// @snippet qobject-tr
-QString result;
-if (QCoreApplication::instance()) {
- PyObject *klass = PyObject_GetAttr(%PYSELF, Shiboken::PyMagicName::class_());
- PyObject *cname = PyObject_GetAttr(klass, Shiboken::PyMagicName::name());
- result = QString(QCoreApplication::instance()->translate(Shiboken::String::toCString(cname),
- /* %1, %2, QCoreApplication::CodecForTr, %3)); */
- %1, %2, %3));
-
- Py_DECREF(klass);
- Py_DECREF(cname);
-} else {
- result = QString(QString::fromLatin1(%1));
+PyTypeObject *type = Py_TYPE(%PYSELF);
+PyObject *mro = type->tp_mro;
+auto len = PyTuple_GET_SIZE(mro);
+QString result = QString::fromUtf8(%1);
+QString oldResult = result;
+static auto *sbkObjectType = reinterpret_cast<PyTypeObject *>(SbkObject_TypeF());
+for (Py_ssize_t idx = 0; idx < len - 1; ++idx) {
+ // Skip the last class which is `object`.
+ auto *type = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx));
+ if (type == sbkObjectType)
+ continue;
+ const char *context = type->tp_name;
+ const char *dotpos = strrchr(context, '.');
+ if (dotpos != nullptr)
+ context = dotpos + 1;
+ result = QCoreApplication::translate(context, %1, %2, %3);
+ if (result != oldResult)
+ break;
}
%PYARG_0 = %CONVERTTOPYTHON[QString](result);
// @snippet qobject-tr
diff --git a/sources/pyside2/PySide2/support/generate_pyi.py b/sources/pyside2/PySide2/support/generate_pyi.py
index 6a69a798a..9eb84de7a 100644
--- a/sources/pyside2/PySide2/support/generate_pyi.py
+++ b/sources/pyside2/PySide2/support/generate_pyi.py
@@ -1,4 +1,6 @@
# This Python file uses the following encoding: utf-8
+from __future__ import print_function, absolute_import, unicode_literals
+LICENSE_TEXT = """
#############################################################################
##
## Copyright (C) 2020 The Qt Company Ltd.
@@ -37,8 +39,7 @@
## $QT_END_LICENSE$
##
#############################################################################
-
-from __future__ import print_function, absolute_import, unicode_literals
+"""
"""
generate_pyi.py
@@ -201,14 +202,6 @@ class Formatter(Writer):
yield
-def get_license_text():
- with io.open(sourcepath) as f:
- lines = f.readlines()
- license_line = next((lno for lno, line in enumerate(lines)
- if "$QT_END_LICENSE$" in line))
- return "".join(lines[:license_line + 3])
-
-
def find_imports(text):
return [imp for imp in PySide2.__all__ if imp + "." in text]
@@ -228,7 +221,7 @@ def generate_pyi(import_name, outpath, options):
outfile = io.StringIO()
fmt = Formatter(outfile)
- fmt.print(get_license_text()) # which has encoding, already
+ fmt.print(LICENSE_TEXT.strip())
need_imports = not USE_PEP563
if USE_PEP563:
fmt.print("from __future__ import annotations")
@@ -307,6 +300,8 @@ def generate_all_pyi(outpath, options):
if __name__ == "__main__":
+ # PYSIDE-1621: Enforce embedding to ensure that it always works.
+ sys.pyside_uses_embedding = True
parser = argparse.ArgumentParser(
description="This script generates the .pyi file for all PySide modules.")
parser.add_argument("modules", nargs="+",
diff --git a/sources/pyside2/PySide2/templates/core_common.xml b/sources/pyside2/PySide2/templates/core_common.xml
index 6d02428ad..b5d1f02e2 100644
--- a/sources/pyside2/PySide2/templates/core_common.xml
+++ b/sources/pyside2/PySide2/templates/core_common.xml
@@ -114,35 +114,52 @@
<insert-template name="tuple_retval_ok"/>
</template>
+ <!-- QInputDialog: these should allow threads -->
<template name="fix_arg,arg,arg,arg,arg,arg,arg,bool*,arg">
bool ok_;
- %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, %7, &amp;ok_, %9);
+ %RETURN_TYPE retval_;
+ Py_BEGIN_ALLOW_THREADS
+ retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, %7, &amp;ok_, %9);
+ Py_END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
<template name="fix_arg,arg,arg,arg,arg,arg,arg,bool*,arg,arg">
bool ok_;
- %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, %7, &amp;ok_, %9, %10);
+ %RETURN_TYPE retval_;
+ Py_BEGIN_ALLOW_THREADS
+ retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, %7, &amp;ok_, %9, %10);
+ Py_END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
<template name="fix_arg,arg,arg,arg,arg,arg,bool*,arg">
bool ok_;
- %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, &amp;ok_, %8);
+ %RETURN_TYPE retval_;
+ Py_BEGIN_ALLOW_THREADS
+ retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, &amp;ok_, %8);
+ Py_END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
<template name="fix_arg,arg,arg,arg,arg,bool*,arg">
bool ok_;
- %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, &amp;ok_, %7);
+ %RETURN_TYPE retval_;
+ Py_BEGIN_ALLOW_THREADS
+ retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, &amp;ok_, %7);
+ Py_END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
<template name="fix_arg,arg,arg,arg,bool*,arg,arg">
bool ok_;
- %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, &amp;ok_, %6, %7);
+ %RETURN_TYPE retval_;
+ Py_BEGIN_ALLOW_THREADS
+ retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, &amp;ok_, %6, %7);
+ Py_END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
+ <!-- End of QInputDialog templates -->
<template name="fix_char*">
char val_{};
diff --git a/sources/pyside2/libpyside/feature_select.cpp b/sources/pyside2/libpyside/feature_select.cpp
index 6a21d168d..7604f69aa 100644
--- a/sources/pyside2/libpyside/feature_select.cpp
+++ b/sources/pyside2/libpyside/feature_select.cpp
@@ -255,6 +255,7 @@ static bool replaceClassDict(PyTypeObject *type)
// Replace `__dict__` which usually has refcount 1 (but see cyclic_test.py)
Py_DECREF(type->tp_dict);
type->tp_dict = new_dict;
+ setCurrentSelectId(type, select_id.object());
return true;
}
@@ -275,6 +276,7 @@ static bool addNewDict(PyTypeObject *type, PyObject *select_id)
setNextDict(dict, new_dict);
setNextDict(new_dict, next_dict);
type->tp_dict = new_dict;
+ setCurrentSelectId(type, select_id);
return true;
}
@@ -297,6 +299,7 @@ static bool moveToFeatureSet(PyTypeObject *type, PyObject *select_id)
}
} while (dict != initial_dict);
type->tp_dict = initial_dict;
+ setCurrentSelectId(type, getSelectId(initial_dict));
return false;
}
@@ -418,6 +421,13 @@ void Select(PyObject *obj)
type->tp_dict = SelectFeatureSet(type);
}
+PyObject *Select(PyTypeObject *type)
+{
+ if (featurePointer != nullptr)
+ type->tp_dict = SelectFeatureSet(type);
+ return type->tp_dict;
+}
+
static bool feature_01_addLowerNames(PyTypeObject *type, PyObject *prev_dict, int id);
static bool feature_02_true_property(PyTypeObject *type, PyObject *prev_dict, int id);
static bool feature_04_addDummyNames(PyTypeObject *type, PyObject *prev_dict, int id);
@@ -446,11 +456,11 @@ void finalize()
}
static bool patch_property_impl();
+static bool is_initialized = false;
void init()
{
// This function can be called multiple times.
- static bool is_initialized = false;
if (!is_initialized) {
fast_id_array = &_fast_id_array[1];
for (int idx = -1; idx < 256; ++idx)
@@ -466,6 +476,14 @@ void init()
cached_globals = nullptr;
}
+void Enable(bool enable)
+{
+ if (!is_initialized)
+ return;
+ featurePointer = enable ? featureProcArray : nullptr;
+ initSelectableFeature(enable ? SelectFeatureSet : nullptr);
+}
+
//////////////////////////////////////////////////////////////////////////////
//
// PYSIDE-1019: Support switchable extensions
diff --git a/sources/pyside2/libpyside/pyside.cpp b/sources/pyside2/libpyside/pyside.cpp
index 5d0859adc..7b01c5b8f 100644
--- a/sources/pyside2/libpyside/pyside.cpp
+++ b/sources/pyside2/libpyside/pyside.cpp
@@ -412,7 +412,7 @@ static const char invalidatePropertyName[] = "_PySideInvalidatePtr";
// PYSIDE-1214, when creating new wrappers for classes inheriting QObject but
// not exposed to Python, try to find the best-matching (most-derived) Qt
// class by walking up the meta objects.
-static const char *typeName(QObject *cppSelf)
+static const char *typeName(const QObject *cppSelf)
{
const char *typeName = typeid(*cppSelf).name();
if (!Shiboken::Conversions::getConverter(typeName)) {
@@ -427,6 +427,20 @@ static const char *typeName(QObject *cppSelf)
return typeName;
}
+PyTypeObject *getTypeForQObject(const QObject *cppSelf)
+{
+ // First check if there are any instances of Python implementations
+ // inheriting a PySide class.
+ auto *existing = Shiboken::BindingManager::instance().retrieveWrapper(cppSelf);
+ if (existing != nullptr)
+ return reinterpret_cast<PyObject *>(existing)->ob_type;
+ // Find the best match (will return a PySide type)
+ auto *sbkObjectType = Shiboken::ObjectType::typeForTypeName(typeName(cppSelf));
+ if (sbkObjectType != nullptr)
+ return reinterpret_cast<PyTypeObject *>(sbkObjectType);
+ return nullptr;
+}
+
PyObject *getWrapperForQObject(QObject *cppSelf, SbkObjectType *sbk_type)
{
PyObject *pyOut = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper(cppSelf));
diff --git a/sources/pyside2/libpyside/pyside.h b/sources/pyside2/libpyside/pyside.h
index a465fec47..c72f37ae7 100644
--- a/sources/pyside2/libpyside/pyside.h
+++ b/sources/pyside2/libpyside/pyside.h
@@ -140,6 +140,11 @@ PYSIDE_API void setNextQObjectMemoryAddr(void *addr);
PYSIDE_API PyObject *getWrapperForQObject(QObject *cppSelf, SbkObjectType *sbk_type);
+/// Return the best-matching type for a QObject (Helper for QObject.findType())
+/// \param cppSelf QObject instance
+/// \return type object
+PYSIDE_API PyTypeObject *getTypeForQObject(const QObject *cppSelf);
+
#ifdef PYSIDE_QML_SUPPORT
// Used by QtQuick module to notify QtQml that custom QtQuick items can be registered.
typedef bool (*QuickRegisterItemFunction)(PyObject *pyObj, const char *uri, int versionMajor,
diff --git a/sources/pyside2/pyside_version.py b/sources/pyside2/pyside_version.py
index 876a0e401..3ee73451b 100644
--- a/sources/pyside2/pyside_version.py
+++ b/sources/pyside2/pyside_version.py
@@ -39,7 +39,7 @@
major_version = "5"
minor_version = "15"
-patch_version = "5"
+patch_version = "6"
# For example: "a", "b", "rc"
# (which means "alpha", "beta", "release candidate").
diff --git a/sources/pyside2/tests/QtCore/CMakeLists.txt b/sources/pyside2/tests/QtCore/CMakeLists.txt
index 9d268e079..c7e50d640 100644
--- a/sources/pyside2/tests/QtCore/CMakeLists.txt
+++ b/sources/pyside2/tests/QtCore/CMakeLists.txt
@@ -37,6 +37,7 @@ PYSIDE_TEST(deletelater_test.py)
PYSIDE_TEST(destroysignal_test.py)
PYSIDE_TEST(duck_punching_test.py)
PYSIDE_TEST(emoji_string_test.py)
+PYSIDE_TEST(feature_with_uic_test.py)
PYSIDE_TEST(hash_test.py)
PYSIDE_TEST(inherits_test.py)
PYSIDE_TEST(max_signals.py)
diff --git a/sources/pyside2/tests/QtCore/feature_with_uic/__init__.py b/sources/pyside2/tests/QtCore/feature_with_uic/__init__.py
new file mode 100644
index 000000000..396f82fb1
--- /dev/null
+++ b/sources/pyside2/tests/QtCore/feature_with_uic/__init__.py
@@ -0,0 +1,29 @@
+#############################################################################
+##
+## Copyright (C) 2020 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+# this file intentionally left blank
diff --git a/sources/pyside2/tests/QtCore/feature_with_uic/window.py b/sources/pyside2/tests/QtCore/feature_with_uic/window.py
new file mode 100644
index 000000000..db0fbd033
--- /dev/null
+++ b/sources/pyside2/tests/QtCore/feature_with_uic/window.py
@@ -0,0 +1,81 @@
+# -*- coding: utf-8 -*-
+#############################################################################
+##
+## Copyright (C) 2021 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+################################################################################
+## Form generated from reading UI file 'window.ui'
+##
+## Created by: Qt User Interface Compiler version 5.15.2
+##
+## WARNING! All changes made in this file will be lost when recompiling UI file!
+################################################################################
+
+from PySide2.QtCore import *
+from PySide2.QtGui import *
+from PySide2.QtWidgets import *
+
+
+class Ui_MainWindow(object):
+ def setupUi(self, MainWindow):
+ if not MainWindow.objectName():
+ MainWindow.setObjectName(u"MainWindow")
+ MainWindow.resize(263, 196)
+ self.centralwidget = QWidget(MainWindow)
+ self.centralwidget.setObjectName(u"centralwidget")
+ self.horizontalLayout = QHBoxLayout(self.centralwidget)
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.verticalLayout = QVBoxLayout()
+ self.verticalLayout.setObjectName(u"verticalLayout")
+ self.pushButton = QPushButton(self.centralwidget)
+ self.pushButton.setObjectName(u"pushButton")
+
+ self.verticalLayout.addWidget(self.pushButton)
+
+
+ self.horizontalLayout.addLayout(self.verticalLayout)
+
+ MainWindow.setCentralWidget(self.centralwidget)
+ self.menubar = QMenuBar(MainWindow)
+ self.menubar.setObjectName(u"menubar")
+ self.menubar.setGeometry(QRect(0, 0, 263, 23))
+ MainWindow.setMenuBar(self.menubar)
+ self.statusbar = QStatusBar(MainWindow)
+ self.statusbar.setObjectName(u"statusbar")
+ MainWindow.setStatusBar(self.statusbar)
+
+ self.retranslateUi(MainWindow)
+ self.pushButton.clicked.connect(MainWindow.close)
+
+ QMetaObject.connectSlotsByName(MainWindow)
+ # setupUi
+
+ def retranslateUi(self, MainWindow):
+ MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
+ self.pushButton.setText(QCoreApplication.translate("MainWindow", u"PushButton", None))
+ # retranslateUi
+
diff --git a/sources/pyside2/tests/QtCore/feature_with_uic/window.ui b/sources/pyside2/tests/QtCore/feature_with_uic/window.ui
new file mode 100644
index 000000000..0b85824ea
--- /dev/null
+++ b/sources/pyside2/tests/QtCore/feature_with_uic/window.ui
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>263</width>
+ <height>196</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QPushButton" name="pushButton">
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>263</width>
+ <height>23</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>pushButton</sender>
+ <signal>clicked()</signal>
+ <receiver>MainWindow</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>131</x>
+ <y>97</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>131</x>
+ <y>97</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/sources/pyside2/tests/QtCore/feature_with_uic_test.py b/sources/pyside2/tests/QtCore/feature_with_uic_test.py
new file mode 100644
index 000000000..5b61a4afb
--- /dev/null
+++ b/sources/pyside2/tests/QtCore/feature_with_uic_test.py
@@ -0,0 +1,76 @@
+#############################################################################
+##
+## Copyright (C) 2021 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+"""
+feature_with_uic_test.py
+------------------------
+
+Check if feature switching works with a normal UIC file.
+This crashed due to callbacks into QApplication.
+
+PYSIDE-1626: Switch early in `BindingManager::getOverride`.
+"""
+
+import os
+import sys
+import unittest
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide2.QtCore import QLibraryInfo, qVersion
+from PySide2.QtWidgets import QApplication, QMainWindow
+
+if sys.version_info[0] >= 3:
+ from __feature__ import snake_case
+
+from feature_with_uic.window import Ui_MainWindow
+
+
+class MainWindow(QMainWindow, Ui_MainWindow):
+
+ def __init__(self):
+ super().__init__()
+ self.setupUi(self)
+
+
+class FeatureTest(UsesQApplication):
+
+ def testFeaturesWorkWithUIC(self):
+ window = MainWindow()
+ window.set_window_title(qVersion())
+ window.show()
+ while not window.window_handle().is_exposed():
+ QCoreApplication.process_events()
+
+
+if __name__ == '__main__' and sys.version_info[0] >= 3:
+ unittest.main()
diff --git a/sources/pyside2/tests/QtCore/qobject_parent_test.py b/sources/pyside2/tests/QtCore/qobject_parent_test.py
index 0a02fbc26..becc7c48e 100644
--- a/sources/pyside2/tests/QtCore/qobject_parent_test.py
+++ b/sources/pyside2/tests/QtCore/qobject_parent_test.py
@@ -39,6 +39,16 @@ init_test_paths(False)
from PySide2.QtCore import *
+class TestObject1(QTimer):
+ def __init(self, parent):
+ super().__init__(parent)
+
+
+class TestObject2(TestObject1):
+ def __init(self, parent):
+ super().__init__(parent)
+
+
class ParentRefCountCase(unittest.TestCase):
'''Test case for the refcount changes of setParent'''
@@ -158,6 +168,26 @@ class ParentCase(unittest.TestCase):
child = QObject(parent)
self.assertEqual(parent, child.parent())
+ def testFindChildByType(self):
+ parent = QObject()
+ expected = TestObject2(parent)
+ actual = parent.findChild(TestObject2)
+ self.assertEqual(actual, expected)
+ actual = parent.findChild(TestObject1)
+ self.assertEqual(actual, expected)
+ actual = parent.findChild(QTimer)
+ self.assertEqual(actual, expected)
+
+ def testFindChildrenByType(self):
+ parent = QObject()
+ expected = [TestObject2(parent)]
+ actual = parent.findChildren(TestObject2)
+ self.assertEqual(actual, expected)
+ actual = parent.findChildren(TestObject1)
+ self.assertEqual(actual, expected)
+ actual = parent.findChildren(QTimer)
+ self.assertEqual(actual, expected)
+
class TestParentOwnership(unittest.TestCase):
'''Test case for Parent/Child object ownership'''
diff --git a/sources/pyside2/tests/QtCore/qsettings_test.py b/sources/pyside2/tests/QtCore/qsettings_test.py
index a9f42a5d5..d7e203734 100644
--- a/sources/pyside2/tests/QtCore/qsettings_test.py
+++ b/sources/pyside2/tests/QtCore/qsettings_test.py
@@ -38,7 +38,7 @@ init_test_paths(False)
from helper.helper import adjust_filename
import py3kcompat as py3k
-from PySide2.QtCore import QDir, QSettings, QTemporaryDir
+from PySide2.QtCore import QDir, QSettings, QTemporaryDir, QByteArray
class TestQSettings(unittest.TestCase):
def testConversions(self):
@@ -57,6 +57,20 @@ class TestQSettings(unittest.TestCase):
r = settings.value('var2', type=list)
self.assertEqual(type(r), list)
+ # Test mixed conversions
+ if py3k.IS_PY3K:
+ ba = QByteArray("hello".encode("utf-8"))
+
+ r = settings.value("test", ba, type=QByteArray)
+ self.assertEqual(type(r), QByteArray)
+
+ r = settings.value("test", ba, type=str)
+ self.assertEqual(type(r), str)
+
+ # Test invalid conversions
+ with self.assertRaises(TypeError):
+ r = settings.value("test", ba, type=dict)
+
def testDefaultValueConversion(self):
temp_dir = QDir.tempPath()
diff --git a/sources/pyside2/tests/QtCore/translation_test.py b/sources/pyside2/tests/QtCore/translation_test.py
index 0f36067bd..b2e674aac 100644
--- a/sources/pyside2/tests/QtCore/translation_test.py
+++ b/sources/pyside2/tests/QtCore/translation_test.py
@@ -59,6 +59,19 @@ class TranslationTest(UsesQCoreApplication):
obj = QObject()
obj.setObjectName(obj.tr('Hello World!'))
+ self.assertEqual(obj.objectName(), 'Orbis, te saluto!')
+
+ def testLatinDerived(self):
+ # PYSIDE-131: Test that derived classes work, too.
+ translator = QTranslator()
+ translator.load(os.path.join(self.trdir, 'trans_latin.qm'))
+ self.app.installTranslator(translator)
+
+ class Derived(QObject):
+ pass
+
+ obj = Derived()
+ obj.setObjectName(obj.tr('Hello World!'))
self.assertEqual(obj.objectName(), py3k.unicode_('Orbis, te saluto!'))
def testRussian(self):
diff --git a/sources/pyside2/tests/pysidetest/embedding_test.py b/sources/pyside2/tests/pysidetest/embedding_test.py
index 1960838ff..570686927 100644
--- a/sources/pyside2/tests/pysidetest/embedding_test.py
+++ b/sources/pyside2/tests/pysidetest/embedding_test.py
@@ -65,16 +65,15 @@ class EmbeddingTest(unittest.TestCase):
# Unfortunately, I see no way how to shut things enough down
# to trigger a second initiatization. Therefore, only one test :-/
def test_pyside_embedding(self):
- import sys, os
+ import sys
self.assertFalse(hasattr(sys, "pyside_uses_embedding"))
sys.pyside_uses_embedding = "anything true"
import PySide2
# everything has to be imported
self.assertTrue("PySide2.support.signature" in sys.modules)
self.assertEqual(sys.pyside_uses_embedding, True)
- dn = os.path.dirname
- name = os.path.basename(dn(dn(dn(PySide2.support.signature.__file__))))
- self.assertTrue(name.startswith("embedded.") and name.endswith(".zip"))
+ # We no longer use a physical zip file.
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 9739dfef6..7743d50a2 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -2825,7 +2825,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov
if (isVarargs)
--numArgs;
typeChecks.prepend(QString::fromLatin1("numArgs %1 %2").arg(isVarargs ? QLatin1String(">=") : QLatin1String("==")).arg(numArgs));
- } else if (sequenceArgCount > 1) {
+ } else if (usePyArgs && sequenceArgCount > 0) {
typeChecks.prepend(QString::fromLatin1("numArgs >= %1").arg(startArg + sequenceArgCount));
} else if (refFunc->isOperatorOverload() && !refFunc->isCallOperator()) {
typeChecks.prepend(QString::fromLatin1("%1isReverse").arg(refFunc->isReverseOperator() ? QString() : QLatin1String("!")));
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp
index dca5631bc..113128f5a 100644
--- a/sources/shiboken2/libshiboken/basewrapper.cpp
+++ b/sources/shiboken2/libshiboken/basewrapper.cpp
@@ -677,6 +677,13 @@ void SbkObjectType_SetPropertyStrings(PyTypeObject *type, const char **strings)
PepType_SOTP(reinterpret_cast<SbkObjectType *>(type))->propertyStrings = strings;
}
+// PYSIDE-1626: Enforcing a context switch without further action.
+void SbkObjectType_UpdateFeature(PyTypeObject *type)
+{
+ if (SelectFeatureSet != nullptr)
+ type->tp_dict = SelectFeatureSet(type);
+}
+
//
//////////////////////////////////////////////////////////////////////////////
diff --git a/sources/shiboken2/libshiboken/basewrapper.h b/sources/shiboken2/libshiboken/basewrapper.h
index 2f0c22e9f..a79a93096 100644
--- a/sources/shiboken2/libshiboken/basewrapper.h
+++ b/sources/shiboken2/libshiboken/basewrapper.h
@@ -98,11 +98,14 @@ typedef void (*SubTypeInitHook)(SbkObjectType *, PyObject *, PyObject *);
typedef PyObject *(*SelectableFeatureHook)(PyTypeObject *);
LIBSHIBOKEN_API SelectableFeatureHook initSelectableFeature(SelectableFeatureHook func);
-// PYSIDE-1019: Get access to PySide reserved bits.
+/// PYSIDE-1019: Get access to PySide reserved bits.
LIBSHIBOKEN_API int SbkObjectType_GetReserved(PyTypeObject *type);
LIBSHIBOKEN_API void SbkObjectType_SetReserved(PyTypeObject *type, int value);
-// PYSIDE-1019: Get access to PySide property strings.
+/// PYSIDE-1626: Enforcing a context switch without further action.
+LIBSHIBOKEN_API void SbkObjectType_UpdateFeature(PyTypeObject *type);
+
+/// PYSIDE-1019: Get access to PySide property strings.
LIBSHIBOKEN_API const char **SbkObjectType_GetPropertyStrings(PyTypeObject *type);
LIBSHIBOKEN_API void SbkObjectType_SetPropertyStrings(PyTypeObject *type, const char **strings);
diff --git a/sources/shiboken2/libshiboken/bindingmanager.cpp b/sources/shiboken2/libshiboken/bindingmanager.cpp
index 065c02049..5d69e923f 100644
--- a/sources/shiboken2/libshiboken/bindingmanager.cpp
+++ b/sources/shiboken2/libshiboken/bindingmanager.cpp
@@ -292,6 +292,9 @@ PyObject *BindingManager::getOverride(const void *cptr,
if (!wrapper || reinterpret_cast<const PyObject *>(wrapper)->ob_refcnt == 0)
return nullptr;
+ // PYSIDE-1626: Touch the type to initiate switching early.
+ SbkObjectType_UpdateFeature(Py_TYPE(wrapper));
+
int flag = currentSelectId(Py_TYPE(wrapper));
int propFlag = isdigit(methodName[0]) ? methodName[0] - '0' : 0;
if ((flag & 0x02) != 0 && (propFlag & 3) != 0) {
diff --git a/sources/shiboken2/libshiboken/embed/signature_bootstrap.py b/sources/shiboken2/libshiboken/embed/signature_bootstrap.py
index dd8df2b63..902864267 100644
--- a/sources/shiboken2/libshiboken/embed/signature_bootstrap.py
+++ b/sources/shiboken2/libshiboken/embed/signature_bootstrap.py
@@ -77,10 +77,11 @@ def bootstrap():
recursion_trap += 1
@contextmanager
- def ensure_shibokensupport(support_path):
+ def ensure_shibokensupport(target, support_path):
# Make sure that we always have the shibokensupport containing package first.
# Also remove any prior loaded module of this name, just in case.
- sys.path.insert(0, support_path)
+ # PYSIDE-1621: support_path can also be a finder instance.
+ target.insert(0, support_path)
sbks = "shibokensupport"
if sbks in sys.modules:
@@ -100,7 +101,7 @@ def bootstrap():
print(" " + p)
sys.stdout.flush()
sys.exit(-1)
- sys.path.remove(support_path)
+ target.remove(support_path)
try:
import shiboken2 as root
@@ -119,8 +120,6 @@ def bootstrap():
# Here we decide if we work embedded or not.
embedding_var = "pyside_uses_embedding"
use_embedding = bool(getattr(sys, embedding_var, False))
- # We keep the zip file for inspection if the sys variable has been set.
- keep_zipfile = hasattr(sys, embedding_var)
loader_path = os.path.join(rp, look_for)
files_dir = os.path.abspath(os.path.join(loader_path, "..", "..", ".."))
assert files_dir.endswith("files.dir")
@@ -131,41 +130,54 @@ def bootstrap():
support_path = prepare_zipfile() if use_embedding else files_dir
setattr(sys, embedding_var, use_embedding)
+ if use_embedding:
+ target, support_path = prepare_zipfile()
+ else:
+ target, support_path = sys.path, files_dir
+
try:
- with ensure_shibokensupport(support_path):
+ with ensure_shibokensupport(target, support_path):
from shibokensupport.signature import loader
except Exception as e:
print('Exception:', e)
traceback.print_exc(file=sys.stdout)
- finally:
- if use_embedding and not keep_zipfile:
- # clear the temp zipfile
- try:
- os.remove(support_path)
- except OSError as e:
- print(e)
- print("Error deleting {support_path}, ignored".format(**locals()))
- return loader
+ return loader
+
# New functionality: Loading from a zip archive.
# There exists the zip importer, but as it is written, only real zip files are
# supported. Before I will start an own implementation, it is easiest to use
# a temporary zip file.
+# PYSIDE-1621: make zip file access totally virtual
def prepare_zipfile():
"""
Write the zip file to a real file and return its name.
It will be implicitly opened as such when we add the name to sys.path .
+
+ New approach (Python 3, only):
+
+ Use EmbeddableZipImporter and pass the zipfile structure directly.
+ The sys.path way does not work, instead we need to use sys.meta_path .
+ See https://docs.python.org/3/library/sys.html#sys.meta_path
"""
import base64
- import tempfile
- import os
+ import io
+ import sys
import zipfile
# 'zipstring_sequence' comes from signature.cpp
zipbytes = base64.b64decode(''.join(zipstring_sequence))
+ if sys.version_info[0] >= 3:
+ vzip = zipfile.ZipFile(io.BytesIO(zipbytes))
+ return sys.meta_path, EmbeddableZipImporter(vzip)
+
+ # Old version for Python 2.7, only.
+ import os
+ import tempfile
+
fd, fname = tempfile.mkstemp(prefix='embedded.', suffix='.zip')
os.write(fd, zipbytes)
os.close(fd)
@@ -178,6 +190,45 @@ def prepare_zipfile():
print('Broken Zip File:', e)
traceback.print_exc(file=sys.stdout)
finally:
- return fname
+ return sys.path, fname
+
+
+class EmbeddableZipImporter(object):
+
+ def __init__(self, zip_file):
+ def p2m(filename):
+ if filename.endswith("/__init__.py"):
+ return filename[:-12].replace("/", ".")
+ if filename.endswith(".py"):
+ return filename[:-3].replace("/", ".")
+ return None
+
+ self.zfile = zip_file
+ self._path2mod = {_.filename : p2m(_.filename) for _ in zip_file.filelist}
+ self._mod2path = {_[1] : _[0] for _ in self._path2mod.items()}
+
+ def find_module(self, fullname, path):
+ return self if self._mod2path.get(fullname) else None
+
+ def load_module(self, fullname):
+ import importlib
+ import sys
+
+ filename = self._mod2path.get(fullname)
+ if filename not in self._path2mod:
+ raise ImportError(fullname)
+ module_spec = importlib.machinery.ModuleSpec(fullname, None)
+ new_module = importlib.util.module_from_spec(module_spec)
+ with self.zfile.open(filename, "r") as f: # "rb" not for zipfile
+ exec(f.read(), new_module.__dict__)
+ new_module.__file__ = filename
+ new_module.__loader__ = self
+ if filename.endswith("/__init__.py"):
+ new_module.__path__ = []
+ new_module.__package__ = fullname
+ else:
+ new_module.__package__ = fullname.rpartition('.')[0]
+ sys.modules[fullname] = new_module
+ return new_module
# eof
diff --git a/sources/shiboken2/libshiboken/sbkenum.cpp b/sources/shiboken2/libshiboken/sbkenum.cpp
index 0d103db6c..7dc73dfbc 100644
--- a/sources/shiboken2/libshiboken/sbkenum.cpp
+++ b/sources/shiboken2/libshiboken/sbkenum.cpp
@@ -750,6 +750,7 @@ newTypeWithName(const char *name,
newspec.slots = newslots;
Shiboken::AutoDecRef bases(PyTuple_New(1));
static auto basetype = SbkEnum_TypeF();
+ Py_INCREF(basetype);
PyTuple_SetItem(bases, 0, reinterpret_cast<PyObject *>(basetype));
auto *type = reinterpret_cast<PyTypeObject *>(SbkType_FromSpecWithBases(&newspec, bases));
PyErr_Print();
diff --git a/sources/shiboken2/libshiboken/signature/signature_globals.cpp b/sources/shiboken2/libshiboken/signature/signature_globals.cpp
index d23ae15d0..818102804 100644
--- a/sources/shiboken2/libshiboken/signature/signature_globals.cpp
+++ b/sources/shiboken2/libshiboken/signature/signature_globals.cpp
@@ -110,7 +110,7 @@ static safe_globals_struc *init_phase_1(PyMethodDef *init_meth)
if (compile == nullptr)
goto error;
AutoDecRef code_obj(PyObject_CallFunction(compile, "Oss",
- bytes.object(), "(builtin)", "exec"));
+ bytes.object(), "signature_bootstrap.py", "exec"));
#else
AutoDecRef code_obj(PyObject_CallFunctionObjArgs(
loads, bytes.object(), nullptr));
diff --git a/sources/shiboken2/shiboken_version.py b/sources/shiboken2/shiboken_version.py
index 876a0e401..3ee73451b 100644
--- a/sources/shiboken2/shiboken_version.py
+++ b/sources/shiboken2/shiboken_version.py
@@ -39,7 +39,7 @@
major_version = "5"
minor_version = "15"
-patch_version = "5"
+patch_version = "6"
# For example: "a", "b", "rc"
# (which means "alpha", "beta", "release candidate").
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
index a509ecf07..022299391 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
@@ -206,6 +206,7 @@ def move_into_pyside_package():
put_into_package(PySide2.support.signature, parser)
put_into_package(PySide2.support.signature, importhandler)
put_into_package(PySide2.support.signature.lib, enum_sig)
+ put_into_package(PySide2.support.signature.lib, tool)
put_into_package(None if orig_typing else PySide2.support.signature, typing)
put_into_package(PySide2.support.signature, inspect)
@@ -217,6 +218,7 @@ from shibokensupport.signature import lib
from shibokensupport.signature import parser
from shibokensupport.signature import importhandler
from shibokensupport.signature.lib import enum_sig
+from shibokensupport.signature.lib import tool
if "PySide2" in sys.modules:
# We publish everything under "PySide2.support.signature", again.
diff --git a/tools/create_changelog.py b/tools/create_changelog.py
index 8f5ea7ad0..7fbff8bed 100644
--- a/tools/create_changelog.py
+++ b/tools/create_changelog.py
@@ -196,12 +196,13 @@ def extract_change_log(commit_message: List[str]) -> Tuple[str, List[str]]:
result = []
component = 'pyside'
within_changelog = False
+ task_nr = ''
for line in commit_message:
if within_changelog:
if line:
result.append(' ' + line.strip())
else:
- break
+ within_changelog = False
else:
if line.startswith('[ChangeLog]'):
log_line = line[11:]
@@ -210,8 +211,16 @@ def extract_change_log(commit_message: List[str]) -> Tuple[str, List[str]]:
if end > 0:
component = log_line[1:end]
log_line = log_line[end + 1:]
- result.append(' * ' + log_line.strip())
+ result.append(log_line.strip())
within_changelog = True
+ elif line.startswith("Fixes: ") or line.startswith("Task-number: "):
+ task_nr = line.split(":")[1].strip()
+ if result:
+ first_line = ' - '
+ if task_nr:
+ first_line += "[{}] ".format(task_nr)
+ first_line += result[0]
+ result[0] = first_line
return (component, result)