diff options
Diffstat (limited to 'sources')
12 files changed, 147 insertions, 45 deletions
diff --git a/sources/pyside6/PySide6/QtBluetooth/typesystem_bluetooth.xml b/sources/pyside6/PySide6/QtBluetooth/typesystem_bluetooth.xml index 165cd310f..7c260bfc0 100644 --- a/sources/pyside6/PySide6/QtBluetooth/typesystem_bluetooth.xml +++ b/sources/pyside6/PySide6/QtBluetooth/typesystem_bluetooth.xml @@ -53,7 +53,7 @@ <enum-type name="Pairing"/> </object-type> <object-type name="QBluetoothDeviceDiscoveryAgent"> - <enum-type name="DiscoveryMethod"/> + <enum-type name="DiscoveryMethod" flags="DiscoveryMethods"/> <enum-type name="Error"/> </object-type> <value-type name="QBluetoothDeviceInfo"> diff --git a/sources/pyside6/PySide6/QtWidgets/CMakeLists.txt b/sources/pyside6/PySide6/QtWidgets/CMakeLists.txt index 3f960bcff..85d4cdfd2 100644 --- a/sources/pyside6/PySide6/QtWidgets/CMakeLists.txt +++ b/sources/pyside6/PySide6/QtWidgets/CMakeLists.txt @@ -37,6 +37,7 @@ ${QtWidgets_GEN_DIR}/qfocusframe_wrapper.cpp ${QtWidgets_GEN_DIR}/qfontcombobox_wrapper.cpp ${QtWidgets_GEN_DIR}/qfontdialog_wrapper.cpp ${QtWidgets_GEN_DIR}/qformlayout_wrapper.cpp +${QtWidgets_GEN_DIR}/qformlayout_takerowresult_wrapper.cpp ${QtWidgets_GEN_DIR}/qframe_wrapper.cpp ${QtWidgets_GEN_DIR}/qgesture_wrapper.cpp ${QtWidgets_GEN_DIR}/qgestureevent_wrapper.cpp diff --git a/sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml b/sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml index 1df831d72..384b03b27 100644 --- a/sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml +++ b/sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml @@ -2295,10 +2295,19 @@ <include file-name="QPixmap" location="global"/> </extra-includes> + <!-- FIXME PYSIDE-7: Remove deprecated overloads --> <modify-function signature="critical(QWidget*,const QString&,const QString&,QFlags<QMessageBox::StandardButton>,QMessageBox::StandardButton)" allow-thread="yes"/> + <modify-function signature="critical(QWidget*,const QString&,const QString&,QMessageBox::StandardButton,QMessageBox::StandardButton)" + allow-thread="yes"/> <modify-function signature="information(QWidget*,const QString&,const QString&,QFlags<QMessageBox::StandardButton>,QMessageBox::StandardButton)" allow-thread="yes"/> + <modify-function signature="information(QWidget*,const QString&,const QString&,QMessageBox::StandardButton,QMessageBox::StandardButton)" + allow-thread="yes"/> <modify-function signature="question(QWidget*,const QString&,const QString&,QFlags<QMessageBox::StandardButton>,QMessageBox::StandardButton)" allow-thread="yes"/> + <modify-function signature="question(QWidget*,const QString&,const QString&,QMessageBox::StandardButton,QMessageBox::StandardButton)" + allow-thread="yes"/> <modify-function signature="warning(QWidget*,const QString&,const QString&,QFlags<QMessageBox::StandardButton>,QMessageBox::StandardButton)" allow-thread="yes"/> + <modify-function signature="warning(QWidget*,const QString&,const QString&,QMessageBox::StandardButton,QMessageBox::StandardButton)" + allow-thread="yes"/> <modify-function signature="QMessageBox(const QString&,const QString&,QMessageBox::Icon,int,int,int,QWidget*,QFlags<Qt::WindowType>)" remove="all"/> <modify-function signature="critical(QWidget*,const QString&,const QString&,int,int,int)" remove="all"/> <modify-function signature="critical(QWidget*,const QString&,const QString&,const QString&,const QString&,const QString&,int,int)" remove="all"/> @@ -2912,6 +2921,9 @@ <enum-type name="ItemRole"/> <enum-type name="RowWrapPolicy"/> + <value-type name="TakeRowResult"> + <include file-name="QFormLayout" location="global"/> + </value-type> <modify-function signature="getLayoutPosition(QLayout*,int*,QFormLayout::ItemRole*)const"> <modify-argument index="0"> diff --git a/sources/pyside6/PySide6/glue/qtwidgets.cpp b/sources/pyside6/PySide6/glue/qtwidgets.cpp index b355f41cb..f95db9ee5 100644 --- a/sources/pyside6/PySide6/glue/qtwidgets.cpp +++ b/sources/pyside6/PySide6/glue/qtwidgets.cpp @@ -96,6 +96,11 @@ QFormLayout::ItemRole _role; %CPPSELF->%FUNCTION_NAME(%ARGUMENT_NAMES, &_row, &_role); %PYARG_0 = PyTuple_New(2); PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](_row)); +// On the C++ side, *rolePtr is not set if row == -1, in which case on +// the Python side this gets converted to a random value outside the +// enum range. Fix this by setting _role to a default value here. +if (_row == -1) + _role = QFormLayout::LabelRole; PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QFormLayout::ItemRole](_role)); // @snippet qformlayout-fix-args diff --git a/sources/pyside6/PySide6/qtguihelper.h b/sources/pyside6/PySide6/qtguihelper.h index 4fee6c53e..acc0de6a8 100644 --- a/sources/pyside6/PySide6/qtguihelper.h +++ b/sources/pyside6/PySide6/qtguihelper.h @@ -50,7 +50,7 @@ namespace QtGuiHelper { Q_DISABLE_COPY_MOVE(QOverrideCursorGuard) QOverrideCursorGuard() = default; - ~QOverrideCursorGuard() { restoreOverrideCursor(); } + ~QOverrideCursorGuard() = default; void restoreOverrideCursor() { diff --git a/sources/pyside6/doc/modules.rst b/sources/pyside6/doc/modules.rst index 9b20d6906..7134c2638 100644 --- a/sources/pyside6/doc/modules.rst +++ b/sources/pyside6/doc/modules.rst @@ -1,5 +1,5 @@ -Qt Modules -=========== +Qt Modules Supported by Qt for Python +===================================== .. toctree:: :hidden: diff --git a/sources/pyside6/tests/QtWidgets/qformlayout_test.py b/sources/pyside6/tests/QtWidgets/qformlayout_test.py index 55348daaa..7cd59b63f 100644 --- a/sources/pyside6/tests/QtWidgets/qformlayout_test.py +++ b/sources/pyside6/tests/QtWidgets/qformlayout_test.py @@ -35,7 +35,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) from init_paths import init_test_paths init_test_paths(False) -from PySide6.QtWidgets import QFormLayout, QWidget +from PySide6.QtWidgets import QFormLayout, QWidget, QLabel, QMainWindow from helper.usesqapplication import UsesQApplication @@ -44,12 +44,11 @@ class QFormLayoutTest(UsesQApplication): def testGetItemPosition(self): formlayout = QFormLayout() - if not sys.pyside63_option_python_enum: - # PYSIDE-1735: This gives random values if no row exists. - row, role = formlayout.getItemPosition(0) - self.assertTrue(isinstance(row, int)) - self.assertTrue(isinstance(role, QFormLayout.ItemRole)) - self.assertEqual(row, -1) + + row, role = formlayout.getItemPosition(0) + self.assertTrue(isinstance(row, int)) + self.assertTrue(isinstance(role, QFormLayout.ItemRole)) + self.assertEqual(row, -1) widget = QWidget() formlayout.addRow(widget) @@ -62,12 +61,11 @@ class QFormLayoutTest(UsesQApplication): def testGetWidgetPosition(self): formlayout = QFormLayout() widget = QWidget() - if not sys.pyside63_option_python_enum: - # PYSIDE-1735: This gives random values if no row exists. - row, role = formlayout.getWidgetPosition(widget) - self.assertTrue(isinstance(row, int)) - self.assertTrue(isinstance(role, QFormLayout.ItemRole)) - self.assertEqual(row, -1) + + row, role = formlayout.getWidgetPosition(widget) + self.assertTrue(isinstance(row, int)) + self.assertTrue(isinstance(role, QFormLayout.ItemRole)) + self.assertEqual(row, -1) formlayout.addRow(widget) row, role = formlayout.getWidgetPosition(widget) @@ -79,12 +77,11 @@ class QFormLayoutTest(UsesQApplication): def testGetLayoutPosition(self): formlayout = QFormLayout() layout = QFormLayout() - if not sys.pyside63_option_python_enum: - # PYSIDE-1735: This gives random values if no row exists. - row, role = formlayout.getLayoutPosition(layout) - self.assertTrue(isinstance(row, int)) - self.assertTrue(isinstance(role, QFormLayout.ItemRole)) - self.assertEqual(row, -1) + + row, role = formlayout.getLayoutPosition(layout) + self.assertTrue(isinstance(row, int)) + self.assertTrue(isinstance(role, QFormLayout.ItemRole)) + self.assertEqual(row, -1) formlayout.addRow(layout) row, role = formlayout.getLayoutPosition(layout) @@ -93,7 +90,35 @@ class QFormLayoutTest(UsesQApplication): self.assertEqual(row, 0) self.assertEqual(role, QFormLayout.SpanningRole) + def testTakeRow(self): + window = QMainWindow() + window.setCentralWidget(QWidget()) + formlayout = QFormLayout(window.centralWidget()) + + widget_label = "blub" + widget = QLabel(widget_label) + + self.assertEqual(formlayout.count(), 0) + formlayout.addRow(widget) + self.assertEqual(formlayout.count(), 1) + self.assertEqual(formlayout.itemAt(0).widget(), widget) + + widget_id = id(widget) + + # Now there are no more references to the original widget on the + # Python side. Assert that this does not break the references to + # the widget on the C++ side so that "taking" the row will work. + del widget + + takeRowResult = formlayout.takeRow(0) + self.assertEqual(formlayout.count(), 0) + + widget = takeRowResult.fieldItem.widget() + + self.assertIsNotNone(widget) + self.assertEqual(widget_id, id(widget)) + self.assertEqual(widget.text(), widget_label) + if __name__ == "__main__": unittest.main() - diff --git a/sources/pyside6/tests/registry/existence_test.py b/sources/pyside6/tests/registry/existence_test.py index 2ab18152a..fa6cdde34 100644 --- a/sources/pyside6/tests/registry/existence_test.py +++ b/sources/pyside6/tests/registry/existence_test.py @@ -72,8 +72,8 @@ import unittest from pathlib import Path sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) -from init_paths import init_all_test_paths -init_all_test_paths() +from init_paths import init_test_paths +init_test_paths(True) from init_platform import enum_all, generate_all from util import (isolate_warnings, check_warnings, suppress_warnings, warn, @@ -119,6 +119,19 @@ if have_refmodule and not hasattr(sig_exists, dict_name): have_refmodule = False +class TestUnrecognizedOffending(unittest.TestCase): + """ + We run the signature generation on all modules and raise an error + if a warning was issued. This is better than turning warnings into + errors because that would stop early before we have all warnings. + """ + def test_signatures_recognized(self): + with isolate_warnings(): + found_sigs = enum_all() + if check_warnings(): + raise RuntimeError("There are errors, see above.") + + @unittest.skipIf(not have_refmodule, "not activated for this platform or version") class TestSignaturesExists(unittest.TestCase): diff --git a/sources/pyside6/tests/registry/init_platform.py b/sources/pyside6/tests/registry/init_platform.py index 06c488ee3..e22d2c9b8 100644 --- a/sources/pyside6/tests/registry/init_platform.py +++ b/sources/pyside6/tests/registry/init_platform.py @@ -1,6 +1,6 @@ ############################################################################# ## -## Copyright (C) 2019 The Qt Company Ltd. +## Copyright (C) 2022 The Qt Company Ltd. ## Contact: https://www.qt.io/licensing/ ## ## This file is part of Qt for Python. @@ -113,13 +113,7 @@ def set_ospaths(build_dir): ps = os.pathsep ospath_var = "PATH" if sys.platform == "win32" else "LD_LIBRARY_PATH" old_val = os.environ.get(ospath_var, "") - lib_path = [os.path.join(build_dir, "pyside6", "libpyside"), - os.path.join(build_dir, "pyside6", "tests", "pysidetest"), - os.path.join(build_dir, "shiboken6", "tests", "libminimal"), - os.path.join(build_dir, "shiboken6", "tests", "libsample"), - os.path.join(build_dir, "shiboken6", "tests", "libother"), - os.path.join(build_dir, "shiboken6", "tests", "libsmart"), - os.path.join(build_dir, "shiboken6", "libshiboken")] + lib_path = [os.path.join(build_dir, "pyside6", "tests", "pysidetest"),] ospath = ps.join(lib_path + old_val.split(ps)) os.environ[ospath_var] = ospath @@ -139,12 +133,6 @@ all_modules.append("testbinding") from shiboken6 import Shiboken all_modules.append("shiboken6.Shiboken") -# 'sample/smart' are needed by 'other', so import them first. -for modname in "minimal sample smart other".split(): - sys.path.insert(0, os.path.join(shiboken_build_dir, "tests", modname + "binding")) - __import__(modname) - all_modules.append(modname) - from shibokensupport.signature.lib.enum_sig import SimplifyingEnumerator # Make sure not to get .pyc in Python2. @@ -208,6 +196,48 @@ def enum_all(): return ret +LICENSE_TEXT = """ +############################################################################# +## +## Copyright (C) 2022 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## 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 Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## 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-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# +""" + + def generate_all(): refPath = get_refpath() module = os.path.basename(os.path.splitext(refPath)[0]) @@ -218,7 +248,7 @@ def generate_all(): license_line = next((lno for lno, line in enumerate(lines) if "$QT_END_LICENSE$" in line)) fmt.print("#recreate # uncomment this to enforce generation") - fmt.print("".join(lines[:license_line + 3])) + fmt.print(LICENSE_TEXT) version = sys.version.replace('\n', ' ') build = qt_build() fmt.print(dedent(f'''\ diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp index 44f3e97c4..7f9fb42b8 100644 --- a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp +++ b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp @@ -676,8 +676,11 @@ QString BuilderPrivate::cursorValueExpression(BaseVisitor *bv, const CXCursor &c if (equalSign == std::string::npos) return QString(); ++equalSign; - return QString::fromLocal8Bit(snippet.data() + equalSign, - qsizetype(snippet.size() - equalSign)).trimmed(); + QString result = QString::fromLocal8Bit(snippet.data() + equalSign, + qsizetype(snippet.size() - equalSign)); + // Fix a default expression as read from code. Simplify white space + result.remove(u'\r'); + return result.contains(u'"') ? result.trimmed() : result.simplified(); } // Resolve a type (loop over aliases/typedefs), for example for base classes diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py index 2fd2b6c4f..94e2143f2 100644 --- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py +++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py @@ -236,7 +236,7 @@ def create_signature(props, key): # parser. pass else: - if varnames[0] in ("self", "cls"): + if varnames and varnames[0] in ("self", "cls"): varnames = varnames[1:] # calculate the modifications diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py index 63cb423c1..f1148eaaf 100644 --- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py +++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py @@ -61,7 +61,7 @@ class ellipsis(object): return "..." ellipsis = ellipsis() -Point = typing.Tuple[float, float] +Point = typing.Tuple[int, int] Variant = typing.Any QImageCleanupFunction = typing.Callable @@ -318,6 +318,8 @@ type_map.update({ "zero(str)": "", "zero(typing.Any)": None, "zero(Any)": None, + # This can be refined by importing numpy.typing optionally, but better than nothing. + "numpy.ndarray": typing.List[typing.Any], }) type_map.update({ @@ -692,9 +694,20 @@ def init_PySide6_QtBluetooth(): return locals() +def init_PySide6_QtHttpServer(): + type_map.update({ + "qMakePair(1u, 1u)": (1, 1), + }) + return locals() + + def init_testbinding(): type_map.update({ "testbinding.PySideCPP2.TestObjectWithoutNamespace": testbinding.TestObjectWithoutNamespace, + "testbinding.FlagsNamespace.Options": testbinding.Option, + "FlagsNamespace.Option.NoOptions": 0, + "StdIntList": typing.List[int], + 'Str("")': str(""), }) return locals() |