[neon/qt/pyside2/Neon/unstable] /: New upstream version 5.15.7

Dmitry Shachnev null at kde.org
Thu Jun 15 10:12:12 BST 2023


Git commit feca35ce028387e3e2c07cc9581473fc0949a09a by Dmitry Shachnev.
Committed on 31/12/2022 at 18:05.
Pushed by carlosdem into branch 'Neon/unstable'.

New upstream version 5.15.7

M  +3    -3    build_history/blacklist.txt
M  +2    -1    build_scripts/config.py
M  +26   -9    build_scripts/main.py
M  +6    -1    build_scripts/platforms/windows_desktop.py
M  +6    -1    build_scripts/setup_runner.py
M  +10   -0    build_scripts/utils.py
M  +1    -1    build_scripts/wheel_override.py
A  +46   -0    coin/dependencies.yaml
M  +7    -0    coin/instructions/common_environment.yaml
M  +1    -1    coin/instructions/execute_build_instructions.yaml
M  +6    -0    coin/instructions/execute_license_check.yaml
M  +1    -1    coin/instructions/execute_test_instructions.yaml
M  +7    -7    coin/instructions/relocate_pyside.yaml
M  +9    -9    coin/module_config.yaml
M  +5    -1    coin_build_instructions.py
M  +3    -1    coin_test_instructions.py
A  +46   -0    dist/changes-5.15.3
A  +38   -0    dist/changes-5.15.4
A  +30   -0    dist/changes-5.15.5
A  +34   -0    dist/changes-5.15.6
A  +33   -0    dist/changes-5.15.7
M  +6    -8    examples/widgets/mainwindows/application/application.py
M  +8    -10   examples/widgets/mainwindows/mdi/mdi.py
M  +15   -8    examples/widgets/richtext/textobject/textobject.py
D  +0    -3    product_dependencies.yaml
M  +3    -1    sources/pyside2-tools/pyside_tool.py
M  +1    -1    sources/pyside2/CMakeLists.txt
M  +21   -1    sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
M  +65   -66   sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml
M  +1    -1    sources/pyside2/PySide2/QtGui/CMakeLists.txt
M  +38   -5    sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml
M  +2    -0    sources/pyside2/PySide2/QtNetwork/typesystem_network.xml
M  +5    -1    sources/pyside2/PySide2/QtOpenGLFunctions/CMakeLists.txt
M  +2    -0    sources/pyside2/PySide2/QtOpenGLFunctions/QtOpenGLFunctions_global.post.h.in
M  +9    -0    sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions.xml
M  +3    -3    sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp
M  +8    -1    sources/pyside2/PySide2/QtQml/typesystem_qml.xml
M  +1    -0    sources/pyside2/PySide2/QtTest/CMakeLists.txt
M  +4    -0    sources/pyside2/PySide2/QtTest/typesystem_test.xml
M  +4    -0    sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
M  +73   -35   sources/pyside2/PySide2/glue/qtcore.cpp
M  +37   -0    sources/pyside2/PySide2/glue/qtdatavisualization.cpp
M  +57   -0    sources/pyside2/PySide2/glue/qtgui.cpp
A  +76   -0    sources/pyside2/PySide2/glue/qtopenglfunctions.cpp  *
A  +45   -0    sources/pyside2/PySide2/qopenglversionfunctionsfactory.h  *
M  +8    -12   sources/pyside2/PySide2/support/generate_pyi.py
M  +22   -5    sources/pyside2/PySide2/templates/core_common.xml
M  +2    -1    sources/pyside2/PySide2/templates/gui_common.xml
M  +1    -0    sources/pyside2/doc/CMakeLists.txt
M  +71   -3    sources/pyside2/doc/extras/QtCore.Property.rst
M  +0    -6    sources/pyside2/doc/quickstart.rst
M  +8    -0    sources/pyside2/doc/tutorials/basictutorial/uifiles.rst
M  +21   -1    sources/pyside2/libpyside/feature_select.cpp
M  +9    -8    sources/pyside2/libpyside/globalreceiverv2.cpp
M  +39   -25   sources/pyside2/libpyside/pyside.cpp
M  +6    -3    sources/pyside2/libpyside/pyside.h
M  +1    -1    sources/pyside2/libpyside/pysideclassinfo.cpp
M  +1    -1    sources/pyside2/libpyside/pysidemetafunction.cpp
M  +7    -7    sources/pyside2/libpyside/pysideproperty.cpp
M  +9    -4    sources/pyside2/libpyside/pysideqflags.cpp
M  +5    -5    sources/pyside2/libpyside/pysidesignal.cpp
M  +1    -1    sources/pyside2/libpyside/pysideslot.cpp
M  +6    -0    sources/pyside2/libpyside/pysidestaticstrings.cpp
M  +6    -0    sources/pyside2/libpyside/pysidestaticstrings.h
M  +1    -1    sources/pyside2/pyside_version.py
M  +1    -0    sources/pyside2/tests/QtCore/CMakeLists.txt
M  +2    -0    sources/pyside2/tests/QtCore/bug_686.py
C  +2    -24   sources/pyside2/tests/QtCore/feature_with_uic/__init__.py [from: sources/pyside2/tests/pysidetest/enum_test.py - 065% similarity]
A  +81   -0    sources/pyside2/tests/QtCore/feature_with_uic/window.py
A  +62   -0    sources/pyside2/tests/QtCore/feature_with_uic/window.ui
C  +32   -24   sources/pyside2/tests/QtCore/feature_with_uic_test.py [from: sources/pyside2/tests/QtGui/qdatastream_gui_operators_test.py - 059% similarity]
M  +7    -5    sources/pyside2/tests/QtCore/qflags_test.py
M  +30   -0    sources/pyside2/tests/QtCore/qobject_parent_test.py
M  +21   -3    sources/pyside2/tests/QtCore/qsettings_test.py
M  +2    -0    sources/pyside2/tests/QtCore/snake_prop_feature_test.py
M  +13   -0    sources/pyside2/tests/QtCore/translation_test.py
M  +13   -0    sources/pyside2/tests/QtDataVisualization/datavisualization_test.py
M  +5    -3    sources/pyside2/tests/QtGui/qdatastream_gui_operators_test.py
M  +2    -26   sources/pyside2/tests/QtGui/qrasterwindow_test.py
M  +3    -2    sources/pyside2/tests/QtWidgets/signature_test.py
M  +32   -2    sources/pyside2/tests/pysidetest/constructor_properties_test.py
M  +3    -4    sources/pyside2/tests/pysidetest/embedding_test.py
M  +24   -0    sources/pyside2/tests/pysidetest/enum_test.py
M  +11   -6    sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
M  +17   -17   sources/shiboken2/ApiExtractor/abstractmetalang.cpp
M  +4    -4    sources/shiboken2/ApiExtractor/abstractmetalang.h
M  +19   -8    sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
M  +12   -3    sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
M  +6    -2    sources/shiboken2/ApiExtractor/clangparser/clangutils.h
M  +28   -15   sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
M  +33   -3    sources/shiboken2/ApiExtractor/qtdocparser.cpp
M  +4    -3    sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp
M  +22   -11   sources/shiboken2/ApiExtractor/typesystemparser.cpp
M  +30   -1    sources/shiboken2/CMakeLists.txt
T  +1    -76   sources/shiboken2/data/docgenerator.1
M  +1    -1    sources/shiboken2/data/shiboken_helpers.cmake
M  +12   -8    sources/shiboken2/doc/typesystem_codeinjection.rst
M  +4    -0    sources/shiboken2/doc/typesystem_conversionrule.rst
M  +7    -5    sources/shiboken2/doc/typesystem_variables.rst
M  +28   -14   sources/shiboken2/generator/generator.cpp
M  +3    -0    sources/shiboken2/generator/generator.h
M  +2    -3    sources/shiboken2/generator/main.cpp
M  +9    -30   sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
M  +148  -75   sources/shiboken2/generator/shiboken2/cppgenerator.cpp
M  +5    -1    sources/shiboken2/generator/shiboken2/cppgenerator.h
M  +13   -16   sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
M  +1    -5    sources/shiboken2/generator/shiboken2/shibokengenerator.h
M  +23   -3    sources/shiboken2/libshiboken/CMakeLists.txt
M  +94   -37   sources/shiboken2/libshiboken/basewrapper.cpp
M  +21   -8    sources/shiboken2/libshiboken/basewrapper.h
M  +3    -0    sources/shiboken2/libshiboken/basewrapper_p.h
M  +7    -3    sources/shiboken2/libshiboken/bindingmanager.cpp
M  +20   -2    sources/shiboken2/libshiboken/embed/embedding_generator.py
M  +74   -20   sources/shiboken2/libshiboken/embed/signature_bootstrap.py
M  +6    -4    sources/shiboken2/libshiboken/pep384impl.cpp
M  +6    -1    sources/shiboken2/libshiboken/pep384impl.h
D  +0    -100  sources/shiboken2/libshiboken/qapp_macro.cpp
D  +0    -52   sources/shiboken2/libshiboken/qapp_macro.h
M  +0    -1    sources/shiboken2/libshiboken/sbkarrayconverter.cpp
M  +1    -1    sources/shiboken2/libshiboken/sbkconverter_p.h
M  +68   -55   sources/shiboken2/libshiboken/sbkenum.cpp
M  +3    -0    sources/shiboken2/libshiboken/sbkenum.h
M  +4    -0    sources/shiboken2/libshiboken/sbkstaticstrings.cpp
M  +4    -0    sources/shiboken2/libshiboken/sbkstaticstrings.h
M  +1    -0    sources/shiboken2/libshiboken/sbkstaticstrings_p.h
M  +1    -1    sources/shiboken2/libshiboken/sbkstring.cpp
M  +23   -0    sources/shiboken2/libshiboken/shibokenbuffer.cpp
M  +8    -0    sources/shiboken2/libshiboken/shibokenbuffer.h
M  +1    -1    sources/shiboken2/libshiboken/signature.h
M  +103  -4    sources/shiboken2/libshiboken/signature/signature.cpp
M  +4    -1    sources/shiboken2/libshiboken/signature/signature_globals.cpp
M  +1    -1    sources/shiboken2/shiboken_version.py
M  +6    -31   sources/shiboken2/shibokenmodule/CMakeLists.txt
R  +4    -7    sources/shiboken2/shibokenmodule/files.dir/shibokensupport/feature.py [from: sources/shiboken2/shibokenmodule/files.dir/shibokensupport/__feature__.py - 095% similarity]
M  +22   -4    sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py
M  +35   -25   sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
M  +8    -0    sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py
M  +19   -14   sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
M  +7    -0    sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
M  +16   -15   sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
M  +1    -0    sources/shiboken2/tests/samplebinding/time_test.py
M  +2    -0    sources/shiboken2/tests/samplebinding/typesystem_sample.xml
M  +11   -2    tools/create_changelog.py
A  +122  -0    tools/debug_renamer.py
A  +196  -0    tools/leak_finder.py
A  +85   -0    tools/license_changer.py
C  +29   -14   tools/license_check.py [from: sources/pyside2/pyside_version.py - 069% similarity]
A  +123  -0    tools/uic_test.py

The files marked with a * at the end have a non valid license. Please read: https://community.kde.org/Policies/Licensing_Policy and use the headers which are listed at that page.


https://invent.kde.org/neon/qt/pyside2/-/commit/feca35ce028387e3e2c07cc9581473fc0949a09a

diff --git a/build_history/blacklist.txt b/build_history/blacklist.txt
index 9b63f978..827191a2 100644
--- a/build_history/blacklist.txt
+++ b/build_history/blacklist.txt
@@ -18,9 +18,6 @@
     darwin py3
 [QtCore::qfileread_test]
     darwin
-#  Nested exception in Python 3
-[QtCore::qflags_test]
-    py3
 [QtCore::qobject_connect_notify_test]
     linux
     darwin
@@ -96,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/build_scripts/config.py b/build_scripts/config.py
index b1b32068..00cbd3fc 100644
--- a/build_scripts/config.py
+++ b/build_scripts/config.py
@@ -93,6 +93,7 @@ class Config(object):
             'Programming Language :: Python :: 3.7',
             'Programming Language :: Python :: 3.8',
             'Programming Language :: Python :: 3.9',
+            'Programming Language :: Python :: 3.10',
         ]
 
         self.setup_script_dir = None
@@ -135,7 +136,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.10"
+        setup_kwargs['python_requires'] = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <3.11"
 
         if quiet:
             # Tells distutils / setuptools to be quiet, and only print warnings or errors.
diff --git a/build_scripts/main.py b/build_scripts/main.py
index ea91ef75..c7e67ac1 100644
--- a/build_scripts/main.py
+++ b/build_scripts/main.py
@@ -805,6 +805,8 @@ class PysideBuild(_build, DistUtilsCommandMixin):
         # Add source location for generating documentation
         cmake_src_dir = OPTION["QT_SRC"] if OPTION["QT_SRC"] else qt_src_dir
         cmake_cmd.append("-DQT_SRC_DIR={}".format(cmake_src_dir))
+        if OPTION['SKIP_DOCS']:
+            cmake_cmd.append("-DSKIP_DOCS=yes")
         log.info("Qt Source dir: {}".format(cmake_src_dir))
 
         if self.build_type.lower() == 'debug':
@@ -900,16 +902,23 @@ class PysideBuild(_build, DistUtilsCommandMixin):
             deployment_target = macos_pyside_min_deployment_target()
             cmake_cmd.append("-DCMAKE_OSX_DEPLOYMENT_TARGET={}".format(deployment_target))
             os.environ['MACOSX_DEPLOYMENT_TARGET'] = deployment_target
+        elif sys.platform == 'win32':
+            # Prevent cmake from auto-detecting clang if it is in path.
+            cmake_cmd.append("-DCMAKE_C_COMPILER=cl.exe")
+            cmake_cmd.append("-DCMAKE_CXX_COMPILER=cl.exe")
 
-        if OPTION["DOC_BUILD_ONLINE"]:
-            log.info("Output format will be HTML")
-            cmake_cmd.append("-DDOC_OUTPUT_FORMAT=html")
-        else:
-            log.info("Output format will be qthelp")
-            cmake_cmd.append("-DDOC_OUTPUT_FORMAT=qthelp")
+        if not OPTION["SKIP_DOCS"]:
+            # Build the whole documentation (rst + API) by default
+            cmake_cmd.append("-DFULLDOCSBUILD=1")
 
-        # Build the whole documentation (rst + API) by default
-        cmake_cmd.append("-DFULLDOCSBUILD=1")
+            if OPTION["DOC_BUILD_ONLINE"]:
+                log.info("Output format will be HTML")
+                cmake_cmd.append("-DDOC_OUTPUT_FORMAT=html")
+            else:
+                log.info("Output format will be qthelp")
+                cmake_cmd.append("-DDOC_OUTPUT_FORMAT=qthelp")
+        else:
+            cmake_cmd.append("-DSKIP_DOCS=1")
 
         if not OPTION["SKIP_CMAKE"]:
             log.info("Configuring module {} ({})...".format(extension, module_src_dir))
@@ -926,6 +935,13 @@ class PysideBuild(_build, DistUtilsCommandMixin):
         if run_process(cmd_make) != 0:
             raise DistutilsSetupError("Error compiling {}".format(extension))
 
+        if sys.version_info == (3, 6) and sys.platform == "darwin":
+            # Python 3.6 has a Sphinx problem because of docutils 0.17 .
+            # Instead of pinning v0.16, setting the default encoding fixes that.
+            # Since other platforms are not affected, we restrict this to macOS.
+            if "UTF-8" not in os.environ.get("LC_ALL", ""):
+                os.environ["LC_ALL"] = "en_US.UTF-8"
+
         if not OPTION["SKIP_DOCS"]:
             if extension.lower() == "shiboken2":
                 try:
@@ -940,6 +956,7 @@ class PysideBuild(_build, DistUtilsCommandMixin):
                     log.info("Sphinx not found, skipping documentation build")
         else:
             log.info("Skipped documentation generation")
+            cmake_cmd.append("-DSKIP_DOCS=1")
 
         if not OPTION["SKIP_MAKE_INSTALL"]:
             log.info("Installing module {}...".format(extension))
@@ -1039,7 +1056,7 @@ class PysideBuild(_build, DistUtilsCommandMixin):
             OPTION["CMAKE"],
             "-L",         # Lists variables
             "-N",         # Just inspects the cache (faster)
-            "--build",    # Specifies the build dir
+            "-B",         # Specifies the build dir
             self.shiboken_build_dir
         ]
         out = run_process_output(cmake_cmd)
diff --git a/build_scripts/platforms/windows_desktop.py b/build_scripts/platforms/windows_desktop.py
index 345847e2..6b92c082 100644
--- a/build_scripts/platforms/windows_desktop.py
+++ b/build_scripts/platforms/windows_desktop.py
@@ -270,7 +270,12 @@ def copy_msvc_redist_files(vars, redist_target_path):
         zip_file = "pyside_qt_deps_64_2019.7z"
         if "{target_arch}".format(**vars) == "32":
             zip_file = "pyside_qt_deps_32_2019.7z"
-        download_and_extract_7z(redist_url + zip_file, redist_target_path)
+        try:
+            download_and_extract_7z(redist_url + zip_file, redist_target_path)
+        except:
+            print("download.qt.io is down, try with mirror")
+            redist_url = "https://www.funet.fi/pub/mirrors/download.qt-project.org/development_releases/prebuilt/vcredist/"
+            download_and_extract_7z(redist_url + zip_file, redist_target_path)
     else:
         print("Qt dependency DLLs (MSVC redist) will not be downloaded and extracted.")
 
diff --git a/build_scripts/setup_runner.py b/build_scripts/setup_runner.py
index 57c8fbd1..3c7116b8 100644
--- a/build_scripts/setup_runner.py
+++ b/build_scripts/setup_runner.py
@@ -88,8 +88,13 @@ class SetupRunner(object):
         internal_build_type_arg = self.construct_internal_build_type_cmd_line_argument(build_type)
         setup_cmd = [sys.executable] + self.sub_argv + [internal_build_type_arg]
 
+        command = self.sub_argv[0]
+        if command == 'setup.py' and len(self.sub_argv) > 1:
+            command = self.sub_argv[1]
+
         # Add --reuse-build option if requested and not already present.
-        if reuse_build and not self.cmd_line_argument_is_in_args("reuse-build", self.sub_argv):
+        if (reuse_build and command in ('bdist_wheel', 'build', 'build_rst_docs', 'install')
+            and not self.cmd_line_argument_is_in_args("reuse-build", self.sub_argv)):
             setup_cmd.append(self.construct_cmd_line_argument("reuse-build"))
         self.invocations_list.append(setup_cmd)
 
diff --git a/build_scripts/utils.py b/build_scripts/utils.py
index 0782ae03..002d6ae5 100644
--- a/build_scripts/utils.py
+++ b/build_scripts/utils.py
@@ -691,6 +691,16 @@ def find_llvm_config():
     return result
 
 
+# Expand the __ARCH_ place holder in the CLANG environment variables
+def expand_clang_variables(target_arch):
+    for var in 'LLVM_INSTALL_DIR', 'CLANG_INSTALL_DIR':
+        value = os.environ.get(var)
+        if value and '_ARCH_' in value:
+            value = value.replace('_ARCH_', target_arch)
+            os.environ[var] = value
+            print("{} = {}".format(var, value))
+
+
 # Add Clang to path for Windows for the shiboken ApiExtractor tests.
 # Revisit once Clang is bundled with Qt.
 def detect_clang():
diff --git a/build_scripts/wheel_override.py b/build_scripts/wheel_override.py
index 66141763..3f3c12a2 100644
--- a/build_scripts/wheel_override.py
+++ b/build_scripts/wheel_override.py
@@ -90,7 +90,7 @@ class PysideBuildWheel(_bdist_wheel, DistUtilsCommandMixin):
         limited_api_enabled = (OPTION["LIMITED_API"] == 'yes'
                                and sys.version_info[0] >= 3)
         if limited_api_enabled:
-            self.py_limited_api = "cp35.cp36.cp37.cp38.cp39"
+            self.py_limited_api = "cp35.cp36.cp37.cp38.cp39.cp310"
 
         self._package_version = get_package_version()
 
diff --git a/coin/dependencies.yaml b/coin/dependencies.yaml
new file mode 100644
index 00000000..032c8c4b
--- /dev/null
+++ b/coin/dependencies.yaml
@@ -0,0 +1,46 @@
+product_dependency:
+  ../../qt/tqtc-qt5.git:
+    ref: "4f71992dd5c14023330332538c84cb5fb5ac5a14"
+dependency_source: supermodule
+dependencies: [
+      "../../qt/qt3d",
+      "../../qt/qtactiveqt",
+      "../../qt/qtandroidextras",
+      "../../qt/qtbase",
+      "../../qt/qtcharts",
+      "../../qt/qtconnectivity",
+      "../../qt/qtdatavis3d",
+      "../../qt/qtdeclarative",
+      "../../qt/qtdoc",
+      "../../qt/qtgamepad",
+      "../../qt/qtgraphicaleffects",
+      "../../qt/qtimageformats",
+      "../../qt/qtlocation",
+      "../../qt/qtlottie",
+      "../../qt/qtmacextras",
+      "../../qt/qtmultimedia",
+      "../../qt/qtnetworkauth",
+      "../../qt/qtpurchasing",
+      "../../qt/qtqa",
+      "../../qt/qtquick3d",
+      "../../qt/qtquickcontrols2",
+      "../../qt/qtquicktimeline",
+      "../../qt/qtremoteobjects",
+      "../../qt/qtscxml",
+      "../../qt/qtsensors",
+      "../../qt/qtserialbus",
+      "../../qt/qtserialport",
+      "../../qt/qtspeech",
+      "../../qt/qtsvg",
+      "../../qt/qttools",
+      "../../qt/qttranslations",
+      "../../qt/qtvirtualkeyboard",
+      "../../qt/qtwayland",
+      "../../qt/qtwebchannel",
+      "../../qt/qtwebengine",
+      "../../qt/qtwebglplugin",
+      "../../qt/qtwebsockets",
+      "../../qt/qtwebview",
+      "../../qt/qtwinextras",
+      "../../qt/qtx11extras"
+      ]
diff --git a/coin/instructions/common_environment.yaml b/coin/instructions/common_environment.yaml
index 2c660333..41ab0059 100644
--- a/coin/instructions/common_environment.yaml
+++ b/coin/instructions/common_environment.yaml
@@ -115,3 +115,10 @@ instructions:
          condition: property
          property: target.compiler
          equals_value: ICC_18
+    - type: EnvironmentVariable
+      variableName: LLVM_INSTALL_DIR
+      variableValue: "{{.Env.LLVM_DYNAMIC_LIBS_100}}"
+      disable_if:
+         condition: property
+         property: host.osVersion
+         equals_value: openSUSE_15_1
diff --git a/coin/instructions/execute_build_instructions.yaml b/coin/instructions/execute_build_instructions.yaml
index 1a0c7306..e940e925 100644
--- a/coin/instructions/execute_build_instructions.yaml
+++ b/coin/instructions/execute_build_instructions.yaml
@@ -39,7 +39,7 @@ instructions:
       property: host.os
       equals_value: Windows
   - type: ChangeDirectory
-    directory: "{{.AgentWorkingDir}}\\pyside\\pyside-setup"
+    directory: "{{.AgentWorkingDir}}\\pyside\\tqtc-pyside-setup"
     enable_if:
         condition: property
         property: host.os
diff --git a/coin/instructions/execute_license_check.yaml b/coin/instructions/execute_license_check.yaml
index 51027ba7..9b4d68d4 100644
--- a/coin/instructions/execute_license_check.yaml
+++ b/coin/instructions/execute_license_check.yaml
@@ -18,6 +18,12 @@ instructions:
       directory: qt/qtqa-latest
       userMessageOnFailure: >
               Could not install source archive. Please investigate why.
+    - type: ExecuteCommand
+      command: /bin/mv pyside/tqtc-pyside-setup pyside/pyside-setup
+      maxTimeInSeconds: 300
+      maxTimeBetweenOutput: 120
+      userMessageOnFailure: >
+              Failed to rename tqtc-pyside-setup dir
     - type: EnvironmentVariable
       variableName: QT_MODULE_TO_TEST
       variableValue: pyside/pyside-setup
diff --git a/coin/instructions/execute_test_instructions.yaml b/coin/instructions/execute_test_instructions.yaml
index 22a98066..f5dd7aa5 100644
--- a/coin/instructions/execute_test_instructions.yaml
+++ b/coin/instructions/execute_test_instructions.yaml
@@ -30,7 +30,7 @@ instructions:
   - type: ExecuteCommand
     command: "c:\\users\\qt\\MSVC.bat python -u coin_test_instructions.py --os={{.Env.CI_OS}} {{.Env.CI_PACKAGING_FEATURE}} --instdir=\\Users\\qt\\work\\install --targetOs={{.Env.CI_OS}} --hostArch=X86_64 --targetArch={{.Env.CI_TARGET_ARCHITECTURE}}"
     maxTimeInSeconds: 14400
-    maxTimeBetweenOutput: 600
+    maxTimeBetweenOutput: 1200
     enable_if:
         condition: property
         property: host.os
diff --git a/coin/instructions/relocate_pyside.yaml b/coin/instructions/relocate_pyside.yaml
index afab83c7..d096acb1 100644
--- a/coin/instructions/relocate_pyside.yaml
+++ b/coin/instructions/relocate_pyside.yaml
@@ -11,7 +11,7 @@ instructions:
     userMessageOnFailure: >
          Failed to change to pyside dir
   - type: ExecuteCommand
-    command: c:\\users\\qt\\MSVC.bat rd /s /q pyside-setup
+    command: c:\\users\\qt\\MSVC.bat rd /s /q tqtc-pyside-setup
     maxTimeInSeconds: 300
     maxTimeBetweenOutput: 120
     enable_if:
@@ -19,9 +19,9 @@ instructions:
       property: host.os
       equals_value: Windows
     userMessageOnFailure: >
-         Failed to remove pyside-setup dir
+         Failed to remove tqtc-pyside-setup dir
   - type: ExecuteCommand
-    command: /bin/rm -rf pyside-setup
+    command: /bin/rm -rf tqtc-pyside-setup
     maxTimeInSeconds: 300
     maxTimeBetweenOutput: 120
     enable_if:
@@ -29,14 +29,14 @@ instructions:
       property: host.os
       not_equals_value: Windows
     userMessageOnFailure: >
-         Failed to remove pyside-setup dir
+         Failed to remove tqtc-pyside-setup dir
   - type: InstallBinaryArchive
     relativeStoragePath: "{{.Env.MODULE_ARTIFACTS_RELATIVE_STORAGE_PATH}}/artifacts.tar.gz"
     directory: "pyside"
     maxTimeInSeconds: 1200
     maxTimeBetweenOutput: 1200
   - type: ChangeDirectory
-    directory: "{{.AgentWorkingDir}}\\pyside\\pyside-setup"
+    directory: "{{.AgentWorkingDir}}\\pyside\\tqtc-pyside-setup"
     maxTimeInSeconds: 7200
     maxTimeBetweenOutput: 120
     enable_if:
@@ -46,7 +46,7 @@ instructions:
     userMessageOnFailure: >
          Failed to install binary artifacts
   - type: ChangeDirectory
-    directory: "{{.AgentWorkingDir}}/pyside/pyside-setup"
+    directory: "{{.AgentWorkingDir}}/pyside/tqtc-pyside-setup"
     maxTimeInSeconds: 7200
     maxTimeBetweenOutput: 120
     enable_if:
@@ -54,4 +54,4 @@ instructions:
       property: host.os
       not_equals_value: Windows
     userMessageOnFailure: >
-         Failed to change to pyside-setup dir
+         Failed to change to tqtc-pyside-setup dir
diff --git a/coin/module_config.yaml b/coin/module_config.yaml
index fd80acf9..99778cce 100644
--- a/coin/module_config.yaml
+++ b/coin/module_config.yaml
@@ -18,7 +18,7 @@ accept_configuration:
             not_contains_value: -no-gui
           - condition: property   # Following configs are not supported
             property: target.osVersion
-            not_in_values: [OPENSUSE_13_01, QEMU, WebAssembly, Ubuntu_18_04, SLES_12, SLES_15]
+            not_in_values: [OPENSUSE_13_01, QEMU, WebAssembly, Ubuntu_18_04, SLES_12, SLES_15, MacOS_10_15]
           - condition: property  # MibnGW and msvc2015 are not supported
             property: target.compiler
             not_in_values: [Mingw, MSVC2015]
@@ -55,14 +55,14 @@ upload_pyside: &upload_pyside
 
 instructions:
      LicenseCheck:
-      - !include "{{pyside/pyside-setup}}/execute_license_check.yaml"
+      - !include "{{pyside/tqtc-pyside-setup}}/execute_license_check.yaml"
      Build:
-      - !include "{{pyside/pyside-setup}}/common_environment.yaml"
-      - !include "{{pyside/pyside-setup}}/find_path_to_msvc_compiler.yaml"
-      - !include "{{pyside/pyside-setup}}/execute_build_instructions.yaml"
+      - !include "{{pyside/tqtc-pyside-setup}}/common_environment.yaml"
+      - !include "{{pyside/tqtc-pyside-setup}}/find_path_to_msvc_compiler.yaml"
+      - !include "{{pyside/tqtc-pyside-setup}}/execute_build_instructions.yaml"
       - *upload_pyside
      Test:
-      - !include "{{pyside/pyside-setup}}/common_environment.yaml"
-      - !include "{{pyside/pyside-setup}}/find_path_to_msvc_compiler.yaml"
-      - !include "{{pyside/pyside-setup}}/relocate_pyside.yaml"
-      - !include "{{pyside/pyside-setup}}/execute_test_instructions.yaml"
+      - !include "{{pyside/tqtc-pyside-setup}}/common_environment.yaml"
+      - !include "{{pyside/tqtc-pyside-setup}}/find_path_to_msvc_compiler.yaml"
+      - !include "{{pyside/tqtc-pyside-setup}}/relocate_pyside.yaml"
+      - !include "{{pyside/tqtc-pyside-setup}}/execute_test_instructions.yaml"
diff --git a/coin_build_instructions.py b/coin_build_instructions.py
index 95d800b5..cf5dca62 100644
--- a/coin_build_instructions.py
+++ b/coin_build_instructions.py
@@ -38,7 +38,7 @@
 #############################################################################
 from build_scripts.options import has_option
 from build_scripts.options import option_value
-from build_scripts.utils import install_pip_dependencies
+from build_scripts.utils import install_pip_dependencies, expand_clang_variables
 from build_scripts.utils import get_qtci_virtualEnv
 from build_scripts.utils import run_instruction
 from build_scripts.utils import rmtree
@@ -143,6 +143,8 @@ def call_setup(python_ver, phase):
             "--verbose-build"]
     if python_ver == "3":
         cmd += ["--limited-api=yes"]
+    else:
+        cmd += ["--skip-docs"]  # Sphinx is broken in Python 2
     if is_snapshot_build():
         cmd += ["--snapshot-build"]
 
@@ -175,6 +177,8 @@ def run_build_instructions(phase):
 if __name__ == "__main__":
 
     # Remove some environment variables that impact cmake
+    arch = '32' if CI_TARGET_ARCH and CI_TARGET_ARCH == 'X86' else '64'
+    expand_clang_variables(arch)
     for env_var in ['CC', 'CXX']:
         if os.environ.get(env_var):
             del os.environ[env_var]
diff --git a/coin_test_instructions.py b/coin_test_instructions.py
index 467f58d1..3b8f7e39 100644
--- a/coin_test_instructions.py
+++ b/coin_test_instructions.py
@@ -38,7 +38,7 @@
 #############################################################################
 from build_scripts.options import has_option
 from build_scripts.options import option_value
-from build_scripts.utils import install_pip_dependencies
+from build_scripts.utils import install_pip_dependencies, expand_clang_variables
 from build_scripts.utils import get_qtci_virtualEnv
 from build_scripts.utils import run_instruction
 from build_scripts.utils import rmtree
@@ -103,6 +103,8 @@ def call_testrunner(python_ver, buildnro):
 
 def run_test_instructions():
     # Remove some environment variables that impact cmake
+    arch = '32' if CI_TARGET_ARCH and CI_TARGET_ARCH == 'X86' else '64'
+    expand_clang_variables(arch)
     for env_var in ['CC', 'CXX']:
         if os.environ.get(env_var):
             del os.environ[env_var]
diff --git a/dist/changes-5.15.3 b/dist/changes-5.15.3
new file mode 100644
index 00000000..fe795989
--- /dev/null
+++ b/dist/changes-5.15.3
@@ -0,0 +1,46 @@
+Qt for Python 5.15.3 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-454]  namespace std is no longer rejected in the Qt typesystem
+                 files.
+ - [PYSIDE-807]  setup.py's 'clean' command has been fixed.
+ - [PYSIDE-1305] The error handling of constructor keyword arguments has been
+                 fixed.
+ - [PYSIDE-1422] A crash related to  Signal and __eq__ has been fixed.
+ - [PYSIDE-1432] An ownership issue in QLayout::replaceWidget() has been fixed.
+ - [PYSIDE-1442] QFlags operations have been fixed.
+ - [PYSIDE-1447] A crash related to qApp and Python 3.9 has been fixed.
+ - [PYSIDE-1449] QTestlib's QAbstractItemModelTester has been added.
+ - [PYSIDE-1460] An infinite loop changing up directories in the signature
+                 bootstrap code has been fixed.
+ - [PYSIDE-1466] The newly introduced overload QSetting.value() taking a type
+                 has been documentated.
+ - [PYSIDE-1478] A bug related to using QQmlContext.setContextProperty()
+                 with the snake case feature has been fixed.
+
+****************************************************************************
+*                                  Shiboken2                               *
+****************************************************************************
+
+ - [PYSIDE-1347] Inheritance for enum types has been fixed.
+ - [PYSIDE-1448] Code injected at target/end being invoked for multiple
+                 overload ids has been fixed.
+ - [PYSIDE-1470] shiboken.delete() can now be used to delete Q*Application.
+ - [PYSIDE-1501] The clang parser has been fixed to be able to handle some
+                 Boost headers.
diff --git a/dist/changes-5.15.4 b/dist/changes-5.15.4
new file mode 100644
index 00000000..a97be5dc
--- /dev/null
+++ b/dist/changes-5.15.4
@@ -0,0 +1,38 @@
+Qt for Python 5.15.4 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-955]  QOpenGLContext.versionFunctions() have been implemented.
+                 Class QOpenGLVersionFunctionsFactory (from Qt 6) has also
+                 been added.
+ - [PYSIDE-1409] signature: The decision heuristics of result tuples have
+                 been refined.
+ - [PYSIDE-1438] Crashes in Qt Datavisualization's QBar/SurfaceDataProxy
+                 add/set/insertRow() members have been fixed.
+ - [PYSIDE-1502] Import errors will now be properly reported.
+ - [PYSIDE-1513] Documentation on properties has been added.
+ - [PYSIDE-1538] signature: Unrecognized items will no longer raise
+                 exceptions.
+ - [PYSIDE-1540] The performance of QPainter::drawPoints(QPolygon) has been
+                 improved.
+
+****************************************************************************
+*                                  Shiboken2                               *
+****************************************************************************
+
+ - [PYSIDE-1529] Crashes when registering static fields have been fixed.
diff --git a/dist/changes-5.15.5 b/dist/changes-5.15.5
new file mode 100644
index 00000000..02c98b0d
--- /dev/null
+++ b/dist/changes-5.15.5
@@ -0,0 +1,30 @@
+Qt for Python 5.15.5 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                                 *
+****************************************************************************
+
+ - Crashes in QClipboard.mimeData(), QTextCursor.currentList() and
+   QTextCursor.currentTable() have been fixed.
+ - Fixed issues where __feature__ was affected by other imports.
+ - Fixed crashes on QImage(uchar *) constructors, related to GIL handling.
+ - QOpenGLPaintDevice has been added.
+
+****************************************************************************
+*                                  Shiboken2                               *
+****************************************************************************
+
+ - No changes
diff --git a/dist/changes-5.15.6 b/dist/changes-5.15.6
new file mode 100644
index 00000000..091adf2c
--- /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/dist/changes-5.15.7 b/dist/changes-5.15.7
new file mode 100644
index 00000000..44c467ca
--- /dev/null
+++ b/dist/changes-5.15.7
@@ -0,0 +1,33 @@
+Qt for Python 5.15.7 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-1647] A crash when constructing a QApplication in an embedded
+                 application has been fixed.
+ - [PYSIDE-1659] QUiLoader restrictions wrt signal/slot connections have been
+                 documented.
+ - [PYSIDE-1681] A hang in QQmlApplicationEngine functions when using a
+                 message handler has been fixed.
+
+****************************************************************************
+*                                  Shiboken2                               *
+****************************************************************************
+
+ - [PYSIDE-1655] A stack-use-after-scope ASAN issue in TypeSystemParser
+                 has been fixed.
+ - [PYSIDE-1686] shiboken has been adapted to LLVM 12.01.
diff --git a/examples/widgets/mainwindows/application/application.py b/examples/widgets/mainwindows/application/application.py
index 8c4626f9..5645a074 100644
--- a/examples/widgets/mainwindows/application/application.py
+++ b/examples/widgets/mainwindows/application/application.py
@@ -189,16 +189,14 @@ class MainWindow(QtWidgets.QMainWindow):
         self.statusBar().showMessage("Ready")
 
     def readSettings(self):
-        settings = QtCore.QSettings("Trolltech", "Application Example")
-        pos = settings.value("pos", QtCore.QPoint(200, 200))
-        size = settings.value("size", QtCore.QSize(400, 400))
-        self.resize(size)
-        self.move(pos)
+        settings = QtCore.QSettings('QtProject', 'Application Example')
+        geometry = settings.value('geometry', QtCore.QByteArray())
+        if geometry.size():
+            self.restoreGeometry(geometry)
 
     def writeSettings(self):
-        settings = QtCore.QSettings("Trolltech", "Application Example")
-        settings.setValue("pos", self.pos())
-        settings.setValue("size", self.size())
+        settings = QtCore.QSettings('QtProject', 'Application Example')
+        settings.setValue('geometry', self.saveGeometry())
 
     def maybeSave(self):
         if self.textEdit.document().isModified():
diff --git a/examples/widgets/mainwindows/mdi/mdi.py b/examples/widgets/mainwindows/mdi/mdi.py
index 9daca826..9eca5fdb 100644
--- a/examples/widgets/mainwindows/mdi/mdi.py
+++ b/examples/widgets/mainwindows/mdi/mdi.py
@@ -42,8 +42,8 @@
 
 """PySide2 port of the widgets/draganddrop/draggabletext example from Qt v5.x, originating from PyQt"""
 
-from PySide2.QtCore import (QFile, QFileInfo, QPoint, QSettings, QSignalMapper,
-        QSaveFile, QSize, QTextStream, Qt)
+from PySide2.QtCore import (QByteArray, QFile, QFileInfo, QPoint, QSettings,
+        QSignalMapper, QSaveFile, QSize, QTextStream, Qt)
 from PySide2.QtGui import QIcon, QKeySequence
 from PySide2.QtWidgets import (QAction, QApplication, QFileDialog, QMainWindow,
         QMdiArea, QMessageBox, QTextEdit, QWidget)
@@ -405,16 +405,14 @@ class MainWindow(QMainWindow):
         self.statusBar().showMessage("Ready")
 
     def readSettings(self):
-        settings = QSettings('Trolltech', 'MDI Example')
-        pos = settings.value('pos', QPoint(200, 200))
-        size = settings.value('size', QSize(400, 400))
-        self.move(pos)
-        self.resize(size)
+        settings = QSettings('QtProject', 'MDI Example')
+        geometry = settings.value('geometry', QByteArray())
+        if geometry.size():
+            self.restoreGeometry(geometry)
 
     def writeSettings(self):
-        settings = QSettings('Trolltech', 'MDI Example')
-        settings.setValue('pos', self.pos())
-        settings.setValue('size', self.size())
+        settings = QSettings('QtProject', 'MDI Example')
+        settings.setValue('geometry', self.saveGeometry())
 
     def activeMdiChild(self):
         activeSubWindow = self.mdiArea.activeSubWindow()
diff --git a/examples/widgets/richtext/textobject/textobject.py b/examples/widgets/richtext/textobject/textobject.py
index b828ea3d..e82ea95d 100644
--- a/examples/widgets/richtext/textobject/textobject.py
+++ b/examples/widgets/richtext/textobject/textobject.py
@@ -42,13 +42,17 @@
 
 """PySide2 port of the widgets/richtext/textobject example from Qt v5.x"""
 
+import os
+
 from PySide2 import QtCore, QtGui, QtWidgets, QtSvg
 
 
-class SvgTextObject(QtCore.QObject, QtGui.QTextObjectInterface):
+class SvgTextObject(QtGui.QPyTextObject):
+    def __init__(self, parent=None):
+        super(SvgTextObject, self).__init__(parent)
 
     def intrinsicSize(self, doc, posInDocument, format):
-        renderer = QtSvg.QSvgRenderer(format.property(Window.SvgData).toByteArray())
+        renderer = QtSvg.QSvgRenderer(format.property(Window.SvgData))
         size = renderer.defaultSize()
 
         if size.height() > 25:
@@ -57,7 +61,7 @@ class SvgTextObject(QtCore.QObject, QtGui.QTextObjectInterface):
         return QtCore.QSizeF(size)
 
     def drawObject(self, painter, rect, doc, posInDocument, format):
-        renderer = QtSvg.QSvgRenderer(format.property(Window.SvgData).toByteArray())
+        renderer = QtSvg.QSvgRenderer(format.property(Window.SvgData))
         renderer.render(painter, rect)
 
 
@@ -80,8 +84,10 @@ class Window(QtWidgets.QWidget):
         file = QtCore.QFile(fileName)
 
         if not file.open(QtCore.QIODevice.ReadOnly):
-            QtWidgets.QMessageBox.warning(self, self.tr("Error Opening File"),
-                    self.tr("Could not open '%1'").arg(fileName))
+            reason = file.errorString()
+            message = "Could not open '{}': {}".format(fileName, reason)
+            QtWidgets.QMessageBox.warning(self, "Error Opening File",
+                                          message.arg(fileName))
 
         svgData = file.readAll()
 
@@ -90,7 +96,7 @@ class Window(QtWidgets.QWidget):
         svgCharFormat.setProperty(Window.SvgData, svgData)
 
         cursor = self.textEdit.textCursor()
-        cursor.insertText(u"\uFFFD", svgCharFormat)
+        cursor.insertText(chr(0xfffc), svgCharFormat)
         self.textEdit.setTextCursor(cursor)
 
     def setupTextObject(self):
@@ -102,8 +108,9 @@ class Window(QtWidgets.QWidget):
         self.fileNameLineEdit = QtWidgets.QLineEdit()
         insertTextObjectButton = QtWidgets.QPushButton(self.tr("Insert Image"))
 
-        self.fileNameLineEdit.setText('./files/heart.svg')
-        QtCore.QObject.connect(insertTextObjectButton, QtCore.SIGNAL('clicked()'), self.insertTextObject)
+        file = os.path.join(os.path.dirname(__file__), 'files', 'heart.svg')
+        self.fileNameLineEdit.setText(file)
+        insertTextObjectButton.clicked.connect(self.insertTextObject)
 
         bottomLayout = QtWidgets.QHBoxLayout()
         bottomLayout.addWidget(fileNameLabel)
diff --git a/product_dependencies.yaml b/product_dependencies.yaml
deleted file mode 100644
index 29c4fb5d..00000000
--- a/product_dependencies.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-dependencies:
-  ../../qt/qt5.git:
-    ref: "5.15.2"
diff --git a/sources/pyside2-tools/pyside_tool.py b/sources/pyside2-tools/pyside_tool.py
index da2d7415..ec27a812 100755
--- a/sources/pyside2-tools/pyside_tool.py
+++ b/sources/pyside2-tools/pyside_tool.py
@@ -38,6 +38,8 @@
 ## $QT_END_LICENSE$
 ##
 #############################################################################
+from __future__ import print_function
+
 import sys
 import os
 import subprocess
@@ -66,7 +68,7 @@ def qt_tool_wrapper(qt_tool, args):
     out, err = proc.communicate()
     if err:
         msg = err.decode("utf-8")
-        print("Error: {}\nwhile executing '{}'".format(msg, ' '.join(cmd)))
+        print(msg, file=sys.stderr)
     sys.exit(proc.returncode)
 
 
diff --git a/sources/pyside2/CMakeLists.txt b/sources/pyside2/CMakeLists.txt
index dc2beded..4336d6cc 100644
--- a/sources/pyside2/CMakeLists.txt
+++ b/sources/pyside2/CMakeLists.txt
@@ -268,7 +268,7 @@ endif ()
 find_program(SPHINX_BUILD sphinx-build)
 find_program(DOT_EXEC dot)
 
-if (QT_SRC_DIR AND SPHINX_BUILD AND DOT_EXEC)
+if (QT_SRC_DIR AND SPHINX_BUILD AND DOT_EXEC AND NOT SKIP_DOCS)
     add_subdirectory(doc)
 else ()
     set(DOCS_TARGET_DISABLED_MESSAGE "apidoc generation targets disabled.")
diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
index 205e4ef0..89f5069d 100644
--- a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
+++ b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
@@ -112,7 +112,6 @@
     <rejection class="QtPrivate"/>
     <rejection class="QtSharedPointer"/>
     <rejection class="QtStringBuilder"/>
-    <rejection class="std"/>
 
   <rejection class="QByteArray" field-name="MaxSize"/>
   <rejection class="QChildEvent" field-name="c"/>
@@ -2608,6 +2607,27 @@
     <modify-function signature="value(const QString&,const QVariant&)const" remove="all"/>
     <add-function signature="value(const QString&, const QVariant& @defaultValue@ = 0, PyObject* @type@ = 0)" return-type="PyObject*">
       <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qsettings-value"/>
+      <inject-documentation mode="append" format="target">
+        Custom overload that adds an optional named parameter to the function ``value()``
+        to automatically cast the type that is being returned by the function.
+
+        An example of this situation could be an ini file that contains
+        the value of a one-element list::
+
+            settings.setValue('var', ['a'])
+
+        The the ini file will be::
+
+            [General]
+            var=a  # we cannot know that this is a list!
+
+        Once we read it, we could specify if we want
+        the default behavior, a str, or to cast the output
+        to a list.
+
+            settings.value('var')  # Will get "a"
+            settings.value('var', type=list)  # Will get ["a"]
+      </inject-documentation>
     </add-function>
   </object-type>
   <object-type name="QEvent"  polymorphic-id-expression="%1->type() == QEvent::None">
diff --git a/sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml b/sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml
index f10aeea3..5dc87a01 100644
--- a/sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml
+++ b/sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml
@@ -119,56 +119,43 @@
           <parent index="this" action="add"/>
         </modify-argument>
       </modify-function>
-      <modify-function signature="addRow(QVector<QtDataVisualization::QBarDataItem>*)">
-        <modify-argument index="1">
-          <parent index="this" action="add"/>
-        </modify-argument>
-      </modify-function>
-      <modify-function signature="addRow(QVector<QtDataVisualization::QBarDataItem>*, const QString&)">
-        <modify-argument index="1">
-          <parent index="this" action="add"/>
-        </modify-argument>
-      </modify-function>
-      <modify-function signature="addRows(const QtDataVisualization::QBarDataArray&)">
-        <modify-argument index="1">
-          <parent index="this" action="add"/>
-        </modify-argument>
-      </modify-function>
-      <modify-function signature="addRows(const QtDataVisualization::QBarDataArray&, const QStringList&)">
-        <modify-argument index="1">
-          <parent index="this" action="add"/>
-        </modify-argument>
-      </modify-function>
-      <modify-function signature="insertRow(int, QVector<QtDataVisualization::QBarDataItem>*)">
-        <modify-argument index="2">
-          <parent index="this" action="add"/>
-        </modify-argument>
-      </modify-function>
-      <modify-function signature="insertRow(int, QVector<QtDataVisualization::QBarDataItem>*, const QString&)">
-        <modify-argument index="2">
-          <parent index="this" action="add"/>
-        </modify-argument>
-      </modify-function>
-      <modify-function signature="insertRows(int, const QtDataVisualization::QBarDataArray&)">
-        <modify-argument index="2">
-          <parent index="this" action="add"/>
-        </modify-argument>
-      </modify-function>
-      <modify-function signature="insertRows(int, const QtDataVisualization::QBarDataArray&, const QStringList&)">
-        <modify-argument index="2">
-          <parent index="this" action="add"/>
-        </modify-argument>
-      </modify-function>
-      <modify-function signature="setRow(int, QVector<QtDataVisualization::QBarDataItem>*)">
-        <modify-argument index="2">
-          <parent index="this" action="add"/>
-        </modify-argument>
-      </modify-function>
-      <modify-function signature="setRow(int, QVector<QtDataVisualization::QBarDataItem>*, const QString&)">
-        <modify-argument index="2">
-          <parent index="this" action="add"/>
-        </modify-argument>
-      </modify-function>
+
+      <!-- PYSIDE-1438: Replace all add/set/insertRow() taking a 'QVector*' by overloads
+           taking 'const QVector &' since an allocated list needs to be passed. -->
+      <modify-function signature="addRow(QVector<QtDataVisualization::QBarDataItem>*)" remove="all"/>
+      <add-function signature="addRow(const QVector<QtDataVisualization::QBarDataItem>&)" return-type="int">
+          <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+                       snippet="dataproxy-addrow"/>
+      </add-function>
+      <modify-function signature="addRow(QVector<QtDataVisualization::QBarDataItem>*,const QString&)" remove="all"/>
+      <add-function signature="addRow(const QVector<QtDataVisualization::QBarDataItem>&,const QString&)"
+                    return-type="int">
+          <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+                       snippet="dataproxy-addrow-string"/>
+      </add-function>
+
+      <modify-function signature="insertRow(int,QVector<QtDataVisualization::QBarDataItem>*)" remove="all"/>
+      <add-function signature="insertRow(int,const QVector<QtDataVisualization::QBarDataItem>&)">
+          <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+                       snippet="dataproxy-insertrow"/>
+      </add-function>
+      <modify-function signature="insertRow(int,QVector<QtDataVisualization::QBarDataItem>*,const QString&)" remove="all"/>
+      <add-function signature="insertRow(int,const QVector<QtDataVisualization::QBarDataItem>&, const QString&)">
+          <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+                       snippet="dataproxy-insertrow-string"/>
+      </add-function>
+
+      <modify-function signature="setRow(int,QVector<QtDataVisualization::QBarDataItem>*)" remove="all"/>
+      <add-function signature="setRow(int,const QVector<QtDataVisualization::QBarDataItem>&)">
+          <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+                       snippet="dataproxy-setrow"/>
+      </add-function>
+      <modify-function signature="setRow(int,QVector<QtDataVisualization::QBarDataItem>*,const QString&)" remove="all"/>
+      <add-function signature="setRow(int,const QVector<QtDataVisualization::QBarDataItem>&,const QString&)">
+          <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+                       snippet="dataproxy-setrow-string"/>
+      </add-function>
+
       <modify-function signature="setRows(int, const QtDataVisualization::QBarDataArray&)">
         <modify-argument index="2">
           <parent index="this" action="add"/>
@@ -182,7 +169,13 @@
     </object-type>
     <object-type name="QCustom3DItem"/>
     <object-type name="QCustom3DLabel"/>
-    <object-type name="QCustom3DVolume"/>
+    <object-type name="QCustom3DVolume">
+        <modify-function signature="setTextureData(QVector<uchar>*)" remove="all"/>
+        <add-function signature="setTextureData(const QVector<uchar>&)">
+            <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+                         snippet="qcustom3dvolume-settexturedata"/>
+        </add-function>
+    </object-type>
     <object-type name="QHeightMapSurfaceDataProxy"/>
     <object-type name="QItemModelBarDataProxy">
       <enum-type name="MultiMatchBehavior"/>
@@ -251,21 +244,27 @@
     </object-type>
     <value-type name="QSurfaceDataItem"/>
     <object-type name="QSurfaceDataProxy">
-      <modify-function signature="addRow(QVector<QtDataVisualization::QSurfaceDataItem>*)">
-        <modify-argument index="1">
-          <parent index="this" action="add"/>
-        </modify-argument>
-      </modify-function>
-      <modify-function signature="insertRow(int, QVector<QtDataVisualization::QSurfaceDataItem>*)">
-        <modify-argument index="2">
-          <parent index="this" action="add"/>
-        </modify-argument>
-      </modify-function>
-      <modify-function signature="setRow(int, QVector<QtDataVisualization::QSurfaceDataItem>*)">
-        <modify-argument index="2">
-          <parent index="this" action="add"/>
-        </modify-argument>
-      </modify-function>
+
+    <!-- PYSIDE-1438: Replace all add/set/insertRow() taking a 'QVector*' by overloads
+         taking 'const QVector &' since an allocated list needs to be passed. -->
+    <modify-function signature="addRow(QVector<QtDataVisualization::QSurfaceDataItem>*)" remove="all"/>
+    <add-function signature="addRow(const QVector<QtDataVisualization::QSurfaceDataItem>&)" return-type="int">
+        <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+                     snippet="dataproxy-addrow"/>
+    </add-function>
+
+    <modify-function signature="insertRow(int,QVector<QtDataVisualization::QSurfaceDataItem>*)" remove="all"/>
+    <add-function signature="insertRow(int,const QVector<QtDataVisualization::QSurfaceDataItem>&)">
+        <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+                     snippet="dataproxy-insertrow"/>
+    </add-function>
+
+    <modify-function signature="setRow(int,QVector<QtDataVisualization::QSurfaceDataItem>*)" remove="all"/>
+    <add-function signature="setRow(int,const QVector<QtDataVisualization::QSurfaceDataItem>&)">
+        <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+                     snippet="dataproxy-setrow"/>
+    </add-function>
+
       <modify-function signature="resetArray(QtDataVisualization::QSurfaceDataArray*)">
         <modify-argument index="1">
           <parent index="this" action="add"/>
diff --git a/sources/pyside2/PySide2/QtGui/CMakeLists.txt b/sources/pyside2/PySide2/QtGui/CMakeLists.txt
index c4a38a18..88d8be93 100644
--- a/sources/pyside2/PySide2/QtGui/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtGui/CMakeLists.txt
@@ -100,7 +100,7 @@ ${QtGui_GEN_DIR}/qopengldebugmessage_wrapper.cpp
 ${QtGui_GEN_DIR}/qopenglextrafunctions_wrapper.cpp
 ${QtGui_GEN_DIR}/qopenglframebufferobjectformat_wrapper.cpp
 ${QtGui_GEN_DIR}/qopenglfunctions_wrapper.cpp
-# Compile error on Windows: ${QtGui_GEN_DIR}/qopenglpaintdevice_wrapper.cpp
+${QtGui_GEN_DIR}/qopenglpaintdevice_wrapper.cpp
 ${QtGui_GEN_DIR}/qopenglpixeltransferoptions_wrapper.cpp
 ${QtGui_GEN_DIR}/qopenglshaderprogram_wrapper.cpp
 ${QtGui_GEN_DIR}/qopengltexture_wrapper.cpp
diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml
index 04abbae5..e66ee48c 100644
--- a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml
+++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml
@@ -643,6 +643,16 @@
         <define-ownership class="target" owner="default"/>
       </modify-argument>
     </modify-function>
+    <modify-function signature="currentTable()const">
+      <modify-argument index="return">
+        <define-ownership class="target" owner="default"/>
+      </modify-argument>
+    </modify-function>
+    <modify-function signature="currentList()const">
+      <modify-argument index="return">
+        <define-ownership class="target" owner="default"/>
+      </modify-argument>
+    </modify-function>
     <modify-function signature="insertTable(int,int,const QTextTableFormat &)">
       <modify-argument index="return">
         <define-ownership class="target" owner="default"/>
@@ -758,6 +768,8 @@
       <include file-name="QStringList" location="global"/>
       <include file-name="QMatrix" location="global"/>
     </extra-includes>
+    <inject-code class="native" position="beginning"
+                 file="../glue/qtgui.cpp" snippet="qimage-decref-image-data"/>
 
     <modify-function signature="load(const QString&, const char*)" allow-thread="yes"/>
     <modify-function signature="load(QIODevice*,const char*)" allow-thread="yes"/>
@@ -1760,6 +1772,11 @@
       </modify-argument>
       <inject-code class="target" position="end" file="../glue/qtgui.cpp" snippet="qclipboard-text"/>
     </modify-function>
+    <modify-function signature="mimeData(QClipboard::Mode)const">
+      <modify-argument index="return">
+        <define-ownership class="target" owner="default"/>
+      </modify-argument>
+    </modify-function>
   </object-type>
   <object-type name="QPaintEngineState">
     <extra-includes>
@@ -1871,18 +1888,23 @@
     <modify-function signature="drawRects(const QRect*,int)" remove="all"/>
     <modify-function signature="drawRects(const QRectF*,int)" remove="all"/>
     <!-- ### -->
+    <!-- PYSIDE-1540: Preferably use the QPolygon overloads first to avoid
+         a costly sequence type check on QPolygon. -->
     <modify-function signature="drawPoints(const QPoint*,int)" remove="all"/>
-    <add-function signature="drawPoints(QVector<QPoint>)">
+    <add-function signature="drawPoints(QVector<QPoint>)" overload-number="2">
         <inject-code>
             <insert-template name="qpainter_drawlist"/>
         </inject-code>
     </add-function>
     <modify-function signature="drawPoints(const QPointF*,int)" remove="all"/>
-    <add-function signature="drawPoints(QVector<QPointF>)">
+    <add-function signature="drawPoints(QVector<QPointF>)" overload-number="3">
         <inject-code>
             <insert-template name="qpainter_drawlist"/>
         </inject-code>
     </add-function>
+    <modify-function signature="drawPoints(const QPolygon&)" overload-number="0"/>
+    <modify-function signature="drawPoints(const QPolygonF&)" overload-number="1"/>
+
     <modify-function signature="drawPolygon(const QPoint*,int,Qt::FillRule)" remove="all"/>
     <add-function signature="drawPolygon(QVector<QPoint>,Qt::FillRule)">
         <inject-code file="../glue/qtgui.cpp" snippet="qpainter-drawpolygon"/>
@@ -2601,6 +2623,10 @@
   </object-type>
   <object-type name="QOpenGLContext">
     <enum-type name="OpenGLModuleType"/>
+    <modify-function signature="versionFunctions(const QOpenGLVersionProfile&) const">
+    <inject-code class="target" position="beginning" file="../glue/qtgui.cpp"
+                 snippet="qopenglcontext-versionfunctions"/>
+    </modify-function>
   </object-type>
   <object-type name="QOpenGLContextGroup" since="5.0"/>
   <object-type name="QOpenGLDebugLogger" since="5.1">
@@ -2616,9 +2642,7 @@
     <enum-type name="FramebufferRestorePolicy" since="5.7"/>
   </object-type>
   <value-type name="QOpenGLFramebufferObjectFormat"/>
-  <!-- Compile error on Windows: QOpenGLPaintDevice::QOpenGLPaintDevice(const QOpenGLPaintDevice &)': attempting to reference a deleted function
   <object-type name="QOpenGLPaintDevice" since="5.0"/>
-  -->
   <object-type name="QOpenGLExtraFunctions" since="5.6">
       <!-- Exlusions due to compile errors -->
       <modify-function signature="glEndTransformFeedback()" remove="all"/>
@@ -2835,11 +2859,20 @@
           <modify-argument index="return">
               <replace-type modified-type="QString"/>
           </modify-argument>
-          <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qstring-return"/>
+          <inject-code class="target" position="end" file="../glue/qtgui.cpp"
+                       snippet="glgetstring-return"/>
       </modify-function>
   </object-type>
   <object-type name="QOpenGLFunctions" since="5.0">
       <enum-type name="OpenGLFeature" flags="OpenGLFeatures"/>
+      <add-function signature="glGetShaderSource(unsigned int @shader@)" return-type="const char *">
+          <inject-code class="target" position="beginning" file="../glue/qtgui.cpp"
+                       snippet="glgetshadersource"/>
+      </add-function>
+      <add-function signature="glShaderSource(unsigned int @shader@,const QString & @source@)">
+          <inject-code class="target" position="beginning" file="../glue/qtgui.cpp"
+                       snippet="glshadersource"/>
+      </add-function>
       <modify-function signature="glGetAttachedShaders(unsigned int,int,int*,unsigned int*)">
           <modify-argument index="3"><array/></modify-argument>
           <modify-argument index="4"><array/></modify-argument>
diff --git a/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml b/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml
index dc60a509..d91f0780 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/QtOpenGLFunctions/CMakeLists.txt b/sources/pyside2/PySide2/QtOpenGLFunctions/CMakeLists.txt
index 383afb68..62ed669c 100644
--- a/sources/pyside2/PySide2/QtOpenGLFunctions/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtOpenGLFunctions/CMakeLists.txt
@@ -42,7 +42,8 @@ else()
          ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_4_compatibility_wrapper.cpp
          ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_4_core_wrapper.cpp
          ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_5_compatibility_wrapper.cpp
-         ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_5_core_wrapper.cpp)
+         ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_5_core_wrapper.cpp
+         ${QtOpenGLFunctions_GEN_DIR}/qopenglversionfunctionsfactory_wrapper.cpp)
    message(STATUS "Qt${QT_MAJOR_VERSION}OpenGLFunctions: Adding Desktop OpenGL classes")
 endif()
 
@@ -71,3 +72,6 @@ create_pyside_module(NAME QtOpenGLFunctions
                      SOURCES QtOpenGLFunctions_SRC
                      TYPESYSTEM_NAME ${QtOpenGLFunctions_BINARY_DIR}/typesystem_openglfunctions.xml
                      DROPPED_ENTRIES QtOpenGLFunctions_DROPPED_ENTRIES)
+
+install(FILES ${pyside2_SOURCE_DIR}/qopenglversionfunctionsfactory.h
+        DESTINATION include/PySide2/QtOpenGLFunctions)
diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/QtOpenGLFunctions_global.post.h.in b/sources/pyside2/PySide2/QtOpenGLFunctions/QtOpenGLFunctions_global.post.h.in
index 6c8c7708..e43bc2b8 100644
--- a/sources/pyside2/PySide2/QtOpenGLFunctions/QtOpenGLFunctions_global.post.h.in
+++ b/sources/pyside2/PySide2/QtOpenGLFunctions/QtOpenGLFunctions_global.post.h.in
@@ -59,3 +59,5 @@
 #if QT_CONFIG(opengles2)
 #  include <QtGui/qopenglfunctions_es2.h>
 #endif
+
+#include "qopenglversionfunctionsfactory.h" // PySide class
diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions.xml
index 1d5b08ed..edb27136 100644
--- a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions.xml
+++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions.xml
@@ -404,6 +404,15 @@
       &openglfunctions_modifications1_0;
       &openglfunctions_modifications1_1;
   </object-type>
+
+  <object-type name="QOpenGLVersionFunctionsFactory">
+      <modify-function signature="get(const QOpenGLVersionProfile&,QOpenGLContext*)"
+                       return-type="QAbstractOpenGLFunctions*">
+          <inject-code class="target" position="beginning" file="../glue/qtopenglfunctions.cpp"
+                       snippet="qopenglversionfunctionsfactory-get"/>
+      </modify-function>
+  </object-type>
+
   <suppress-warning text="^There's no user provided way.*QOpenGLFunctions_\d_\d.*::glIndex.*$"/>
 
 </typesystem>
diff --git a/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp b/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp
index 2b60c5c7..93133984 100644
--- a/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp
+++ b/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp
@@ -470,13 +470,13 @@ PyTypeObject *QtQml_VolatileBoolTypeF(void)
 }
 
 static const char *PropertyList_SignatureStrings[] = {
-    "PySide2.QtQml.ListProperty(type:type,append:typing.Callable,"
+    "PySide2.QtQml.ListProperty(self,type:type,append:typing.Callable,"
         "at:typing.Callable=None,clear:typing.Callable=None,count:typing.Callable=None)",
     nullptr}; // Sentinel
 
 static const char *VolatileBool_SignatureStrings[] = {
-    "PySide2.QtQml.VolatileBool.get()->bool",
-    "PySide2.QtQml.VolatileBool.set(a:object)",
+    "PySide2.QtQml.VolatileBool.get(self)->bool",
+    "PySide2.QtQml.VolatileBool.set(self,a:object)",
     nullptr}; // Sentinel
 
 void PySide::initQmlSupport(PyObject *module)
diff --git a/sources/pyside2/PySide2/QtQml/typesystem_qml.xml b/sources/pyside2/PySide2/QtQml/typesystem_qml.xml
index 0a12d44c..c237a9d5 100644
--- a/sources/pyside2/PySide2/QtQml/typesystem_qml.xml
+++ b/sources/pyside2/PySide2/QtQml/typesystem_qml.xml
@@ -116,7 +116,14 @@
     <object-type name="QQmlAbstractUrlInterceptor">
         <enum-type name="DataType"/>
     </object-type>
-    <object-type name="QQmlApplicationEngine"/>
+    <object-type name="QQmlApplicationEngine">
+        <!-- PYSIDE-1681: QQmlApplicationEngine constructor, load() and similar need
+             allow-thread in case there is a message handler installed
+             (qInstallMessageHandler) -->
+        <modify-function signature="^QQmlApplicationEngine\(.*\)$" allow-thread="yes"/>
+        <modify-function signature="load(const QString &)" allow-thread="yes"/>
+        <modify-function signature="load(const QUrl &)" allow-thread="yes"/>
+    </object-type>
     <object-type name="QQmlComponent">
         <enum-type name="CompilationMode"/>
         <enum-type name="Status"/>
diff --git a/sources/pyside2/PySide2/QtTest/CMakeLists.txt b/sources/pyside2/PySide2/QtTest/CMakeLists.txt
index 04bb28cc..50b9e3e3 100644
--- a/sources/pyside2/PySide2/QtTest/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtTest/CMakeLists.txt
@@ -2,6 +2,7 @@ project(QtTest)
 
 set(QtTest_SRC
 ${QtTest_GEN_DIR}/qtest_pysideqtoucheventsequence_wrapper.cpp
+${QtTest_GEN_DIR}/qabstractitemmodeltester_wrapper.cpp
 ${QtTest_GEN_DIR}/qtest_wrapper.cpp
 # module is always needed
 ${QtTest_GEN_DIR}/qttest_module_wrapper.cpp
diff --git a/sources/pyside2/PySide2/QtTest/typesystem_test.xml b/sources/pyside2/PySide2/QtTest/typesystem_test.xml
index f7facaf7..5aa45feb 100644
--- a/sources/pyside2/PySide2/QtTest/typesystem_test.xml
+++ b/sources/pyside2/PySide2/QtTest/typesystem_test.xml
@@ -102,6 +102,10 @@
   </object-type>
   ^^^ this is now moved into QtGui -->
 
+  <object-type name="QAbstractItemModelTester">
+      <enum-type name="FailureReportingMode"/>
+  </object-type>
+
   <namespace-type name="QTest">
     <!-- Qt5: private <enum-type name="AttributeIndex" since="4.6"/> -->
     <enum-type name="KeyAction"/>
diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
index 155591b0..91458e31 100644
--- a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
+++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
@@ -1276,6 +1276,10 @@
       <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="removeownership-1"/>
     </modify-function>
 
+    <modify-function signature="replaceWidget(QWidget*,QWidget*,QFlags<Qt::FindChildOption>)">
+       <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-2"/>
+    </modify-function>
+
     <modify-function signature="parentWidget()const">
       <modify-argument index="this">
         <parent index="return" action="add"/>
diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp
index 306a2239..78de3d5d 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/glue/qtdatavisualization.cpp b/sources/pyside2/PySide2/glue/qtdatavisualization.cpp
index 119d79a4..ce5aa693 100644
--- a/sources/pyside2/PySide2/glue/qtdatavisualization.cpp
+++ b/sources/pyside2/PySide2/glue/qtdatavisualization.cpp
@@ -40,3 +40,40 @@
 // @snippet releaseownership
 Shiboken::Object::releaseOwnership(%PYARG_1);
 // @snippet releaseownership
+
+// @snippet qcustom3dvolume-settexturedata
+using VectorType = decltype(%1);
+%CPPSELF.setTextureData(new VectorType(%1));
+// @snippet qcustom3dvolume-settexturedata
+
+// @snippet dataproxy-addrow
+using VectorType = decltype(%1);
+%RETURN_TYPE %0 = %CPPSELF.addRow(new VectorType(%1));
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet dataproxy-addrow
+
+// @snippet dataproxy-addrow-string
+using VectorType = decltype(%1);
+%RETURN_TYPE %0 = %CPPSELF.addRow(new VectorType(%1), %2);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet dataproxy-addrow-string
+
+// @snippet dataproxy-insertrow
+using VectorType = decltype(%2);
+%CPPSELF.insertRow(%1, new VectorType(%2));
+// @snippet dataproxy-insertrow
+
+// @snippet dataproxy-insertrow-string
+using VectorType = decltype(%2);
+%CPPSELF.insertRow(%1, new VectorType(%2), %3);
+// @snippet dataproxy-insertrow-string
+
+// @snippet dataproxy-setrow
+using VectorType = decltype(%2);
+%CPPSELF.setRow(%1, new VectorType(%2));
+// @snippet dataproxy-setrow
+
+// @snippet dataproxy-setrow-string
+using VectorType = decltype(%2);
+%CPPSELF.setRow(%1, new VectorType(%2), %3);
+// @snippet dataproxy-setrow-string
diff --git a/sources/pyside2/PySide2/glue/qtgui.cpp b/sources/pyside2/PySide2/glue/qtgui.cpp
index a6b45b7c..00d04578 100644
--- a/sources/pyside2/PySide2/glue/qtgui.cpp
+++ b/sources/pyside2/PySide2/glue/qtgui.cpp
@@ -41,6 +41,53 @@
  * INJECT CODE
  ********************************************************************/
 
+// @snippet qopenglcontext-versionfunctions
+
+// %CPPSELF.%FUNCTION_NAME(%1, %2); Pretend to shiboken we call the function
+
+// Import QtOpenGLFunctions and call the factory function
+// QOpenGLVersionFunctionsFactory.get()
+PyObject *module = PyImport_ImportModule("PySide2.QtOpenGLFunctions");
+if (module == nullptr)
+    return nullptr;
+PyObject *loc = PyModule_GetDict(module);
+static PyObject *const factoryName =
+    Shiboken::String::createStaticString("QOpenGLVersionFunctionsFactory");
+auto factory = PyDict_GetItem(loc, factoryName);
+if (factory == nullptr)
+    return nullptr;
+
+static PyObject *const getMethod = Shiboken::String::createStaticString("get");
+%PYARG_0 = PyObject_CallMethodObjArgs(factory, getMethod, pyArgs[0], %PYSELF,
+                                       nullptr);
+// @snippet qopenglcontext-versionfunctions
+
+// @snippet glgetshadersource
+GLsizei bufSize = 4096;
+GLsizei length = bufSize - 1;
+QByteArray buffer;
+for (; length == bufSize - 1; bufSize += 4096) {
+    buffer.resize(qsizetype(bufSize));
+    %CPPSELF->%FUNCTION_NAME(%1, bufSize, &length, buffer.data());
+    if (%CPPSELF->glGetError() != GL_NO_ERROR) {
+        buffer.clear();
+        break;
+    }
+}
+auto *data = buffer.constData();
+%PYARG_0 = %CONVERTTOPYTHON[char *](data);
+// @snippet glgetshadersource
+
+// @snippet glshadersource
+const QByteArray buffer = %2.toUtf8();
+const char *sources[] = {buffer.constData()};
+%CPPSELF->%FUNCTION_NAME(%1, 1, sources, nullptr);
+// @snippet glshadersource
+
+// @snippet glgetstring-return
+%PYARG_0 = %CONVERTTOPYTHON[const char *](%0);
+// @snippet glgetstring-return
+
 // @snippet qtransform-quadtoquad
 QTransform _result;
 if (QTransform::quadToQuad(%1, %2, _result)) {
@@ -143,6 +190,16 @@ for (int i = 0, i_max = %CPPSELF.count(); i < i_max; ++i){
 %0 = new %TYPE(QPixmap::fromImage(%1));
 // @snippet qpixmap
 
+// @snippet qimage-decref-image-data
+static void imageDecrefDataHandler(void *data)
+{
+    // Avoid "Python memory allocator called without holding the GIL"
+    auto state = PyGILState_Ensure();
+    Py_DECREF(reinterpret_cast<PyObject *>(data));
+    PyGILState_Release(state);
+}
+// @snippet qimage-decref-image-data
+
 // @snippet qimage-constbits
 %PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.byteCount());
 // @snippet qimage-constbits
diff --git a/sources/pyside2/PySide2/glue/qtopenglfunctions.cpp b/sources/pyside2/PySide2/glue/qtopenglfunctions.cpp
new file mode 100644
index 00000000..c839ae44
--- /dev/null
+++ b/sources/pyside2/PySide2/glue/qtopenglfunctions.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// @snippet qopenglversionfunctionsfactory-get
+QAbstractOpenGLFunctions *af = %CPPSELF.%FUNCTION_NAME(%1, %2);
+if (auto *f = dynamic_cast<QOpenGLFunctions_4_5_Core *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_5_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_5_Compatibility *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_5_Compatibility *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_4_Core *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_4_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_4_Compatibility *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_4_Compatibility *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_3_Core *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_3_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_2_Core *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_2_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_1_Core *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_1_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_0_Core *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_0_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_0_Compatibility *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_0_Compatibility *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_3_3_Core *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_3_3_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_3_3_Compatibility *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_3_3_Compatibility *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_3_2_Core *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_3_2_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_3_2_Compatibility *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_3_2_Compatibility *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_3_1 *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_3_1 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_3_0 *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_3_0 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_2_1 *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_2_1 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_2_0 *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_2_0 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_1_5 *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_1_5 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_1_4 *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_1_4 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_1_3 *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_1_3 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_1_2 *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_1_2 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_1_1 *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_1_1 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_1_0 *>(af)) {
+    %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_1_0 *](f);
+} else {
+    QString message;
+    QDebug(&message) << "No OpenGL functions could be obtained for" << %1;
+    PyErr_SetString(PyExc_RuntimeError, message.toUtf8().constData());
+    %PYARG_0 = Py_None;
+}
+// @snippet qopenglversionfunctionsfactory-get
diff --git a/sources/pyside2/PySide2/qopenglversionfunctionsfactory.h b/sources/pyside2/PySide2/qopenglversionfunctionsfactory.h
new file mode 100644
index 00000000..27b8373f
--- /dev/null
+++ b/sources/pyside2/PySide2/qopenglversionfunctionsfactory.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGLVERSIONFUNCTIONSFACTORY_H
+#define QOPENGLVERSIONFUNCTIONSFACTORY_H
+
+#include <QtGui/QOpenGLContext>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLVersionProfile;
+
+class QOpenGLVersionFunctionsFactory
+{
+public:
+    static QAbstractOpenGLFunctions *get(const QOpenGLVersionProfile &versionProfile,
+                                         QOpenGLContext *context)
+    {
+        return context
+            ? context->versionFunctions(versionProfile)
+            : nullptr;
+    }
+};
+
+QT_END_NAMESPACE
+
+#endif // QOPENGLVERSIONFUNCTIONSFACTORY_H
diff --git a/sources/pyside2/PySide2/support/generate_pyi.py b/sources/pyside2/PySide2/support/generate_pyi.py
index d71ee338..9eb84de7 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
@@ -131,6 +132,7 @@ class Formatter(Writer):
         self.optional_replacer = optional_replacer
         # self.level is maintained by enum_sig.py
         # self.after_enum() is a one-shot set by enum_sig.py .
+        # self.is_method() is true for non-plain functions.
 
     @contextmanager
     def module(self, mod_name):
@@ -187,7 +189,7 @@ class Formatter(Writer):
         yield key
 
     def _function(self, func_name, signature, spaces):
-        if "self" not in tuple(signature.parameters.keys()):
+        if self.is_method() and "self" not in tuple(signature.parameters.keys()):
             self.print('{spaces}@staticmethod'.format(**locals()))
         signature = self.optional_replacer(signature)
         self.print('{spaces}def {func_name}{signature}: ...'.format(**locals()))
@@ -200,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]
 
@@ -227,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")
@@ -306,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 6d02428a..b5d1f02e 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, &ok_, %9);
+        %RETURN_TYPE retval_;
+        Py_BEGIN_ALLOW_THREADS
+        retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, %7, &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, &ok_, %9, %10);
+        %RETURN_TYPE retval_;
+        Py_BEGIN_ALLOW_THREADS
+        retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, %7, &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, &ok_, %8);
+        %RETURN_TYPE retval_;
+        Py_BEGIN_ALLOW_THREADS
+        retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, &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, &ok_, %7);
+        %RETURN_TYPE retval_;
+        Py_BEGIN_ALLOW_THREADS
+        retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, &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, &ok_, %6, %7);
+        %RETURN_TYPE retval_;
+        Py_BEGIN_ALLOW_THREADS
+        retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, &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/PySide2/templates/gui_common.xml b/sources/pyside2/PySide2/templates/gui_common.xml
index a139a5fe..1a740679 100644
--- a/sources/pyside2/PySide2/templates/gui_common.xml
+++ b/sources/pyside2/PySide2/templates/gui_common.xml
@@ -80,8 +80,9 @@
     </template>
 
     <template name="qimage_buffer_constructor">
+        Py_INCREF(%PYARG_1);
         auto ptr = reinterpret_cast<uchar*>(Shiboken::Buffer::getPointer(%PYARG_1));
-        %0 = new %TYPE(ptr, %ARGS);
+        %0 = new %TYPE(ptr, %ARGS, imageDecrefDataHandler, %PYARG_1);
     </template>
 
     <template name="qcolor_repr">
diff --git a/sources/pyside2/doc/CMakeLists.txt b/sources/pyside2/doc/CMakeLists.txt
index ab5d694e..950e4868 100644
--- a/sources/pyside2/doc/CMakeLists.txt
+++ b/sources/pyside2/doc/CMakeLists.txt
@@ -152,6 +152,7 @@ configure_file("conf.py.in" "rst/conf.py" @ONLY)
 add_custom_target("docrsts"
     COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/rst
     COMMAND Shiboken2::shiboken2 --generator-set=qtdoc ${docHeader}
+            --enable-pyside-extensions
             --include-paths="${QT_INCLUDE_DIR}${PATH_SEP}${pyside2_SOURCE_DIR}${PATH_SEP}${TS_ROOT}"
             --api-version=${SUPPORTED_QT_VERSION}
             --typesystem-paths="${QDOC_TYPESYSTEM_PATH}"
diff --git a/sources/pyside2/doc/extras/QtCore.Property.rst b/sources/pyside2/doc/extras/QtCore.Property.rst
index a10c9f80..6bcfc265 100644
--- a/sources/pyside2/doc/extras/QtCore.Property.rst
+++ b/sources/pyside2/doc/extras/QtCore.Property.rst
@@ -1,5 +1,6 @@
 .. currentmodule:: PySide2.QtCore
 .. _Property:
+
 Property
 ********
 
@@ -8,7 +9,9 @@ Detailed Description
 
 The Property function lets you declare properties that
 behave both as Qt and Python properties, and have their
-setters and getters defined as Python functions.
+getters and setters defined as Python functions.
+
+They are equivalent to the ``Q_PROPERTY`` macro in the `Qt Docs`_.
 
 Here is an example that illustrates how to use this
 function:
@@ -19,14 +22,14 @@ function:
     from PySide2.QtCore import QObject, Property
 
     class MyObject(QObject):
-        def __init__(self,startval=42):
+        def __init__(self, startval=42):
             QObject.__init__(self)
             self.ppval = startval
 
         def readPP(self):
             return self.ppval
 
-        def setPP(self,val):
+        def setPP(self, val):
             self.ppval = val
 
         pp = Property(int, readPP, setPP)
@@ -35,6 +38,68 @@ function:
     obj.pp = 47
     print(obj.pp)
 
+The full options for ``QtCore.Property`` can be found with ``QtCore.Property.__doc__``:
+
+.. code-block::
+
+   Property(self, type: type,
+            fget: Optional[Callable] = None,
+            fset: Optional[Callable] = None,
+            freset: Optional[Callable] = None,
+            fdel: Optional[Callable] = None,
+            doc: str = '', notify: Optional[Callable] = None,
+            designable: bool = True, scriptable: bool = True,
+            stored: bool = True, user: bool = False,
+            constant: bool = False, final: bool = False) -> PySide2.QtCore.Property
+
+Normally, only ``type``, ``fget``and ``fset`` are used.
+
+
+Properties compared with Python properties
+------------------------------------------
+
+``Python`` has property objects very similar to ``QtCore.Property``.
+Despite the fact that the latter has an extra ``freset`` function, the usage
+of properties is almost the same. The main difference is that ``QtCore.Property``
+requires a ``type`` parameter.
+
+In the above example, the following lines would be equivalent properties:
+
+.. code-block::
+
+        pp = QtCore.Property(int, readPP, setPP)    # PySide version
+        pp = property(readPP, setPP)                # Python version
+
+As you know from the `Python Docs`_, ``Python`` allows to break the property
+creation into multiple steps, using the decorator syntax. We can do this in
+``PySide`` as well:
+
+.. code-block::
+   :linenos:
+
+    from PySide2.QtCore import QObject, Property
+
+    class MyObject(QObject):
+        def __init__(self, startval=42):
+            QObject.__init__(self)
+            self.ppval = startval
+
+        @Property(int)
+        def pp(self):
+            return self.ppval
+
+        @pp.setter
+        def pp(self, val):
+            self.ppval = val
+
+    obj = MyObject()
+    obj.pp = 47
+    print(obj.pp)
+
+Please be careful here: The two ``Python`` functions have the same name, intentionally.
+This is needed to let ``Python`` know that these functions belong to the same property.
+
+
 Properties in QML expressions
 -----------------------------
 
@@ -60,3 +125,6 @@ example illustrating how to do this:
             pass
 
         name = Property(str, _name, notify=name_changed)
+
+.. _`Python Docs`:  https://docs.python.org/3/library/functions.html?highlight=property#property
+.. _`Qt Docs`:  https://doc.qt.io/qt-5/properties.html
diff --git a/sources/pyside2/doc/quickstart.rst b/sources/pyside2/doc/quickstart.rst
index 87471a8a..db2e9328 100644
--- a/sources/pyside2/doc/quickstart.rst
+++ b/sources/pyside2/doc/quickstart.rst
@@ -52,12 +52,6 @@ constructs to print version information::
     # Prints the Qt version used to compile PySide2
     print(PySide2.QtCore.__version__)
 
-.. note::
-
-    As it happened in 5.14.2, PySide had a couple of new releases to fix
-    issues in 5.14.2, adding yet another version level. In that case, you
-    will have different versions being shown for Qt and PySide.
-
 Create a Simple Application
 ---------------------------
 
diff --git a/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst b/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst
index 98238462..8da69819 100644
--- a/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst
+++ b/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst
@@ -185,3 +185,11 @@ command prompt:
 .. code-block:: python
 
     python main.py
+
+.. note::
+
+    `QUiLoader` uses connect() calls taking the function signatures as string
+    arguments for signal/slot connections.
+    It is thus unable to handle Python types like `str` or `list` from
+    custom widgets written in Python since these types are internally mapped
+    to different C++ types.
diff --git a/sources/pyside2/libpyside/feature_select.cpp b/sources/pyside2/libpyside/feature_select.cpp
index 6a21d168..3011b358 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;
 }
 
@@ -405,6 +408,8 @@ static inline PyObject *SelectFeatureSet(PyTypeObject *type)
             if (!SelectFeatureSetSubtype(sub_type, select_id))
                 break;
         }
+        // PYSIDE-1436: Clear all caches for the type and subtypes.
+        PyType_Modified(type);
     }
     return type->tp_dict;
 }
@@ -418,6 +423,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 +458,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 +478,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/globalreceiverv2.cpp b/sources/pyside2/libpyside/globalreceiverv2.cpp
index 0377f769..b16a923d 100644
--- a/sources/pyside2/libpyside/globalreceiverv2.cpp
+++ b/sources/pyside2/libpyside/globalreceiverv2.cpp
@@ -1,6 +1,6 @@
 /****************************************************************************
 **
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
 ** Contact: https://www.qt.io/licensing/
 **
 ** This file is part of Qt for Python.
@@ -108,14 +108,14 @@ DynamicSlotDataV2::DynamicSlotDataV2(PyObject *callback, GlobalReceiverV2 *paren
         //monitor class from method lifetime
         m_weakRef = WeakRef::create(m_pythonSelf, DynamicSlotDataV2::onCallbackDestroyed, this);
 
-        m_hash = QByteArray::number((qlonglong)PyObject_Hash(m_callback))
-                 + QByteArray::number((qlonglong)PyObject_Hash(m_pythonSelf));
-
+        // PYSIDE-1422: Avoid hash on self which might be unhashable.
+        m_hash = QByteArray::number(static_cast<qlonglong>(PyObject_Hash(m_callback)))
+                 + QByteArray::number(reinterpret_cast<qlonglong>(m_pythonSelf));
     } else {
         m_callback = callback;
         Py_INCREF(m_callback);
 
-        m_hash = QByteArray::number((qlonglong)PyObject_Hash(m_callback));
+        m_hash = QByteArray::number(static_cast<qlonglong>(PyObject_Hash(m_callback)));
     }
 }
 
@@ -128,10 +128,11 @@ QByteArray DynamicSlotDataV2::hash(PyObject *callback)
 {
     Shiboken::GilState gil;
     if (PyMethod_Check(callback)) {
-        return  QByteArray::number((qlonglong)PyObject_Hash(PyMethod_GET_FUNCTION(callback)))
-              + QByteArray::number((qlonglong)PyObject_Hash(PyMethod_GET_SELF(callback)));
+        // PYSIDE-1422: Avoid hash on self which might be unhashable.
+        return  QByteArray::number(static_cast<qlonglong>(PyObject_Hash(PyMethod_GET_FUNCTION(callback))))
+              + QByteArray::number(reinterpret_cast<qlonglong>(PyMethod_GET_SELF(callback)));
     }
-    return QByteArray::number(qlonglong(PyObject_Hash(callback)));
+    return QByteArray::number(static_cast<qlonglong>(PyObject_Hash(callback)));
 }
 
 PyObject *DynamicSlotDataV2::callback()
diff --git a/sources/pyside2/libpyside/pyside.cpp b/sources/pyside2/libpyside/pyside.cpp
index 219b99d4..7b01c5b8 100644
--- a/sources/pyside2/libpyside/pyside.cpp
+++ b/sources/pyside2/libpyside/pyside.cpp
@@ -58,7 +58,6 @@
 #include <sbkconverter.h>
 #include <sbkstring.h>
 #include <sbkstaticstrings.h>
-#include <qapp_macro.h>
 
 #include <QtCore/QByteArray>
 #include <QtCore/QCoreApplication>
@@ -121,38 +120,36 @@ static bool _setProperty(PyObject *qObj, PyObject *name, PyObject *value, bool *
     return true;
 }
 
-bool fillQtProperties(PyObject *qObj, const QMetaObject *metaObj, PyObject *kwds, const char **blackList, unsigned int blackListSize)
+bool fillQtProperties(PyObject *qObj, const QMetaObject *metaObj, PyObject *kwds)
 {
 
     PyObject *key, *value;
     Py_ssize_t pos = 0;
 
     while (PyDict_Next(kwds, &pos, &key, &value)) {
-        if (!blackListSize || !std::binary_search(blackList, blackList + blackListSize, std::string(Shiboken::String::toCString(key)))) {
-            QByteArray propName(Shiboken::String::toCString(key));
-            bool accept = false;
-            if (metaObj->indexOfProperty(propName) != -1) {
-                if (!_setProperty(qObj, key, value, &accept))
-                    return false;
-            } else {
-                propName.append("()");
-                if (metaObj->indexOfSignal(propName) != -1) {
-                    accept = true;
-                    propName.prepend('2');
-                    if (!PySide::Signal::connect(qObj, propName, value))
-                        return false;
-                }
-            }
-            if (!accept) {
-                // PYSIDE-1019: Allow any existing attribute in the constructor.
-                if (!_setProperty(qObj, key, value, &accept))
+        QByteArray propName(Shiboken::String::toCString(key));
+        bool accept = false;
+        if (metaObj->indexOfProperty(propName) != -1) {
+            if (!_setProperty(qObj, key, value, &accept))
+                return false;
+        } else {
+            propName.append("()");
+            if (metaObj->indexOfSignal(propName) != -1) {
+                accept = true;
+                propName.prepend('2');
+                if (!PySide::Signal::connect(qObj, propName, value))
                     return false;
             }
-            if (!accept) {
-                PyErr_Format(PyExc_AttributeError, "'%s' is not a Qt property or a signal",
-                             propName.constData());
+        }
+        if (!accept) {
+            // PYSIDE-1019: Allow any existing attribute in the constructor.
+            if (!_setProperty(qObj, key, value, &accept))
                 return false;
-            }
+        }
+        if (!accept) {
+            PyErr_Format(PyExc_AttributeError, "'%s' is not a Qt property or a signal",
+                         propName.constData());
+            return false;
         }
     }
     return true;
@@ -306,6 +303,9 @@ void initQApp()
      */
     if (!qApp)
         Py_DECREF(MakeQAppWrapper(nullptr));
+
+    // PYSIDE-1470: Register a function to destroy an application from shiboken.
+    setDestroyQApplication(destroyQCoreApplication);
 }
 
 PyObject *getMetaDataFromQObject(QObject *cppSelf, PyObject *self, PyObject *name)
@@ -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 c1a298cc..c72f37ae 100644
--- a/sources/pyside2/libpyside/pyside.h
+++ b/sources/pyside2/libpyside/pyside.h
@@ -71,12 +71,10 @@ inline Py_ssize_t hash(const T& value)
  * Fill QObject properties and do signal connections using the values found in \p kwds dictonary.
  * \param qObj PyObject fot the QObject.
  * \param metaObj QMetaObject of \p qObj.
- * \param blackList keys to be ignored in kwds dictionary, this string list MUST be sorted.
- * \param blackListSize numbe rof elements in blackList.
  * \param kwds key->value dictonary.
  * \return True if everything goes well, false with a Python error setted otherwise.
  */
-PYSIDE_API bool fillQtProperties(PyObject *qObj, const QMetaObject *metaObj, PyObject *kwds, const char **blackList, unsigned int blackListSize);
+PYSIDE_API bool fillQtProperties(PyObject *qObj, const QMetaObject *metaObj, PyObject *kwds);
 
 /**
 *   If the type \p T was registered on Qt meta type system with Q_DECLARE_METATYPE macro, this class will initialize
@@ -142,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/libpyside/pysideclassinfo.cpp b/sources/pyside2/libpyside/pysideclassinfo.cpp
index aa47f97c..098c391e 100644
--- a/sources/pyside2/libpyside/pysideclassinfo.cpp
+++ b/sources/pyside2/libpyside/pysideclassinfo.cpp
@@ -179,7 +179,7 @@ void classInfoFree(void *self)
 namespace PySide { namespace ClassInfo {
 
 static const char *ClassInfo_SignatureStrings[] = {
-    "PySide2.QtCore.ClassInfo(**info:typing.Dict[str,str])",
+    "PySide2.QtCore.ClassInfo(self,**info:typing.Dict[str,str])",
     nullptr}; // Sentinel
 
 void init(PyObject *module)
diff --git a/sources/pyside2/libpyside/pysidemetafunction.cpp b/sources/pyside2/libpyside/pysidemetafunction.cpp
index afb3dbb1..63fed028 100644
--- a/sources/pyside2/libpyside/pysidemetafunction.cpp
+++ b/sources/pyside2/libpyside/pysidemetafunction.cpp
@@ -102,7 +102,7 @@ PyObject *functionCall(PyObject *self, PyObject *args, PyObject * /* kw */)
 namespace PySide { namespace MetaFunction {
 
 static const char *MetaFunction_SignatureStrings[] = {
-    "PySide2.QtCore.MetaFunction.__call__(*args:typing.Any)->typing.Any",
+    "PySide2.QtCore.MetaFunction.__call__(self,*args:typing.Any)->typing.Any",
     nullptr}; // Sentinel
 
 void init(PyObject *module)
diff --git a/sources/pyside2/libpyside/pysideproperty.cpp b/sources/pyside2/libpyside/pysideproperty.cpp
index 97729d28..33b7c9c2 100644
--- a/sources/pyside2/libpyside/pysideproperty.cpp
+++ b/sources/pyside2/libpyside/pysideproperty.cpp
@@ -279,13 +279,13 @@ _property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *reset, PyO
         Py_XDECREF(del);
         del = pData->fdel ? pData->fdel : Py_None;
     }
-    if (pData->getter_doc && get != Py_None) {
-        /* make _init use __doc__ from getter */
-        doc = "";
-    }
-    else {
-        doc = !pData->doc.isEmpty() ? pData->doc : "";
-    }
+
+    // make _init use __doc__ from getter
+      if ((pData->getter_doc && get != Py_None) || pData->doc.isEmpty())
+          doc.clear();
+      else
+          doc = pData->doc;
+
     auto notify = pData->notify ? pData->notify : Py_None;
 
     PyObject *typeName = String::fromCString(pData->typeName);
diff --git a/sources/pyside2/libpyside/pysideqflags.cpp b/sources/pyside2/libpyside/pysideqflags.cpp
index b141ce15..8b224f2c 100644
--- a/sources/pyside2/libpyside/pysideqflags.cpp
+++ b/sources/pyside2/libpyside/pysideqflags.cpp
@@ -99,12 +99,17 @@ extern "C" {
             return NULL;
         }
 
-        long valA = PYSIDE_QFLAGS(self)->ob_value;
-        long valB = getNumberValue(other);
-
         if (self == other) {
-            result = 1;
+            switch (op) {
+            case Py_EQ:
+            case Py_LE:
+            case Py_GE:
+                result = 1;
+                break;
+            }
         } else  {
+            const long valA = PYSIDE_QFLAGS(self)->ob_value;
+            const long valB = getNumberValue(other);
             switch (op) {
             case Py_EQ:
                 result = (valA == valB);
diff --git a/sources/pyside2/libpyside/pysidesignal.cpp b/sources/pyside2/libpyside/pysidesignal.cpp
index 5c030316..b5069a00 100644
--- a/sources/pyside2/libpyside/pysidesignal.cpp
+++ b/sources/pyside2/libpyside/pysidesignal.cpp
@@ -624,17 +624,17 @@ namespace PySide {
 namespace Signal {
 
 static const char *MetaSignal_SignatureStrings[] = {
-    "PySide2.QtCore.MetaSignal.__instancecheck__(object:object)->bool",
+    "PySide2.QtCore.MetaSignal.__instancecheck__(self,object:object)->bool",
     nullptr}; // Sentinel
 
 static const char *Signal_SignatureStrings[] = {
-    "PySide2.QtCore.Signal(*types:type,name:str=nullptr,arguments:str=nullptr)",
+    "PySide2.QtCore.Signal(self,*types:type,name:str=nullptr,arguments:str=nullptr)",
     nullptr}; // Sentinel
 
 static const char *SignalInstance_SignatureStrings[] = {
-    "PySide2.QtCore.SignalInstance.connect(slot:object,type:type=nullptr)",
-    "PySide2.QtCore.SignalInstance.disconnect(slot:object=nullptr)",
-    "PySide2.QtCore.SignalInstance.emit(*args:typing.Any)",
+    "PySide2.QtCore.SignalInstance.connect(self,slot:object,type:type=nullptr)",
+    "PySide2.QtCore.SignalInstance.disconnect(self,slot:object=nullptr)",
+    "PySide2.QtCore.SignalInstance.emit(self,*args:typing.Any)",
     nullptr}; // Sentinel
 
 void init(PyObject *module)
diff --git a/sources/pyside2/libpyside/pysideslot.cpp b/sources/pyside2/libpyside/pysideslot.cpp
index 1ec24ab2..7911b21d 100644
--- a/sources/pyside2/libpyside/pysideslot.cpp
+++ b/sources/pyside2/libpyside/pysideslot.cpp
@@ -183,7 +183,7 @@ namespace PySide {
 namespace Slot {
 
 static const char *Slot_SignatureStrings[] = {
-    "PySide2.QtCore.Slot(*types:type,name:str=nullptr,result:str=nullptr)->typing.Callable[...,typing.Optional[str]]",
+    "PySide2.QtCore.Slot(self,*types:type,name:str=nullptr,result:str=nullptr)->typing.Callable[...,typing.Optional[str]]",
     nullptr}; // Sentinel
 
 void init(PyObject *module)
diff --git a/sources/pyside2/libpyside/pysidestaticstrings.cpp b/sources/pyside2/libpyside/pysidestaticstrings.cpp
index 760d7763..2dab2caa 100644
--- a/sources/pyside2/libpyside/pysidestaticstrings.cpp
+++ b/sources/pyside2/libpyside/pysidestaticstrings.cpp
@@ -60,4 +60,10 @@ STATIC_STRING_IMPL(name, "name")
 STATIC_STRING_IMPL(property, "property")
 STATIC_STRING_IMPL(select_id, "select_id")
 } // namespace PyName
+namespace PyMagicName
+{
+STATIC_STRING_IMPL(doc, "__doc__")
+STATIC_STRING_IMPL(name, "__name__")
+STATIC_STRING_IMPL(property_methods, "__property_methods__")
+} // namespace PyMagicName
 } // namespace PySide
diff --git a/sources/pyside2/libpyside/pysidestaticstrings.h b/sources/pyside2/libpyside/pysidestaticstrings.h
index 1222d8f4..54d1ab9c 100644
--- a/sources/pyside2/libpyside/pysidestaticstrings.h
+++ b/sources/pyside2/libpyside/pysidestaticstrings.h
@@ -55,6 +55,12 @@ PyObject *name();
 PyObject *property();
 PyObject *select_id();
 } // namespace PyName
+namespace PyMagicName
+{
+PyObject *doc();
+PyObject *name();
+PyObject *property_methods();
+} // namespace PyMagicName
 } // namespace PySide
 
 #endif // PYSIDESTRINGS_H
diff --git a/sources/pyside2/pyside_version.py b/sources/pyside2/pyside_version.py
index 009db0bf..9ec9b0e7 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 = "2"
+patch_version = "7"
 
 # 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 9d268e07..c7e50d64 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/bug_686.py b/sources/pyside2/tests/QtCore/bug_686.py
index 6e4f8994..d944cafe 100644
--- a/sources/pyside2/tests/QtCore/bug_686.py
+++ b/sources/pyside2/tests/QtCore/bug_686.py
@@ -49,6 +49,7 @@ class MyWriteThread(QThread):
         self.started = True
         while not self.lock.tryLockForWrite():
             pass
+        self.lock.unlock()
         self.canQuit = True
 
 class MyReadThread(QThread):
@@ -62,6 +63,7 @@ class MyReadThread(QThread):
         self.started = True
         while not self.lock.tryLockForRead():
             pass
+        self.lock.unlock()
         self.canQuit = True
 
 class MyMutexedThread(QThread):
diff --git a/sources/pyside2/tests/pysidetest/enum_test.py b/sources/pyside2/tests/QtCore/feature_with_uic/__init__.py
similarity index 65%
copy from sources/pyside2/tests/pysidetest/enum_test.py
copy to sources/pyside2/tests/QtCore/feature_with_uic/__init__.py
index d179d624..396f82fb 100644
--- a/sources/pyside2/tests/pysidetest/enum_test.py
+++ b/sources/pyside2/tests/QtCore/feature_with_uic/__init__.py
@@ -1,8 +1,6 @@
-# -*- coding: utf-8 -*-
-
 #############################################################################
 ##
-## Copyright (C) 2016 The Qt Company Ltd.
+## 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.
@@ -28,24 +26,4 @@
 ##
 #############################################################################
 
-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(True)
-
-from testbinding import Enum1, TestObjectWithoutNamespace
-
-class ListConnectionTest(unittest.TestCase):
-
-    def testEnumVisibility(self):
-        self.assertEqual(Enum1.Option1, 1)
-        self.assertEqual(Enum1.Option2, 2)
-        self.assertEqual(TestObjectWithoutNamespace.Enum2.Option3, 3)
-        self.assertEqual(TestObjectWithoutNamespace.Enum2.Option4, 4)
-
-if __name__ == '__main__':
-    unittest.main()
-
+# 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 00000000..db0fbd03
--- /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 00000000..0b85824e
--- /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/QtGui/qdatastream_gui_operators_test.py b/sources/pyside2/tests/QtCore/feature_with_uic_test.py
similarity index 59%
copy from sources/pyside2/tests/QtGui/qdatastream_gui_operators_test.py
copy to sources/pyside2/tests/QtCore/feature_with_uic_test.py
index c9b5c16a..64a620be 100644
--- a/sources/pyside2/tests/QtGui/qdatastream_gui_operators_test.py
+++ b/sources/pyside2/tests/QtCore/feature_with_uic_test.py
@@ -1,8 +1,6 @@
-# -*- coding: utf-8 -*-
-
 #############################################################################
 ##
-## Copyright (C) 2016 The Qt Company Ltd.
+## 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.
@@ -28,6 +26,16 @@
 ##
 #############################################################################
 
+"""
+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
@@ -36,33 +44,33 @@ 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 PySide2.QtCore import QDataStream, QByteArray, QIODevice, Qt
-from PySide2.QtGui import QPixmap, QColor
-
 from helper.usesqapplication import UsesQApplication
 
-class QPixmapQDatastream(UsesQApplication):
-    '''QDataStream <<>> QPixmap'''
+from PySide2.QtCore import QCoreApplication, 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 setUp(self):
-        super(QPixmapQDatastream, self).setUp()
-        self.source_pixmap = QPixmap(100, 100)
-        self.source_pixmap.fill(Qt.red)
-        self.output_pixmap = QPixmap()
-        self.buffer = QByteArray()
-        self.read_stream = QDataStream(self.buffer, QIODevice.ReadOnly)
-        self.write_stream = QDataStream(self.buffer, QIODevice.WriteOnly)
+    def __init__(self):
+        super().__init__()
+        self.setupUi(self)
 
-    def testStream(self):
-        self.write_stream << self.source_pixmap
 
-        self.read_stream >> self.output_pixmap
+class FeatureTest(UsesQApplication):
 
-        image = self.output_pixmap.toImage()
-        pixel = image.pixel(10,10)
-        self.assertEqual(pixel, QColor(Qt.red).rgba())
-        self.assertEqual(self.source_pixmap.toImage(), self.output_pixmap.toImage())
+    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__':
+if __name__ == '__main__' and sys.version_info[0] >= 3:
     unittest.main()
diff --git a/sources/pyside2/tests/QtCore/qflags_test.py b/sources/pyside2/tests/QtCore/qflags_test.py
index 08a7c55b..e1e989c1 100644
--- a/sources/pyside2/tests/QtCore/qflags_test.py
+++ b/sources/pyside2/tests/QtCore/qflags_test.py
@@ -30,6 +30,7 @@
 
 '''Test cases for QFlags'''
 
+import operator
 import os
 import sys
 import unittest
@@ -117,12 +118,13 @@ class QFlagsOnQVariant(unittest.TestCase):
 class QFlagsWrongType(unittest.TestCase):
     def testWrongType(self):
         '''Wrong type passed to QFlags binary operators'''
+        for op in operator.or_, operator.and_, operator.xor:
+            for x in '43', 'jabba', QObject, object:
+                self.assertRaises(TypeError, op, Qt.NoItemFlags, x)
+                self.assertRaises(TypeError, op, x, Qt.NoItemFlags)
+        # making sure this actually does not fail all the time
+        self.assertEqual(operator.or_(Qt.NoItemFlags, 43), 43)
 
-        self.assertRaises(TypeError, Qt.NoItemFlags | '43')
-        self.assertRaises(TypeError, Qt.NoItemFlags & '43')
-        self.assertRaises(TypeError, 'jabba' & Qt.NoItemFlags)
-        self.assertRaises(TypeError, 'hut' & Qt.NoItemFlags)
-        self.assertRaises(TypeError, Qt.NoItemFlags & QObject())
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/sources/pyside2/tests/QtCore/qobject_parent_test.py b/sources/pyside2/tests/QtCore/qobject_parent_test.py
index 0a02fbc2..becc7c48 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 639f6d27..d7e20373 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 QSettings
+from PySide2.QtCore import QDir, QSettings, QTemporaryDir, QByteArray
 
 class TestQSettings(unittest.TestCase):
     def testConversions(self):
@@ -57,9 +57,27 @@ 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):
-        settings = QSettings('foo.ini', QSettings.IniFormat)
+        temp_dir = QDir.tempPath()
+        dir = QTemporaryDir('{}/qsettings_XXXXXX'.format(temp_dir))
+        self.assertTrue(dir.isValid())
+        file_name = dir.filePath('foo.ini')
+        settings = QSettings(file_name, QSettings.IniFormat)
         settings.setValue('zero_value', 0)
         settings.setValue('empty_list', [])
         settings.setValue('bool1', False)
@@ -67,7 +85,7 @@ class TestQSettings(unittest.TestCase):
         del settings
 
         # Loading values already set
-        settings = QSettings('foo.ini', QSettings.IniFormat)
+        settings = QSettings(file_name, QSettings.IniFormat)
 
         # Getting value that doesn't exist
         r = settings.value("variable")
diff --git a/sources/pyside2/tests/QtCore/snake_prop_feature_test.py b/sources/pyside2/tests/QtCore/snake_prop_feature_test.py
index 779b8a40..aea6a22a 100644
--- a/sources/pyside2/tests/QtCore/snake_prop_feature_test.py
+++ b/sources/pyside2/tests/QtCore/snake_prop_feature_test.py
@@ -88,6 +88,8 @@ class FeatureTest(unittest.TestCase):
             window.modal
 
         from __feature__ import snake_case, true_property
+        #PYSIDE-1548: Make sure that another import does not clear the features.
+        import sys
 
         self.assertTrue(isinstance(QtWidgets.QWidget.modal, property))
         self.assertTrue(isinstance(window.modal, bool))
diff --git a/sources/pyside2/tests/QtCore/translation_test.py b/sources/pyside2/tests/QtCore/translation_test.py
index 0f36067b..b2e674aa 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/QtDataVisualization/datavisualization_test.py b/sources/pyside2/tests/QtDataVisualization/datavisualization_test.py
index af6e5f5d..32fd432e 100644
--- a/sources/pyside2/tests/QtDataVisualization/datavisualization_test.py
+++ b/sources/pyside2/tests/QtDataVisualization/datavisualization_test.py
@@ -88,5 +88,18 @@ class QtDataVisualizationTestCase(UsesQGuiApplication):
         QTimer.singleShot(500, self.app.quit)
         self.app.exec_()
 
+    def testBarDataProxy(self):
+        '''PSYSIDE-1438, crashes in QBarDataProxy.addRow()'''
+        items = [QtDataVisualization.QBarDataItem(v) for v in [1.0, 2.0]]
+        data_proxy = QtDataVisualization.QBarDataProxy()
+        data_proxy.addRow(items)
+        data_proxy.addRow(items, 'bla')
+        data_proxy.insertRow(0, items)
+        data_proxy.insertRow(0, items, 'bla')
+        data_proxy.setRow(0, items)
+        data_proxy.setRow(0, items, 'bla')
+        self.assertTrue(data_proxy.rowCount(), 4)
+
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/sources/pyside2/tests/QtGui/qdatastream_gui_operators_test.py b/sources/pyside2/tests/QtGui/qdatastream_gui_operators_test.py
index c9b5c16a..4db0a0a6 100644
--- a/sources/pyside2/tests/QtGui/qdatastream_gui_operators_test.py
+++ b/sources/pyside2/tests/QtGui/qdatastream_gui_operators_test.py
@@ -47,7 +47,9 @@ class QPixmapQDatastream(UsesQApplication):
     def setUp(self):
         super(QPixmapQDatastream, self).setUp()
         self.source_pixmap = QPixmap(100, 100)
-        self.source_pixmap.fill(Qt.red)
+        # PYSIDE-1533: Use Qt.transparent to force Format_ARGB32_Premultiplied
+        # when converting to QImage in any case.
+        self.source_pixmap.fill(Qt.transparent)
         self.output_pixmap = QPixmap()
         self.buffer = QByteArray()
         self.read_stream = QDataStream(self.buffer, QIODevice.ReadOnly)
@@ -60,8 +62,8 @@ class QPixmapQDatastream(UsesQApplication):
 
         image = self.output_pixmap.toImage()
         pixel = image.pixel(10,10)
-        self.assertEqual(pixel, QColor(Qt.red).rgba())
-        self.assertEqual(self.source_pixmap.toImage(), self.output_pixmap.toImage())
+        self.assertEqual(pixel, QColor(Qt.transparent).rgba())
+        self.assertEqual(self.source_pixmap.toImage(), image)
 
 
 if __name__ == '__main__':
diff --git a/sources/pyside2/tests/QtGui/qrasterwindow_test.py b/sources/pyside2/tests/QtGui/qrasterwindow_test.py
index f18ceaaf..1776e5ef 100644
--- a/sources/pyside2/tests/QtGui/qrasterwindow_test.py
+++ b/sources/pyside2/tests/QtGui/qrasterwindow_test.py
@@ -40,27 +40,6 @@ from helper.usesqapplication import UsesQApplication
 from PySide2.QtCore import QEvent, QPoint, QRect, QSize, QTimer, Qt
 from PySide2.QtGui import QColor, QBackingStore, QPaintDevice, QPainter, QWindow, QPaintDeviceWindow, QRasterWindow, QRegion, QStaticText
 
-# QWindow rendering via QBackingStore
-class TestBackingStoreWindow(QWindow):
-    def __init__(self):
-        super(TestBackingStoreWindow, self).__init__()
-        self.backingStore = QBackingStore(self)
-        self.text = QStaticText("BackingStoreWindow")
-
-    def event(self, event):
-        if event.type() == QEvent.Resize:
-            self.backingStore.resize(self.size())
-            self.render()
-        elif event.type() == QEvent.UpdateRequest or event.type() == QEvent.Expose:
-            self.backingStore.flush(QRegion(QRect(QPoint(0, 0), self.size())))
-
-        return QWindow.event(self, event)
-
-    def render(self):
-        clientRect = QRect(QPoint(0, 0), self.size())
-        painter = QPainter(self.backingStore.paintDevice())
-        painter.fillRect(clientRect, QColor(Qt.green))
-        painter.drawStaticText(QPoint(10, 10), self.text)
 
 # Window using convenience class QRasterWindow
 class TestRasterWindow(QRasterWindow):
@@ -74,19 +53,16 @@ class TestRasterWindow(QRasterWindow):
         painter.fillRect(clientRect, QColor(Qt.red))
         painter.drawStaticText(QPoint(10, 10), self.text)
 
+
 class QRasterWindowTest(UsesQApplication):
     def test(self):
         rasterWindow = TestRasterWindow()
         rasterWindow.setFramePosition(QPoint(100, 100))
         rasterWindow.resize(QSize(400, 400))
         rasterWindow.show()
-        backingStoreWindow = TestBackingStoreWindow()
-        backingStoreWindow.setFramePosition(QPoint(600, 100))
-        backingStoreWindow.resize(QSize(400, 400))
-        backingStoreWindow.show()
-
         QTimer.singleShot(100, self.app.quit)
         self.app.exec_()
 
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/sources/pyside2/tests/QtWidgets/signature_test.py b/sources/pyside2/tests/QtWidgets/signature_test.py
index 57fcf387..cacb576d 100644
--- a/sources/pyside2/tests/QtWidgets/signature_test.py
+++ b/sources/pyside2/tests/QtWidgets/signature_test.py
@@ -65,8 +65,9 @@ class PySideSignatureTest(unittest.TestCase):
         for thing in obj.__signature__:
             self.assertEqual(type(thing), inspect.Signature)
         sm = PySide2.QtWidgets.QApplication.__dict__["palette"]
-        self.assertFalse(callable(sm))
-        self.assertEqual(sm.__func__, obj)
+        # PYSIDE-1436: staticmethod is a callable since Python 3.10
+        # Instead of checking callable(sm), we check the type:
+        self.assertEqual(type(sm), staticmethod)
         self.assertTrue(hasattr(sm, "__signature__") and
                         sm.__signature__ is not None)
 
diff --git a/sources/pyside2/tests/pysidetest/constructor_properties_test.py b/sources/pyside2/tests/pysidetest/constructor_properties_test.py
index 139091fe..5d102704 100644
--- a/sources/pyside2/tests/pysidetest/constructor_properties_test.py
+++ b/sources/pyside2/tests/pysidetest/constructor_properties_test.py
@@ -47,11 +47,13 @@ init_test_paths(False)
 
 from helper.usesqapplication import UsesQApplication
 from PySide2.QtCore import Qt
-from PySide2.QtWidgets import QApplication, QLabel, QFrame
+from PySide2.QtGui import QColor
+from PySide2.QtWidgets import QAction, QApplication, QFrame, QLabel
 
 
 class ConstructorPropertiesTest(UsesQApplication):
 
+    # PYSIDE-1019: First property extension was support by the constructor.
     def testCallConstructor(self):
         label = QLabel(
             frameStyle=QFrame.Panel | QFrame.Sunken,
@@ -65,6 +67,34 @@ class ConstructorPropertiesTest(UsesQApplication):
         ))
 
 
+class DiverseKeywordsTest(UsesQApplication):
+
+    def testDuplicateKeyword(self):
+        r, g, b, a = 1, 2, 3, 4
+        with self.assertRaises(TypeError) as cm:
+            QColor(r, g, b, a, a=0)
+        self.assertTrue("multiple" in cm.exception.args[0])
+
+    # PYSIDE-1305: Handle keyword args correctly.
+    def testUndefinedKeyword(self):
+        r, g, b, a = 1, 2, 3, 4
+        # From the jira issue:
+        with self.assertRaises(AttributeError) as cm:
+            QColor(r, g, b, a, alpha=0)
+        self.assertTrue("unsupported" in cm.exception.args[0])
+
+    # PYSIDE-1305: Handle keyword args correctly.
+    def testUndefinedConstructorKeyword(self):
+        # make sure that the given attribute lands in the constructor
+        x = QAction(autoRepeat=False)
+        self.assertEqual(x.autoRepeat(), False)
+        x = QAction(autoRepeat=True)
+        self.assertEqual(x.autoRepeat(), True)
+        # QAction derives from QObject, and so the missing attributes
+        # in the constructor are reported as AttributeError.
+        with self.assertRaises(AttributeError):
+            QAction(some_other_name=42)
+
+
 if __name__ == '__main__':
     unittest.main()
-
diff --git a/sources/pyside2/tests/pysidetest/embedding_test.py b/sources/pyside2/tests/pysidetest/embedding_test.py
index 1960838f..57068692 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/pyside2/tests/pysidetest/enum_test.py b/sources/pyside2/tests/pysidetest/enum_test.py
index d179d624..a9396383 100644
--- a/sources/pyside2/tests/pysidetest/enum_test.py
+++ b/sources/pyside2/tests/pysidetest/enum_test.py
@@ -36,6 +36,7 @@ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
 from init_paths import init_test_paths
 init_test_paths(True)
 
+from PySide2.QtCore import Qt
 from testbinding import Enum1, TestObjectWithoutNamespace
 
 class ListConnectionTest(unittest.TestCase):
@@ -46,6 +47,29 @@ class ListConnectionTest(unittest.TestCase):
         self.assertEqual(TestObjectWithoutNamespace.Enum2.Option3, 3)
         self.assertEqual(TestObjectWithoutNamespace.Enum2.Option4, 4)
 
+    def testFlagComparisonOperators(self):  # PYSIDE-1696, compare to self
+        f1 = Qt.AlignHCenter | Qt.AlignBottom
+        f2 = Qt.AlignHCenter | Qt.AlignBottom
+        self.assertTrue(f1 == f1)
+        self.assertTrue(f1 <= f1)
+        self.assertTrue(f1 >= f1)
+        self.assertFalse(f1 != f1)
+        self.assertFalse(f1 < f1)
+        self.assertFalse(f1 > f1)
+
+        self.assertTrue(f1 == f2)
+        self.assertTrue(f1 <= f2)
+        self.assertTrue(f1 >= f2)
+        self.assertFalse(f1 != f2)
+        self.assertFalse(f1 < f2)
+        self.assertFalse(f1 > f2)
+
+        self.assertTrue(Qt.AlignHCenter < Qt.AlignBottom)
+        self.assertFalse(Qt.AlignHCenter > Qt.AlignBottom)
+        self.assertFalse(Qt.AlignBottom < Qt.AlignHCenter)
+        self.assertTrue(Qt.AlignBottom > Qt.AlignHCenter)
+
+
 if __name__ == '__main__':
     unittest.main()
 
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index d59147d5..d7ae45ae 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -575,7 +575,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
             } else if (entry->isEnum() && entry->generateCode()) {
                 auto enumEntry = static_cast<const EnumTypeEntry *>(entry);
                 const QString name = enumEntry->targetLangQualifier();
-                AbstractMetaClass *cls = AbstractMetaClass::findClass(m_metaClasses, name);
+                AbstractMetaClass *cls = AbstractMetaClass::findClass(m_metaClasses,
+                                                                      enumEntry->parent());
 
                 const bool enumFound = cls
                     ? cls->findEnum(entry->targetLangEntryName()) != nullptr
@@ -1471,12 +1472,13 @@ bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass)
 
     for (const auto  &baseClassName : baseClasses) {
         if (!types->isClassRejected(baseClassName)) {
-            if (!types->findType(baseClassName)) {
+            auto typeEntry = types->findType(baseClassName);
+            if (typeEntry == nullptr || !typeEntry->isComplex()) {
                 qCWarning(lcShiboken, "%s",
                           qPrintable(msgUnknownBase(metaClass, baseClassName)));
                 return false;
             }
-            auto baseClass = AbstractMetaClass::findClass(m_metaClasses, baseClassName);
+            auto baseClass = AbstractMetaClass::findClass(m_metaClasses, typeEntry);
             if (!baseClass) {
                 qCWarning(lcShiboken).noquote().nospace()
                     << QStringLiteral("class not found for setup inheritance '%1'").arg(baseClassName);
@@ -2448,7 +2450,7 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite
                                                     int /* argumentIndex */)
 {
     QString expr = item->defaultValueExpression();
-    if (expr.isEmpty())
+    if (expr.isEmpty() || expr == u"{}")
         return expr;
 
     if (type) {
@@ -3086,8 +3088,11 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const
         // Member fields need to be initialized
         const AbstractMetaFieldList &fields = clazz->fields();
         for (AbstractMetaField *field : fields) {
-            addClassDependency(field->type()->typeEntry(), clazz, classIndex,
-                               map, &graph);
+            auto typeEntry = field->type()->typeEntry();
+            if (typeEntry->isEnum()) // Enum defined in class?
+                typeEntry = typeEntry->parent();
+            if (typeEntry != nullptr)
+                addClassDependency(typeEntry, clazz, classIndex, map, &graph);
         }
     }
 
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
index 3bdac909..723a1316 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
@@ -2123,6 +2123,12 @@ AbstractMetaField *AbstractMetaClass::findField(const QString &name) const
     return AbstractMetaField::find(m_fields, name);
 }
 
+bool AbstractMetaClass::hasStaticFields() const
+{
+    return std::any_of(m_fields.cbegin(), m_fields.cend(),
+                       [](const AbstractMetaField *f) { return f->isStatic(); });
+}
+
 AbstractMetaEnum *AbstractMetaClass::findEnum(const QString &enumName)
 {
     if (AbstractMetaEnum *e = findByName(m_enums, enumName))
@@ -2171,6 +2177,11 @@ void AbstractMetaClass::getFunctionsFromInvisibleNamespacesToBeGenerated(Abstrac
     }
 }
 
+QString AbstractMetaClass::fullName() const
+{
+    return package() + QLatin1Char('.') + m_typeEntry->targetLangName();
+}
+
 static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractMetaType *type)
 {
     if (!type)
@@ -2520,28 +2531,18 @@ AbstractMetaEnum *AbstractMetaClass::findEnum(const AbstractMetaClassList &class
 {
     Q_ASSERT(entry->isEnum());
 
-    QString qualifiedName = entry->qualifiedCppName();
-    int pos = qualifiedName.lastIndexOf(QLatin1String("::"));
-
-    QString enumName;
-    QString className;
-
-    if (pos > 0) {
-        enumName = qualifiedName.mid(pos + 2);
-        className = qualifiedName.mid(0, pos);
-    } else {
-        enumName = qualifiedName;
-        className = TypeDatabase::globalNamespaceClassName(entry);
-    }
-
-    AbstractMetaClass *metaClass = AbstractMetaClass::findClass(classes, className);
+    auto scopeEntry = entry->parent();
+    AbstractMetaClass *metaClass = AbstractMetaClass::findClass(classes, scopeEntry);
     if (!metaClass) {
         qCWarning(lcShiboken).noquote().nospace()
             << QStringLiteral("AbstractMeta::findEnum(), unknown class '%1' in '%2'")
-                              .arg(className, entry->qualifiedCppName());
+                              .arg(scopeEntry->qualifiedCppName(), entry->qualifiedCppName());
         return nullptr;
     }
 
+    QString qualifiedName = entry->qualifiedCppName();
+    const int pos = qualifiedName.lastIndexOf(QLatin1String("::"));
+    const QString enumName = pos > 0 ? qualifiedName.mid(pos + 2) : qualifiedName;
     return metaClass->findEnum(enumName);
 }
 
@@ -2752,4 +2753,3 @@ QString AbstractMetaEnum::package() const
 {
     return m_typeEntry->targetLangPackage();
 }
-
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h
index c100c63a..8a0363f4 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -84,6 +84,7 @@ public:
                   Format fmt = Documentation::Native);
 
     bool isEmpty() const;
+    bool hasBrief() const { return m_data.contains(Brief); }
 
     QString value(Type t = Documentation::Detailed) const;
     void setValue(const QString& value, Type t = Documentation::Detailed,
@@ -1424,6 +1425,8 @@ public:
 
     AbstractMetaField *findField(const QString &name) const;
 
+    bool hasStaticFields() const;
+
     const AbstractMetaEnumList &enums() const { return m_enums; }
     void setEnums(const AbstractMetaEnumList &enums)
     {
@@ -1442,10 +1445,7 @@ public:
 
     void getFunctionsFromInvisibleNamespacesToBeGenerated(AbstractMetaFunctionList *funcList) const;
 
-    QString fullName() const
-    {
-        return package() + QLatin1Char('.') + name();
-    }
+    QString fullName() const;
 
     /**
      *   Retrieves the class name without any namespace/scope information.
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
index 73b1aca6..b7367090 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
@@ -245,8 +245,16 @@ bool BuilderPrivate::addClass(const CXCursor &cursor, CodeModel::ClassType t)
     if (isClassCursor(semPar)) {
         const CursorClassHash::const_iterator it = m_cursorClassHash.constFind(semPar);
         if (it == m_cursorClassHash.constEnd()) {
-            const QString message = QStringLiteral("Unable to find parent of inner class ") + className;
-            const Diagnostic d(message, cursor, CXDiagnostic_Error);
+            QString message;
+            QTextStream(&message) << "Unable to find containing class \""
+                << getCursorSpelling(semPar) << "\" of inner class \""
+                << className << "\".";
+            // PYSIDE-1501: Has been observed to fail for inner class of
+            // template with separated implementation where a forward
+            // declaration of the outer template is reported (Boost).
+            const auto severity = semPar.kind == CXCursor_ClassTemplate
+                ? CXDiagnostic_Warning : CXDiagnostic_Error;
+            const Diagnostic d(message, cursor, severity);
             qWarning() << d;
             m_baseVisitor->appendDiagnostic(d);
             return false;
@@ -887,8 +895,10 @@ static QString enumType(const CXCursor &cursor)
         // PYSIDE-1228: For "typedef enum { v1, v2 } Foo;", type will return
         // "Foo" as expected. Care must be taken to exclude real anonymous enums.
         name = getTypeName(clang_getCursorType(cursor));
-        if (name.contains(QLatin1String("(anonymous")))
+        if (name.contains(QLatin1String("(unnamed")) // Clang 12.0.1
+            || name.contains(QLatin1String("(anonymous"))) { // earlier
             name.clear();
+        }
     }
     return name;
 }
@@ -921,16 +931,17 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
     case CXCursor_ClassDecl:
     case CXCursor_UnionDecl:
     case CXCursor_StructDecl:
-        if (clang_isCursorDefinition(cursor) == 0)
+        if (clang_isCursorDefinition(cursor) == 0
+            || !d->addClass(cursor, codeModelClassTypeFromCursor(cursor.kind))) {
             return Skip;
-        if (!d->addClass(cursor, codeModelClassTypeFromCursor(cursor.kind)))
-            return Error;
+        }
         break;
     case CXCursor_ClassTemplate:
     case CXCursor_ClassTemplatePartialSpecialization:
-        if (clang_isCursorDefinition(cursor) == 0)
+        if (clang_isCursorDefinition(cursor) == 0
+            || !d->addClass(cursor, CodeModel::Class)) {
             return Skip;
-        d->addClass(cursor, CodeModel::Class);
+        }
         d->m_currentClass->setName(d->m_currentClass->name() + templateBrackets());
         d->m_scope.back() += templateBrackets();
         break;
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
index 6bf2e3ab..57271ef7 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
@@ -139,8 +139,9 @@ QString getTypeName(const CXType &type)
 }
 
 Diagnostic::Diagnostic(const QString &m, const CXCursor &c, CXDiagnosticSeverity s)
-    : message(m), location(getCursorLocation(c)), source(Other), severity(s)
+    : message(m), source(Other), severity(s)
 {
+    setLocation(getCursorLocation(c));
 }
 
 Diagnostic Diagnostic::fromCXDiagnostic(CXDiagnostic cd)
@@ -151,7 +152,7 @@ Diagnostic Diagnostic::fromCXDiagnostic(CXDiagnostic cd)
     result.message = QString::fromUtf8(clang_getCString(spelling));
     clang_disposeString(spelling);
     result.severity = clang_getDiagnosticSeverity(cd);
-    result.location = getExpansionLocation(clang_getDiagnosticLocation(cd));
+    result.setLocation(getExpansionLocation(clang_getDiagnosticLocation(cd)));
 
     CXDiagnosticSet childDiagnostics = clang_getChildDiagnostics(cd);
     if (const unsigned childCount = clang_getNumDiagnosticsInSet(childDiagnostics)) {
@@ -169,6 +170,14 @@ Diagnostic Diagnostic::fromCXDiagnostic(CXDiagnostic cd)
     return result;
 }
 
+void Diagnostic::setLocation(const SourceLocation &sourceLocation)
+{
+    file = getFileName(sourceLocation.file);
+    line = sourceLocation.line;
+    column = sourceLocation.column;
+    offset = sourceLocation.offset;
+}
+
 QVector<Diagnostic> getDiagnostics(CXTranslationUnit tu)
 {
     QVector<Diagnostic> result;
@@ -249,7 +258,7 @@ QDebug operator<<(QDebug s, const Diagnostic &d)
     QDebugStateSaver saver(s);
     s.nospace();
     s.noquote();
-    s << d.location << ": ";
+    s << d.file << ':'<< d.line << ':' << d.column << ": ";
     switch (d.severity) {
     case CXDiagnostic_Ignored:
         s << "ignored";
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.h b/sources/shiboken2/ApiExtractor/clangparser/clangutils.h
index 41d0af46..f7c230a6 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangutils.h
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangutils.h
@@ -68,7 +68,7 @@ struct SourceLocation
 {
     bool equals(const SourceLocation &rhs) const;
 
-    CXFile file;
+    CXFile file = nullptr;
     unsigned line = 0;
     unsigned column = 0;
     unsigned offset = 0;
@@ -96,10 +96,14 @@ struct Diagnostic {
     static Diagnostic fromCXDiagnostic(CXDiagnostic cd);
     // Other
     explicit Diagnostic(const QString &m, const CXCursor &c, CXDiagnosticSeverity s = CXDiagnostic_Warning);
+    void setLocation(const SourceLocation &);
 
     QString message;
     QStringList childMessages;
-    SourceLocation location;
+    QString file;
+    unsigned line = 0;
+    unsigned column = 0;
+    unsigned offset = 0;
     Source source = Clang;
     CXDiagnosticSeverity severity = CXDiagnostic_Warning;
 };
diff --git a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
index dac51100..0b58cf5a 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
@@ -232,7 +232,9 @@ static QByteArray noStandardIncludeOption() { return QByteArrayLiteral("-nostdin
 // should be picked up automatically by clang without specifying
 // them implicitly.
 
-#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
+// Besides g++/Linux, as of MSVC 19.28.29334, MSVC needs clang includes
+// due to PYSIDE-1433, LLVM-47099
+#if !defined(Q_OS_DARWIN)
 #  define NEED_CLANG_BUILTIN_INCLUDES 1
 #else
 #  define NEED_CLANG_BUILTIN_INCLUDES 0
@@ -301,6 +303,24 @@ static QString compilerFromCMake(const QString &defaultCompiler)
 }
 #endif // Q_CC_CLANG, Q_CC_GNU
 
+#if NEED_CLANG_BUILTIN_INCLUDES
+static void appendClangBuiltinIncludes(HeaderPaths *p)
+{
+    const QString clangBuiltinIncludesDir =
+        QDir::toNativeSeparators(findClangBuiltInIncludesDir());
+    if (clangBuiltinIncludesDir.isEmpty()) {
+        qCWarning(lcShiboken, "Unable to locate Clang's built-in include directory "
+                  "(neither by checking the environment variables LLVM_INSTALL_DIR, CLANG_INSTALL_DIR "
+                  " nor running llvm-config). This may lead to parse errors.");
+    } else {
+        qCInfo(lcShiboken, "CLANG builtins includes directory: %s",
+               qPrintable(clangBuiltinIncludesDir));
+        p->append(HeaderPath{QFile::encodeName(clangBuiltinIncludesDir),
+                             HeaderType::System});
+    }
+}
+#endif // NEED_CLANG_BUILTIN_INCLUDES
+
 // Returns clang options needed for emulating the host compiler
 QByteArrayList emulatedCompilerOptions()
 {
@@ -311,26 +331,19 @@ QByteArrayList emulatedCompilerOptions()
     result.append(QByteArrayLiteral("-Wno-microsoft-enum-value"));
     // Fix yvals_core.h:  STL1000: Unexpected compiler version, expected Clang 7 or newer (MSVC2017 update)
     result.append(QByteArrayLiteral("-D_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH"));
+#  if NEED_CLANG_BUILTIN_INCLUDES
+    appendClangBuiltinIncludes(&headerPaths);
+#  endif // NEED_CLANG_BUILTIN_INCLUDES
+
 #elif defined(Q_CC_CLANG)
     HeaderPaths headerPaths = gppInternalIncludePaths(compilerFromCMake(QStringLiteral("clang++")));
     result.append(noStandardIncludeOption());
 #elif defined(Q_CC_GNU)
     HeaderPaths headerPaths;
 
-#if NEED_CLANG_BUILTIN_INCLUDES
-    const QString clangBuiltinIncludesDir =
-        QDir::toNativeSeparators(findClangBuiltInIncludesDir());
-    if (clangBuiltinIncludesDir.isEmpty()) {
-        qCWarning(lcShiboken, "Unable to locate Clang's built-in include directory "
-                  "(neither by checking the environment variables LLVM_INSTALL_DIR, CLANG_INSTALL_DIR "
-                  " nor running llvm-config). This may lead to parse errors.");
-    } else {
-        qCInfo(lcShiboken, "CLANG builtins includes directory: %s",
-               qPrintable(clangBuiltinIncludesDir));
-        headerPaths.append(HeaderPath{QFile::encodeName(clangBuiltinIncludesDir),
-                                      HeaderType::System});
-    }
-#endif // NEED_CLANG_BUILTIN_INCLUDES
+#  if NEED_CLANG_BUILTIN_INCLUDES
+    appendClangBuiltinIncludes(&headerPaths);
+#  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.
diff --git a/sources/shiboken2/ApiExtractor/qtdocparser.cpp b/sources/shiboken2/ApiExtractor/qtdocparser.cpp
index d439b3fd..1aeab85e 100644
--- a/sources/shiboken2/ApiExtractor/qtdocparser.cpp
+++ b/sources/shiboken2/ApiExtractor/qtdocparser.cpp
@@ -41,6 +41,9 @@
 #include <QtCore/QXmlStreamReader>
 #include <QUrl>
 
+static inline QString briefStartElement() { return QStringLiteral("<brief>"); }
+static inline QString briefEndElement() { return QStringLiteral("</brief>"); }
+
 Documentation QtDocParser::retrieveModuleDocumentation()
 {
     return retrieveModuleDocumentation(packageName());
@@ -206,6 +209,25 @@ QString QtDocParser::queryFunctionDocumentation(const QString &sourceFileName,
     return result;
 }
 
+// Extract the <brief> section from a WebXML (class) documentation and remove it
+// from the source.
+static QString extractBrief(QString *value)
+{
+    const auto briefStart = value->indexOf(briefStartElement());
+    if (briefStart < 0)
+        return {};
+    const auto briefEnd = value->indexOf(briefEndElement(),
+                                         briefStart + briefStartElement().size());
+    if (briefEnd < briefStart)
+        return {};
+    const auto briefLength = briefEnd + briefEndElement().size() - briefStart;
+    QString briefValue = value->mid(briefStart, briefLength);
+    briefValue.insert(briefValue.size() - briefEndElement().size(),
+                      QLatin1String("<rst> More_...</rst>"));
+    value->remove(briefStart, briefLength);
+    return briefValue;
+}
+
 void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass)
 {
     if (!metaClass)
@@ -257,9 +279,17 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass)
             signedModifs.append(docModif);
     }
 
-    Documentation doc(getDocumentation(xquery, query, classModifs));
-    if (doc.isEmpty())
-         qCWarning(lcShibokenDoc, "%s", qPrintable(msgCannotFindDocumentation(sourceFileName, "class", className, query)));
+    QString docString = getDocumentation(xquery, query, classModifs);
+    if (docString.isEmpty()) {
+        qCWarning(lcShibokenDoc, "%s",
+                  qPrintable(msgCannotFindDocumentation(sourceFileName, "class", className, query)));
+    }
+    const QString brief = extractBrief(&docString);
+
+    Documentation doc;
+    if (!brief.isEmpty())
+        doc.setValue(brief, Documentation::Brief);
+    doc.setValue(docString);
     metaClass->setDocumentation(doc);
 
     //Functions Documentation
diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp
index 6acac41d..cf3982a1 100644
--- a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp
@@ -72,13 +72,14 @@ R"(<typesystem package="Foo">
     docParser.setDocumentationDataDirectory(tempDir.path());
     docParser.fillDocumentation(classA);
 
-    const QString actualDocSimplified = classA->documentation().value().simplified();
+    const Documentation &doc = classA->documentation();
+    const QString actualDocSimplified = doc.value(Documentation::Detailed).simplified();
+    const QString actualBriefSimplified = doc.value(Documentation::Brief).simplified();
     QVERIFY(!actualDocSimplified.isEmpty());
 
 const char expectedDoc[] =
 R"(<?xml version="1.0"?>
 <description>oi
-<brief>Modified Brief</brief>
 <para>Paragraph number 1</para>
 <para>Paragraph number 2</para>
 <para>Some changed contents here</para>
@@ -86,7 +87,7 @@ R"(<?xml version="1.0"?>
 )";
     const QString expectedDocSimplified = QString::fromLatin1(expectedDoc).simplified();
     // Check whether the first modification worked.
-    QVERIFY(actualDocSimplified.contains(QLatin1String("Modified Brief")));
+    QVERIFY(actualBriefSimplified.contains(QLatin1String("Modified Brief")));
 
 #ifndef HAVE_LIBXSLT
     // QtXmlPatterns is unable to handle para[3] in style sheets,
diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.cpp b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
index d2648d0b..17195d9a 100644
--- a/sources/shiboken2/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystemparser.cpp
@@ -1286,7 +1286,7 @@ ContainerTypeEntry *
         m_error = QLatin1String("no 'type' attribute specified");
         return nullptr;
     }
-    const QStringRef typeName = attributes->takeAt(typeIndex).value();
+    const QStringRef typeName = attributes->at(typeIndex).value();
     ContainerTypeEntry::ContainerKind containerType = containerTypeFromAttribute(typeName);
     if (containerType == ContainerTypeEntry::NoContainer) {
         m_error = QLatin1String("there is no container of type ") + typeName.toString();
@@ -1294,6 +1294,7 @@ ContainerTypeEntry *
     }
     auto *type = new ContainerTypeEntry(name, containerType, since, currentParentTypeEntry());
     applyCommonAttributes(reader, type, attributes);
+    attributes->removeAt(typeIndex);
     return type;
 }
 
@@ -1359,7 +1360,7 @@ NamespaceTypeEntry *
             }
             result->setFilePattern(re);
         } else if (attributeName == QLatin1String("extends")) {
-            const auto extendsPackageName = attributes->takeAt(i).value();
+            const auto extendsPackageName = attributes->at(i).value();
             auto allEntries = TypeDatabase::instance()->findNamespaceTypes(name);
             auto extendsIt = std::find_if(allEntries.cbegin(), allEntries.cend(),
                                           [extendsPackageName] (const NamespaceTypeEntry *e) {
@@ -1370,6 +1371,7 @@ NamespaceTypeEntry *
                 return nullptr;
             }
             result->setExtends(*extendsIt);
+            attributes->removeAt(i);
         } else if (attributeName == visibleAttribute()) {
             const auto attribute = attributes->takeAt(i);
             visibility = visibilityFromAttribute(attribute.value());
@@ -1621,19 +1623,21 @@ bool TypeSystemParser::parseInjectDocumentation(const QXmlStreamReader &,
     for (int i = attributes->size() - 1; i >= 0; --i) {
         const QStringRef name = attributes->at(i).qualifiedName();
         if (name == QLatin1String("mode")) {
-            const QStringRef modeName = attributes->takeAt(i).value();
+            const QStringRef modeName = attributes->at(i).value();
             mode = docModificationFromAttribute(modeName);
             if (mode == TypeSystem::DocModificationInvalid) {
                 m_error = QLatin1String("Unknown documentation injection mode: ") + modeName;
                 return false;
             }
+            attributes->removeAt(i);
         } else if (name == formatAttribute()) {
-            const QStringRef format = attributes->takeAt(i).value();
+            const QStringRef format = attributes->at(i).value();
             lang = languageFromAttribute(format);
             if (lang != TypeSystem::TargetLangCode && lang != TypeSystem::NativeCode) {
                 m_error = QStringLiteral("unsupported class attribute: '%1'").arg(format);
                 return false;
             }
+            attributes->removeAt(i);
         }
     }
 
@@ -1797,12 +1801,13 @@ bool TypeSystemParser::parseCustomConversion(const QXmlStreamReader &,
     for (int i = attributes->size() - 1; i >= 0; --i) {
         const QStringRef name = attributes->at(i).qualifiedName();
         if (name == classAttribute()) {
-            const QStringRef languageAttribute = attributes->takeAt(i).value();
+            const QStringRef languageAttribute = attributes->at(i).value();
             lang = languageFromAttribute(languageAttribute);
             if (lang != TypeSystem::TargetLangCode && lang != TypeSystem::NativeCode) {
                 m_error = QStringLiteral("unsupported class attribute: '%1'").arg(languageAttribute);
                 return false;
             }
+            attributes->removeAt(i);
         } else if (name == QLatin1String("file")) {
             sourceFile = attributes->takeAt(i).value().toString();
         } else if (name == snippetAttribute()) {
@@ -1999,12 +2004,13 @@ bool TypeSystemParser::parseDefineOwnership(const QXmlStreamReader &,
     for (int i = attributes->size() - 1; i >= 0; --i) {
         const QStringRef name = attributes->at(i).qualifiedName();
         if (name == classAttribute()) {
-            const QStringRef className = attributes->takeAt(i).value();
+            const QStringRef className = attributes->at(i).value();
             lang = languageFromAttribute(className);
             if (lang != TypeSystem::TargetLangCode && lang != TypeSystem::NativeCode) {
                 m_error = QStringLiteral("unsupported class attribute: '%1'").arg(className);
                 return false;
             }
+            attributes->removeAt(i);
         } else if (name == ownershipAttribute()) {
             ownership = attributes->takeAt(i).value().toString();
         }
@@ -2067,7 +2073,7 @@ bool TypeSystemParser::parseRemoval(const QXmlStreamReader &,
     TypeSystem::Language lang = TypeSystem::All;
     const int classIndex = indexOfAttribute(*attributes, classAttribute());
     if (classIndex != -1) {
-        const QStringRef value = attributes->takeAt(classIndex).value();
+        const QStringRef value = attributes->at(classIndex).value();
         lang = languageFromAttribute(value);
         if (lang == TypeSystem::TargetLangCode) // "target" means TargetLangAndNativeCode here
             lang = TypeSystem::TargetLangAndNativeCode;
@@ -2075,6 +2081,7 @@ bool TypeSystemParser::parseRemoval(const QXmlStreamReader &,
             m_error = QStringLiteral("unsupported class attribute: '%1'").arg(value);
             return false;
         }
+        attributes->removeAt(classIndex);
     }
     m_contextStack.top()->functionMods.last().removal = lang;
     return true;
@@ -2118,7 +2125,7 @@ bool TypeSystemParser::parseRename(const QXmlStreamReader &reader,
             m_error = msgMissingAttribute(modifierAttribute());
             return false;
         }
-        const QStringRef modifier = attributes->takeAt(modifierIndex).value();
+        const QStringRef modifier = attributes->at(modifierIndex).value();
         modifierFlag = modifierFromAttribute(modifier);
         if (modifierFlag == Modification::InvalidModifier) {
             m_error = QStringLiteral("Unknown access modifier: '%1'").arg(modifier);
@@ -2128,6 +2135,7 @@ bool TypeSystemParser::parseRename(const QXmlStreamReader &reader,
             qCWarning(lcShiboken, "%s",
                       qPrintable(msgUnimplementedAttributeValueWarning(reader, modifierAttribute(), modifier)));
         }
+        attributes->removeAt(modifierIndex);
     }
 
     if (mod)
@@ -2497,12 +2505,13 @@ bool TypeSystemParser::parseParentOwner(const QXmlStreamReader &,
             if (!parseArgumentIndex(index, &ao.index, &m_error))
                 return false;
         } else if (name == actionAttribute()) {
-            const QStringRef action = attributes->takeAt(i).value();
+            const QStringRef action = attributes->at(i).value();
             ao.action = argumentOwnerActionFromAttribute(action);
             if (ao.action == ArgumentOwner::Invalid) {
                 m_error = QLatin1String("Invalid parent actionr '") + action + QLatin1String("'.");
                 return false;
             }
+            attributes->removeAt(i);
         }
     }
     m_contextStack.top()->functionMods.last().argument_mods.last().owner = ao;
@@ -2569,19 +2578,21 @@ bool TypeSystemParser::parseInjectCode(const QXmlStreamReader &,
     for (int i = attributes->size() - 1; i >= 0; --i) {
         const QStringRef name = attributes->at(i).qualifiedName();
         if (name == classAttribute()) {
-            const QStringRef className = attributes->takeAt(i).value();
+            const QStringRef className = attributes->at(i).value();
             lang = languageFromAttribute(className);
             if (lang == TypeSystem::NoLanguage) {
                 m_error = QStringLiteral("Invalid class specifier: '%1'").arg(className);
                 return false;
             }
+            attributes->removeAt(i);
         } else if (name == positionAttribute()) {
-            const QStringRef value = attributes->takeAt(i).value();
+            const QStringRef value = attributes->at(i).value();
             position = codeSnipPositionFromAttribute(value);
             if (position == TypeSystem::CodeSnipPositionInvalid) {
                 m_error = QStringLiteral("Invalid position: '%1'").arg(value);
                 return false;
             }
+            attributes->removeAt(i);
         }
     }
 
diff --git a/sources/shiboken2/CMakeLists.txt b/sources/shiboken2/CMakeLists.txt
index 3de5d322..c6546021 100644
--- a/sources/shiboken2/CMakeLists.txt
+++ b/sources/shiboken2/CMakeLists.txt
@@ -144,7 +144,7 @@ endif()
 # Build with Address sanitizer enabled if requested.
 # This may break things, so use at your own risk.
 if (SANITIZE_ADDRESS AND NOT MSVC)
-    set_sanitize_address()
+    setup_sanitize_address()
 endif()
 
 # Detect if the python libs were compiled in debug mode
@@ -196,6 +196,35 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
     set_debug_build()
 endif()
 
+######################################################################
+## Define the Python files involved in the build process.
+##
+## They are installed into the file system (see shibokenmodule)
+## and embedded into the libshiboken binary through a .zip file.
+######################################################################
+
+set(shiboken_python_files
+    "signature/lib/__init__.py"
+    "signature/lib/enum_sig.py"
+    "signature/lib/tool.py"
+    "signature/__init__.py"
+    "signature/errorhandler.py"
+    "signature/importhandler.py"
+    "signature/layout.py"
+    "signature/loader.py"
+    "signature/mapping.py"
+    "signature/parser.py"
+    "__init__.py"
+    "feature.py"
+    )
+
+if (PYTHON_VERSION_MAJOR LESS 3)
+    list(APPEND shiboken_python_files
+         "backport_inspect.py"
+         "typing27.py"
+         )
+endif()
+
 ######################################################################
 # Adding sub directories to build
 ######################################################################
diff --git a/sources/shiboken2/data/docgenerator.1 b/sources/shiboken2/data/docgenerator.1
deleted file mode 100644
index f5a61f13..00000000
--- a/sources/shiboken2/data/docgenerator.1
+++ /dev/null
@@ -1,76 +0,0 @@
-.TH GENERATORRUNNER 1 "SEPTEMBER 2009" Linux "User Manuals"
-.SH NAME
-generatorrunner - plugin-based binding source code generator
-.SH SYNOPSIS
-.B generatorrunner \-\-generator-set=<plugin name> [options] header-file typesystem-file
-.SH DESCRIPTION
-.B generatorrunner
-is a utility that uses the information taken from APIExtractor
-related to the provided C++ headers and typesystem files and execute
-generators using this information. Generators are plugins and you need
-to specify one using the \-\-generator-set parameter. At the moment there
-are two generators available:
-
-.B qtdoc
-\- Generates Sphinx-based documentation for C++ libraries documented using
-.B qdoc
-documentation syntax, using the XML files created by the documentation tool
-.B (qdoc).
-Can be called supplying
-.B \-\-generator-set=qtdoc
-to
-.B generatorrunner
-or by calling the convenience executable
-.B docgenerator.
-
-Other plugins can be used with
-.B generatorrunner,
-provided that they follow the generator front-end specifications,
-and can be written to generate code or documentation for any target
-languague you desire. For more information about the generator front-end
-architecture and current limitations, refer to http://www.pyside.org/home-binding.
-
-.SH OPTIONS
-.SS "General options"
-.IP \-\-api-version=<version>
-Specify the supported api version used to generate the bindings.
-.IP \-\-debug-level=[sparse|medium|full]
-The amount of messages displayed.
-.IP \-\-documentation-only
-Only generates the documentation.
-.IP \-\-drop-type-entries="<TypeEntry0>[;TypeEntry1;...]"
-Semicolon separated list of type system entries (classes, namespaces, global functions and enums) to be dropped from generation.
-.IP \-\-help \fR,\fP \-h \fR,\fP  -?
-Prints the usage message.
-.IP \-\-project-file=<file>
-Text file containing a description of the binding project. Replaces and overrides command line arguments.
-.IP \-\-include\-paths=\fI<path>[:path:..]\fR
-The directories where the generator will search for the
-headers. Works like gcc's \-I flag.
-.IP \-\-license\-file=\fI[licensefile]\fR
-Template for copyright headers of generated files.
-.IP \-\-no\-supress\-warnings
-Show all warnings.
-.IP \-\-output\-directory=\fI[dir]\fR
-The directory where the generated files will be written.
-.IP \-\-silent
-Avoid printing any messages.
-.IP \-\-typesytem\-paths=\fI<path>[:path:..]\fR
-The directories where the generator will search for the
-external typesystems referred by the main one.
-.IP \-\-version
-Displays the current version.
-Drops support for named args.
-.SS "Specific to qtdoc plugin"
-.IP \-\-documentation\-code\-snippets\-dir
-Directory used to search code snippets used by the documentation
-.IP \-\-documentation\-data\-dir
-Directory with XML files generated by documentation tool (qdoc or Doxygen)
-.IP \-\-documentation\-out\-dir
-The directory where the generated documentation files will be written
-.IP \-\-library\-source\-dir
-Directory where library source code is located
-
-.SH AUTHORS
-Lauro Moura <lauro.neto at openbossa dot org>, Bruno Araujo <bruno.araujo at openbossa dot org>, Hugo Lima <hugo.lima at openbossa dot org>
-
diff --git a/sources/shiboken2/data/docgenerator.1 b/sources/shiboken2/data/docgenerator.1
new file mode 120000
index 00000000..c65282f9
--- /dev/null
+++ b/sources/shiboken2/data/docgenerator.1
@@ -0,0 +1 @@
+generatorrunner.1
\ No newline at end of file
diff --git a/sources/shiboken2/data/shiboken_helpers.cmake b/sources/shiboken2/data/shiboken_helpers.cmake
index 5e0c6ea7..ad32c3ed 100644
--- a/sources/shiboken2/data/shiboken_helpers.cmake
+++ b/sources/shiboken2/data/shiboken_helpers.cmake
@@ -39,7 +39,7 @@ macro(set_debug_build)
     endif()
 endmacro()
 
-macro(setup_sanitize_address)
+macro(set_sanitize_address)
     # Currently this does not check that the clang / gcc version used supports Address sanitizer,
     # so once again, use at your own risk.
     add_compile_options("-fsanitize=address" "-g" "-fno-omit-frame-pointer")
diff --git a/sources/shiboken2/doc/typesystem_codeinjection.rst b/sources/shiboken2/doc/typesystem_codeinjection.rst
index b0d5f385..83660950 100644
--- a/sources/shiboken2/doc/typesystem_codeinjection.rst
+++ b/sources/shiboken2/doc/typesystem_codeinjection.rst
@@ -112,7 +112,8 @@ Below is the example C++ class for whom wrapper code will be generated.
 
     .. code-block:: c++
 
-        class InjectCode {
+        class InjectCode
+        {
         public:
             InjectCode();
             double overloadedMethod(int arg);
@@ -124,6 +125,10 @@ From the C++ class, |project| will generate a ``injectcode_wrapper.cpp`` file
 with the binding code. The next section will use a simplified version of the
 generated wrapper code with the injection spots marked with comments.
 
+There are a number of placeholders indicated by a percent sign ``%``, which
+will be expanded when inserting the code. For a list, see
+:ref:`typesystemvariables`.
+
 Noteworthy Cases
 ----------------
 
@@ -196,7 +201,7 @@ class is polymorphic.
 
         int InjectCodeWrapper::virtualMethod(int arg)
         {
-            PyObject* method = BindingManager::instance().getOverride(this, "virtualMethod");
+            PyObject *method = BindingManager::instance().getOverride(this, "virtualMethod");
             if (!py_override)
                 return this->InjectCode::virtualMethod(arg);
 
@@ -228,10 +233,9 @@ own ``beginning`` and ``end`` code injections.
 
     .. code-block:: c++
 
-            static PyObject*
-            PyInjectCode_overloadedMethod(PyObject* self, PyObject* arg)
+            static PyObject *PyInjectCode_overloadedMethod(PyObject *self, PyObject *arg)
             {
-                PyObject* py_result = 0;
+                PyObject* py_result{};
                 if (PyFloat_Check(arg)) {
                     double cpp_arg0 = Shiboken::Converter<double >::toCpp(arg);
 
@@ -250,13 +254,13 @@ own ``beginning`` and ``end`` code injections.
                 } else goto PyInjectCode_overloadedMethod_TypeError;
 
                 if (PyErr_Occurred() || !py_result)
-                    return 0;
+                    return {};
 
                 return py_result;
 
                 PyInjectCode_overloadedMethod_TypeError:
                     PyErr_SetString(PyExc_TypeError, "'overloadedMethod()' called with wrong parameters.");
-                    return 0;
+                    return {};
             }
 
 
@@ -371,7 +375,7 @@ to prevent bad custom code to pass unnoticed.
             // INJECT-CODE: <typesystem><inject-code class="target" position="beginning">
             // Uses: do something before the module is created.
 
-            PyObject* module = Py_InitModule("MODULENAME", MODULENAME_methods);
+            PyObject *module = Py_InitModule("MODULENAME", MODULENAME_methods);
 
             (... initialization of wrapped classes, namespaces, functions and enums ...)
 
diff --git a/sources/shiboken2/doc/typesystem_conversionrule.rst b/sources/shiboken2/doc/typesystem_conversionrule.rst
index 27e7a72d..fc87a85c 100644
--- a/sources/shiboken2/doc/typesystem_conversionrule.rst
+++ b/sources/shiboken2/doc/typesystem_conversionrule.rst
@@ -32,6 +32,10 @@ conversion-rule
             </conversion-rule>
         </value-type>
 
+    The code can be inserted directly, via ``add-conversion`` (providing snippet
+    functionality) or via ``insert-template`` (XML template,
+    see :ref:`using-code-templates`).
+
     The example above show the structure of a complete conversion rule. Each of the
     child tags comprising the conversion rule are described in their own sections
     below.
diff --git a/sources/shiboken2/doc/typesystem_variables.rst b/sources/shiboken2/doc/typesystem_variables.rst
index 73d4dd12..3d463825 100644
--- a/sources/shiboken2/doc/typesystem_variables.rst
+++ b/sources/shiboken2/doc/typesystem_variables.rst
@@ -1,3 +1,5 @@
+.. _typesystemvariables:
+
 *********************
 Type System Variables
 *********************
@@ -24,9 +26,9 @@ Variables
 
 .. _arg_number:
 
-**%#**
+**%<number>**
 
-  Replaced by the name of a C++ argument in the position indicated by ``#``.
+  Replaced by the name of a C++ argument in the position indicated by ``<number>``.
   The argument counting starts with ``%1``, since ``%0`` represents the return
   variable name. If the number indicates a variable that was removed in the
   type system description, but there is a default value for it, this value will
@@ -214,13 +216,13 @@ Variables
 
 .. _pyarg:
 
-**%PYARG_#**
+**%PYARG_<number>**
 
-  Similar to ``%#``, but is replaced by the Python arguments (PyObjects)
+  Similar to ``%<number>``, but is replaced by the Python arguments (PyObjects)
   received by the Python wrapper method.
 
   If used in the context of a native code injection, i.e. in a virtual method
-  override, ``%PYARG_#`` will be translated to one item of the Python tuple
+  override, ``%PYARG_<number>`` will be translated to one item of the Python tuple
   holding the arguments that should be passed to the Python override for this
   virtual method.
 
diff --git a/sources/shiboken2/generator/generator.cpp b/sources/shiboken2/generator/generator.cpp
index dd56ab7c..60282828 100644
--- a/sources/shiboken2/generator/generator.cpp
+++ b/sources/shiboken2/generator/generator.cpp
@@ -43,6 +43,8 @@
 #include <QDebug>
 #include <typedatabase.h>
 
+static const char ENABLE_PYSIDE_EXTENSIONS[] = "enable-pyside-extensions";
+
 /**
  * DefaultValue is used for storing default values of types for which code is
  * generated in different contexts:
@@ -169,6 +171,7 @@ struct Generator::GeneratorPrivate
     QVector<const AbstractMetaType *> instantiatedContainers;
     QVector<const AbstractMetaType *> instantiatedSmartPointers;
     AbstractMetaClassList m_invisibleTopNamespaces;
+    bool m_usePySideExtensions = false;
 };
 
 Generator::Generator() : m_d(new GeneratorPrivate)
@@ -276,24 +279,24 @@ void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType
         return;
 
     }
-    QString typeName = getSimplifiedContainerTypeName(type);
     if (isContainer) {
+        QString typeName = getSimplifiedContainerTypeName(type);
         if (!m_d->instantiatedContainersNames.contains(typeName)) {
             m_d->instantiatedContainersNames.append(typeName);
             m_d->instantiatedContainers.append(type);
         }
-    } else {
-        // Is smart pointer. Check if the (const?) pointee is already known
-        auto pt = pointeeTypeEntry(type);
-        const bool present =
-            std::any_of(m_d->instantiatedSmartPointers.cbegin(), m_d->instantiatedSmartPointers.cend(),
-                        [pt] (const AbstractMetaType *t) {
-                            return pointeeTypeEntry(t) == pt;
-                        });
-        if (!present)
-            m_d->instantiatedSmartPointers.append(canonicalSmartPtrInstantiation(type));
+        return;
     }
-
+    // Is smart pointer. Check if the (const?) pointee is already known for the given
+    // smart pointer type entry.
+    auto pt = pointeeTypeEntry(type);
+    const bool present =
+        std::any_of(m_d->instantiatedSmartPointers.cbegin(), m_d->instantiatedSmartPointers.cend(),
+                    [typeEntry, pt] (const AbstractMetaType *t) {
+                        return t->typeEntry() == typeEntry && pointeeTypeEntry(t) == pt;
+                    });
+    if (!present)
+        m_d->instantiatedSmartPointers.append(canonicalSmartPtrInstantiation(type));
 }
 
 void Generator::collectInstantiatedContainersAndSmartPointers(const AbstractMetaFunction *func)
@@ -339,11 +342,17 @@ QVector<const AbstractMetaType *> Generator::instantiatedSmartPointers() const
 
 Generator::OptionDescriptions Generator::options() const
 {
-    return OptionDescriptions();
+    return {
+        {QLatin1String(ENABLE_PYSIDE_EXTENSIONS),
+         QLatin1String("Enable PySide extensions, such as support for signal/slots,\n"
+                       "use this if you are creating a binding for a Qt-based library.")}
+    };
 }
 
-bool Generator::handleOption(const QString & /* key */, const QString & /* value */)
+bool Generator::handleOption(const QString & key, const QString & /* value */)
 {
+    if (key == QLatin1String(ENABLE_PYSIDE_EXTENSIONS))
+        return ( m_d->m_usePySideExtensions = true);
     return false;
 }
 
@@ -615,6 +624,11 @@ bool Generator::isVoidPointer(const AbstractMetaType *type)
             && type->name() == QLatin1String("void");
 }
 
+bool Generator::usePySideExtensions() const
+{
+    return m_d->m_usePySideExtensions;
+}
+
 QString Generator::getFullTypeName(const TypeEntry *type) const
 {
     QString result = type->qualifiedCppName();
diff --git a/sources/shiboken2/generator/generator.h b/sources/shiboken2/generator/generator.h
index cf6df528..0cedbd25 100644
--- a/sources/shiboken2/generator/generator.h
+++ b/sources/shiboken2/generator/generator.h
@@ -244,6 +244,9 @@ public:
     /// Returns the generator's name. Used for cosmetic purposes.
     virtual const char *name() const = 0;
 
+    /// Returns true if the user enabled PySide extensions (command line option)
+    bool usePySideExtensions() const;
+
     /**
      *  Retrieves the name of the currently processed module.
      *  While package name is a complete package idetification, e.g. 'PySide.QtCore',
diff --git a/sources/shiboken2/generator/main.cpp b/sources/shiboken2/generator/main.cpp
index 8d819c76..fa41cb62 100644
--- a/sources/shiboken2/generator/main.cpp
+++ b/sources/shiboken2/generator/main.cpp
@@ -109,7 +109,7 @@ static bool processProjectFile(QFile &projectFile, CommandLineArguments &args)
         QByteArray key;
         QString value;
         if (split > 0) {
-            key = line.left(split - 1).trimmed();
+            key = line.left(split).trimmed();
             value = QString::fromUtf8(line.mid(split + 1).trimmed());
         } else {
             key = line;
@@ -612,8 +612,7 @@ int main(int argc, char *argv[])
     extractor.setCppFileNames(cppFileNames);
     extractor.setTypeSystem(typeSystemFileName);
 
-    auto shibokenGenerator = dynamic_cast<const ShibokenGenerator *>(generators.constFirst().data());
-    const bool usePySideExtensions = shibokenGenerator && shibokenGenerator->usePySideExtensions();
+    const bool usePySideExtensions = generators.constFirst().data()->usePySideExtensions();
 
     if (!extractor.run(usePySideExtensions)) {
         errorPrint(QLatin1String("Error running ApiExtractor."));
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
index 5e75cbf8..1b7c786d 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
@@ -1588,30 +1588,6 @@ static void writeInheritedByList(QTextStream& s, const AbstractMetaClass* metaCl
     s << classes.join(QLatin1String(", ")) << Qt::endl << Qt::endl;
 }
 
-// Extract the <brief> section from a WebXML (class) documentation and remove it
-// from the source.
-static bool extractBrief(Documentation *sourceDoc, Documentation *brief)
-{
-    if (sourceDoc->format() != Documentation::Native)
-        return false;
-    QString value = sourceDoc->value();
-    const int briefStart = value.indexOf(briefStartElement());
-    if (briefStart < 0)
-        return false;
-    const int briefEnd = value.indexOf(briefEndElement(), briefStart + briefStartElement().size());
-    if (briefEnd < briefStart)
-        return false;
-    const int briefLength = briefEnd + briefEndElement().size() - briefStart;
-    brief->setFormat(Documentation::Native);
-    QString briefValue = value.mid(briefStart, briefLength);
-    briefValue.insert(briefValue.size() - briefEndElement().size(),
-                      QLatin1String("<rst> More_...</rst>"));
-    brief->setValue(briefValue);
-    value.remove(briefStart, briefLength);
-    sourceDoc->setValue(value);
-    return true;
-}
-
 void QtDocGenerator::generateClass(QTextStream &s, const GeneratorContext &classContext)
 {
     const AbstractMetaClass *metaClass = classContext.metaClass();
@@ -1630,9 +1606,8 @@ void QtDocGenerator::generateClass(QTextStream &s, const GeneratorContext &class
     s << Pad('*', className.count()) << Qt::endl << Qt::endl;
 
     auto documentation = metaClass->documentation();
-    Documentation brief;
-    if (extractBrief(&documentation, &brief))
-        writeFormattedText(s, brief.value(), metaClass);
+    if (documentation.hasBrief())
+        writeFormattedText(s, documentation.value(Documentation::Brief), metaClass);
 
     s << ".. inheritance-diagram:: " << metaClass->fullName() << Qt::endl
       << "    :parts: 2" << Qt::endl << Qt::endl;
@@ -1659,7 +1634,7 @@ void QtDocGenerator::generateClass(QTextStream &s, const GeneratorContext &class
 
     writeInjectDocumentation(s, TypeSystem::DocModificationPrepend, metaClass, nullptr);
     if (!writeInjectDocumentation(s, TypeSystem::DocModificationReplace, metaClass, nullptr))
-        writeFormattedText(s, documentation.value(), metaClass);
+        writeFormattedText(s, documentation.value(Documentation::Detailed), metaClass);
 
     if (!metaClass->isNamespace())
         writeConstructors(s, metaClass);
@@ -1972,7 +1947,7 @@ bool QtDocGenerator::writeInjectDocumentation(QTextStream& s,
                     continue;
 
                 doc.setValue(mod.code(), Documentation::Detailed, fmt);
-                writeFormattedText(s, doc.value(), cppClass);
+                writeFormattedText(s, doc, cppClass);
                 didSomething = true;
             }
         }
@@ -2378,7 +2353,8 @@ bool QtDocGenerator::doSetup()
 
 Generator::OptionDescriptions QtDocGenerator::options() const
 {
-    return OptionDescriptions()
+    OptionDescriptions result = Generator::options();
+    result
         << qMakePair(QLatin1String("doc-parser=<parser>"),
                      QLatin1String("The documentation parser used to interpret the documentation\n"
                                    "input files (qdoc|doxygen)"))
@@ -2393,10 +2369,13 @@ Generator::OptionDescriptions QtDocGenerator::options() const
         << qMakePair(additionalDocumentationOption() + QLatin1String("=<file>"),
                      QLatin1String("List of additional XML files to be converted to .rst files\n"
                                    "(for example, tutorials)."));
+    return result;
 }
 
 bool QtDocGenerator::handleOption(const QString &key, const QString &value)
 {
+    if (Generator::handleOption(key, value))
+        return true;
     if (key == QLatin1String("library-source-dir")) {
         m_libSourceDir = value;
         return true;
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 05d9d97d..75b75d24 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -359,7 +359,6 @@ void CppGenerator::generateClass(QTextStream &s, const GeneratorContext &classCo
             << "#include <pyside.h>\n"
             << "#include <pysideqenum.h>\n"
             << "#include <feature_select.h>\n"
-            << "#include <qapp_macro.h>\n\n"
             << "QT_WARNING_DISABLE_DEPRECATED\n\n";
      }
 
@@ -763,6 +762,9 @@ void CppGenerator::generateClass(QTextStream &s, const GeneratorContext &classCo
     writeConverterFunctions(s, metaClass, classContext);
     writeClassRegister(s, metaClass, classContext, signatureStream);
 
+    if (metaClass->hasStaticFields())
+        writeStaticFieldInitialization(s, metaClass);
+
     // class inject-code native/end
     if (!metaClass->typeEntry()->codeSnips().isEmpty()) {
         writeClassCodeSnips(s, metaClass->typeEntry()->codeSnips(),
@@ -1059,7 +1061,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
 
             QString argConv;
             QTextStream ac(&argConv);
-            auto argType = static_cast<const PrimitiveTypeEntry *>(arg->type()->typeEntry());
+            const auto *argType = arg->type()->typeEntry();
             bool convert = argType->isObject()
                             || argType->isValue()
                             || arg->type()->isValuePointer()
@@ -1068,11 +1070,11 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s,
                             || argType->isEnum()
                             || argType->isContainer()
                             || arg->type()->referenceType() == LValueReference;
-
             if (!convert && argType->isPrimitive()) {
-                if (argType->basicReferencedTypeEntry())
-                    argType = argType->basicReferencedTypeEntry();
-                convert = !m_formatUnits.contains(argType->name());
+                const auto *pte = static_cast<const PrimitiveTypeEntry *>(argType);
+                if (pte->basicReferencedTypeEntry())
+                    pte = pte->basicReferencedTypeEntry();
+                convert = !m_formatUnits.contains(pte->name());
             }
 
             Indentor nested;
@@ -1831,6 +1833,11 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over
         usesNamedArguments = rfunc->isCallOperator() || overloadData.hasArgumentWithDefaultValue();
     }
 
+    s << INDENT << "PyObject *errInfo{};\n";
+    s << INDENT << "SBK_UNUSED(errInfo)\n";
+    s << INDENT << "static const char *fullName = \""
+                << fullPythonFunctionName(rfunc, true) << "\";\n";
+    s << INDENT << "SBK_UNUSED(fullName)\n";
     if (maxArgs > 0) {
         s << INDENT << "int overloadId = -1;\n";
         s << INDENT << "PythonToCppFunc " << PYTHON_TO_CPP_VAR;
@@ -1845,9 +1852,6 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over
         writeUnusedVariableCast(s, QLatin1String(PYTHON_TO_CPP_VAR));
     }
 
-    if (usesNamedArguments && !rfunc->isCallOperator())
-        s << INDENT << "const Py_ssize_t numNamedArgs = (kwds ? PyDict_Size(kwds) : 0);\n";
-
     if (initPythonArguments) {
         s << INDENT << "const Py_ssize_t numArgs = ";
         if (minArgs == 0 && maxArgs == 1 && !rfunc->isConstructor() && !pythonFunctionWrapperUsesListOfArguments(overloadData))
@@ -1869,28 +1873,8 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
     s << "static int\n";
     s << cpythonFunctionName(rfunc) << "(PyObject *self, PyObject *args, PyObject *kwds)\n{\n";
 
-    QSet<QString> argNamesSet;
-    if (usePySideExtensions() && metaClass->isQObject()) {
-        // Write argNames variable with all known argument names.
-        const OverloadData::MetaFunctionList &overloads = overloadData.overloads();
-        for (const AbstractMetaFunction *func : overloads) {
-            const AbstractMetaArgumentList &arguments = func->arguments();
-            for (const AbstractMetaArgument *arg : arguments) {
-                if (arg->defaultValueExpression().isEmpty() || func->argumentRemoved(arg->argumentIndex() + 1))
-                    continue;
-                argNamesSet << arg->name();
-            }
-        }
-        QStringList argNamesList = argNamesSet.values();
-        std::sort(argNamesList.begin(), argNamesList.end());
-        if (argNamesList.isEmpty()) {
-            s << INDENT << "const char **argNames{};\n";
-        } else {
-            s << INDENT << "const char *argNames[] = {\""
-                << argNamesList.join(QLatin1String("\", \"")) << "\"};\n";
-        }
+    if (usePySideExtensions() && metaClass->isQObject())
         s << INDENT << "const QMetaObject *metaObject;\n";
-    }
 
     s << INDENT << "SbkObject *sbkSelf = reinterpret_cast<SbkObject *>(self);\n";
 
@@ -1916,6 +1900,10 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
             s << outdent(INDENT) << '\n';
     }
 
+    // PYSIDE-1478: Switching must also happen at object creation time.
+    if (usePySideExtensions())
+        s << "PySide::Feature::Select(self);\n";
+
     writeMethodWrapperPreamble(s, overloadData, classContext);
 
     s << Qt::endl;
@@ -1930,6 +1918,8 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
     {
         Indentation indent(INDENT);
         s << INDENT << "delete cptr;\n";
+        if (overloadData.maxArgs() > 0)
+            s << INDENT << "Py_XDECREF(errInfo);\n";
         s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
     }
     s << INDENT << "}\n";
@@ -1950,19 +1940,24 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
     s << INDENT << "if (Shiboken::BindingManager::instance().hasWrapper(cptr)) {\n";
     {
         Indentation indent(INDENT);
-        s << INDENT << "Shiboken::BindingManager::instance().releaseWrapper(Shiboken::BindingManager::instance().retrieveWrapper(cptr));\n";
+        s << INDENT << "Shiboken::BindingManager::instance().releaseWrapper("
+                       "Shiboken::BindingManager::instance().retrieveWrapper(cptr));\n";
     }
     s << INDENT << "}\n";
     s << INDENT << "Shiboken::BindingManager::instance().registerWrapper(sbkSelf, cptr);\n";
 
     // Create metaObject and register signal/slot
+    bool errHandlerNeeded = overloadData.maxArgs() > 0;
     if (metaClass->isQObject() && usePySideExtensions()) {
+        errHandlerNeeded = true;
         s << Qt::endl << INDENT << "// QObject setup\n";
         s << INDENT << "PySide::Signal::updateSourceObject(self);\n";
         s << INDENT << "metaObject = cptr->metaObject(); // <- init python qt properties\n";
-        s << INDENT << "if (kwds && !PySide::fillQtProperties(self, metaObject, kwds, argNames, "
-            << argNamesSet.count() << "))\n" << indent(INDENT)
-            << INDENT << returnStatement(m_currentErrorCode) << '\n' << outdent(INDENT);
+        s << INDENT << "if (errInfo && PyDict_Check(errInfo)) {\n" << indent(INDENT)
+            << INDENT << "if (!PySide::fillQtProperties(self, metaObject, errInfo))\n" << indent(INDENT)
+                << INDENT << "goto " << cpythonFunctionName(rfunc) << "_TypeError;\n" << outdent(INDENT)
+            << INDENT << "Py_DECREF(errInfo);\n" << outdent(INDENT)
+        << INDENT << "};\n";
     }
 
     // Constructor code injections, position=end
@@ -1990,7 +1985,8 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
                         Indentation indent(INDENT);
                         writeCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionEnd, TypeSystem::TargetLangCode, func);
                     }
-                    s << INDENT << "}\n";
+                    s << INDENT << "}\n"
+                        << INDENT << "break;\n";
                     break;
                 }
             }
@@ -2000,7 +1996,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
 
     s << Qt::endl;
     s << Qt::endl << INDENT << "return 1;\n";
-    if (overloadData.maxArgs() > 0)
+    if (errHandlerNeeded)
         writeErrorSection(s, overloadData);
     s<< "}\n\n";
 }
@@ -2149,11 +2145,14 @@ void CppGenerator::writeArgumentsInitializer(QTextStream &s, OverloadData &overl
     bool ownerClassIsQObject = rfunc->ownerClass() && rfunc->ownerClass()->isQObject() && rfunc->isConstructor();
     if (usesNamedArguments) {
         if (!ownerClassIsQObject) {
-            s << INDENT << "if (numArgs" << (overloadData.hasArgumentWithDefaultValue() ? " + numNamedArgs" : "") << " > " << maxArgs << ") {\n";
+            s << INDENT << "if (numArgs > " << maxArgs << ") {\n";
             {
                 Indentation indent(INDENT);
-                s << INDENT << "PyErr_SetString(PyExc_TypeError, \"" << fullPythonFunctionName(rfunc) << "(): too many arguments\");\n";
-                s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
+                s << INDENT << "static PyObject *const too_many = "
+                                   "Shiboken::String::createStaticString(\">\");\n";
+                s << INDENT << "errInfo = too_many;\n";
+                s << INDENT << "Py_INCREF(errInfo);\n";
+                s << INDENT << "goto " << cpythonFunctionName(rfunc) << "_TypeError;\n";
             }
             s << INDENT << '}';
         }
@@ -2165,8 +2164,11 @@ void CppGenerator::writeArgumentsInitializer(QTextStream &s, OverloadData &overl
             s << "if (numArgs < " << minArgs << ") {\n";
             {
                 Indentation indent(INDENT);
-                s << INDENT << "PyErr_SetString(PyExc_TypeError, \"" << fullPythonFunctionName(rfunc) << "(): not enough arguments\");\n";
-                s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
+                s << INDENT << "static PyObject *const too_few = "
+                                   "Shiboken::String::createStaticString(\"<\");\n";
+                s << INDENT << "errInfo = too_few;\n";
+                s << INDENT << "Py_INCREF(errInfo);\n";
+                s << INDENT << "goto " << cpythonFunctionName(rfunc) << "_TypeError;\n";
             }
             s << INDENT << '}';
         }
@@ -2300,11 +2302,13 @@ void CppGenerator::writeErrorSection(QTextStream &s, OverloadData &overloadData)
     const AbstractMetaFunction *rfunc = overloadData.referenceFunction();
     s << Qt::endl << INDENT << cpythonFunctionName(rfunc) << "_TypeError:\n";
     Indentation indentation(INDENT);
-    QString funcName = fullPythonFunctionName(rfunc);
+    QString funcName = fullPythonFunctionName(rfunc, true);
 
     QString argsVar = pythonFunctionWrapperUsesListOfArguments(overloadData)
         ? QLatin1String("args") : QLatin1String(PYTHON_ARG);
-    s << INDENT << "Shiboken::setErrorAboutWrongArguments(" << argsVar << ", \"" << funcName << "\");\n";
+    s << INDENT << "Shiboken::setErrorAboutWrongArguments(" << argsVar
+                << ", fullName, errInfo);\n";
+    s << INDENT << "Py_XDECREF(errInfo);\n";
     s << INDENT << "return " << m_currentErrorCode << ";\n";
 }
 
@@ -2821,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("!")));
@@ -2908,7 +2912,7 @@ void CppGenerator::writeSingleFunctionCall(QTextStream &s,
     bool usePyArgs = pythonFunctionWrapperUsesListOfArguments(overloadData);
 
     // Handle named arguments.
-    writeNamedArgumentResolution(s, func, usePyArgs);
+    writeNamedArgumentResolution(s, func, usePyArgs, overloadData);
 
     bool injectCodeCallsFunc = injectedCodeCallsCppFunction(context, func);
     bool mayHaveUnunsedArguments = !func->isUserAdded() && func->hasInjectedCode() && injectCodeCallsFunc;
@@ -3231,33 +3235,46 @@ void CppGenerator::writeAddPythonToCppConversion(QTextStream &s, const QString &
     s << ");\n";
 }
 
-void CppGenerator::writeNamedArgumentResolution(QTextStream &s, const AbstractMetaFunction *func, bool usePyArgs)
+void CppGenerator::writeNamedArgumentResolution(QTextStream &s, const AbstractMetaFunction *func,
+                                                bool usePyArgs, const OverloadData &overloadData)
 {
     const AbstractMetaArgumentList &args = OverloadData::getArgumentsWithDefaultValues(func);
-    if (args.isEmpty())
+    if (args.isEmpty()) {
+        if (overloadData.hasArgumentWithDefaultValue()) {
+            s << INDENT << "if (kwds) {\n";
+            {
+                Indentation indent(INDENT);
+                s << INDENT << "errInfo = kwds;\n";
+                s << INDENT << "Py_INCREF(errInfo);\n";
+                s << INDENT << "goto " << cpythonFunctionName(func) << "_TypeError;\n";
+            }
+            s << INDENT << "}\n";
+        }
         return;
-
-    QString pyErrString(QLatin1String("PyErr_SetString(PyExc_TypeError, \"") + fullPythonFunctionName(func)
-                        + QLatin1String("(): got multiple values for keyword argument '%1'.\");"));
+    }
 
     s << INDENT << "if (kwds) {\n";
     {
         Indentation indent(INDENT);
-        s << INDENT << "PyObject *keyName = nullptr;\n";
-        s << INDENT << "PyObject *value = nullptr;\n";
+        s << INDENT << "PyObject *value{};\n";
+        s << INDENT << "PyObject *kwds_dup = PyDict_Copy(kwds);\n";
         for (const AbstractMetaArgument *arg : args) {
-            int pyArgIndex = arg->argumentIndex() - OverloadData::numberOfRemovedArguments(func, arg->argumentIndex());
+            const int pyArgIndex = arg->argumentIndex()
+                - OverloadData::numberOfRemovedArguments(func, arg->argumentIndex());
             QString pyArgName = usePyArgs ? pythonArgsAt(pyArgIndex) : QLatin1String(PYTHON_ARG);
-            s << INDENT << "keyName = Py_BuildValue(\"s\",\"" << arg->name() << "\");\n";
-            s << INDENT << "if (PyDict_Contains(kwds, keyName)) {\n";
+            QString pyKeyName = QLatin1String("key_") + arg->name();
+            s << INDENT << "static PyObject *const " << pyKeyName
+                        << " = Shiboken::String::createStaticString(\"" << arg->name() << "\");\n";
+            s << INDENT << "if (PyDict_Contains(kwds, " << pyKeyName << ")) {\n";
             {
                 Indentation indent(INDENT);
-                s << INDENT << "value = PyDict_GetItem(kwds, keyName);\n";
+                s << INDENT << "value = PyDict_GetItem(kwds, " << pyKeyName << ");\n";
                 s << INDENT << "if (value && " << pyArgName << ") {\n";
                 {
                     Indentation indent(INDENT);
-                    s << INDENT << pyErrString.arg(arg->name()) << Qt::endl;
-                    s << INDENT << returnStatement(m_currentErrorCode) << Qt::endl;
+                    s << INDENT << "errInfo = " << pyKeyName << ";\n";
+                    s << INDENT << "Py_INCREF(errInfo);\n";
+                    s << INDENT << "goto " << cpythonFunctionName(func) << "_TypeError;\n";
                 }
                 s << INDENT << "}\n";
                 s << INDENT << "if (value) {\n";
@@ -3265,7 +3282,8 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream &s, const AbstractMe
                     Indentation indent(INDENT);
                     s << INDENT << pyArgName << " = value;\n";
                     s << INDENT << "if (!";
-                    writeTypeCheck(s, arg->type(), pyArgName, isNumber(arg->type()->typeEntry()), func->typeReplaced(arg->argumentIndex() + 1));
+                    writeTypeCheck(s, arg->type(), pyArgName, isNumber(arg->type()->typeEntry()),
+                                   func->typeReplaced(arg->argumentIndex() + 1));
                     s << ")\n";
                     {
                         Indentation indent(INDENT);
@@ -3273,9 +3291,29 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream &s, const AbstractMe
                     }
                 }
                 s << INDENT << "}\n";
+                s << INDENT << "PyDict_DelItem(kwds_dup, " << pyKeyName << ");\n";
             }
             s << INDENT << "}\n";
         }
+        // PYSIDE-1305: Handle keyword args correctly.
+        // Normal functions handle their parameters immediately.
+        // For constructors that are QObject, we need to delay that
+        // until extra keyword signals and properties are handled.
+        s << INDENT << "if (PyDict_Size(kwds_dup) > 0) {\n";
+        {
+            Indentation indent(INDENT);
+            s << INDENT << "errInfo = kwds_dup;\n";
+            if (!(func->isConstructor() && func->ownerClass()->isQObject()))
+                s << INDENT << "goto " << cpythonFunctionName(func) << "_TypeError;\n";
+            else
+                s << INDENT << "// fall through to handle extra keyword signals and properties\n";
+        }
+        s << INDENT << "} else {\n";
+        {
+            Indentation indent(INDENT);
+            s << INDENT << "Py_DECREF(kwds_dup);\n";
+        }
+        s << INDENT << "}\n";
     }
     s << INDENT << "}\n";
 }
@@ -4162,15 +4200,14 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
             tp_new = QLatin1String("SbkDummyNew /* PYSIDE-595: Prevent replacement "
                                    "of \"0\" with base->tp_new. */");
         }
-        tp_flags.append(QLatin1String("|Py_TPFLAGS_HAVE_GC"));
     }
     else if (isQApp) {
         tp_new = QLatin1String("SbkQAppTpNew"); // PYSIDE-571: need singleton app
     }
     else {
         tp_new = QLatin1String("SbkObjectTpNew");
-        tp_flags.append(QLatin1String("|Py_TPFLAGS_HAVE_GC"));
     }
+    tp_flags.append(QLatin1String("|Py_TPFLAGS_HAVE_GC"));
 
     QString tp_richcompare;
     if (!metaClass->isNamespace() && metaClass->hasComparisonOperatorOverload())
@@ -4895,7 +4932,7 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction
 {
     OverloadData overloadData(overloads, this);
     const AbstractMetaFunction *rfunc = overloadData.referenceFunction();
-    QString funcName = fullPythonFunctionName(rfunc);
+    QString funcName = fullPythonFunctionName(rfunc, false);
 
     int idx = overloads.length() - 1;
     bool multiple = idx > 0;
@@ -5193,12 +5230,17 @@ void CppGenerator::writeFlagsBinaryOperator(QTextStream &s, const AbstractMetaEn
         << ">(int(PyLong_AsLong(self)));\n";
     s << INDENT << "cppArg = static_cast<" << flagsEntry->originalName() << ">(int(PyLong_AsLong("
         << PYTHON_ARG << ")));\n";
+        // PYSIDE-1436: Need to error check self as well because operators are used
+        //              sometimes with swapped args.
+    s << INDENT << "if (PyErr_Occurred())\n" << INDENT << "return nullptr;\n";
     s << "#else\n";
     s << INDENT << CPP_SELF_VAR << " = static_cast<::" << flagsEntry->originalName()
         << ">(int(PyInt_AsLong(self)));\n";
     s << INDENT << "cppArg = static_cast<" << flagsEntry->originalName()
         << ">(int(PyInt_AsLong(" << PYTHON_ARG << ")));\n";
     s << "#endif\n\n";
+    s << INDENT << "if (PyErr_Occurred())\n" << indent(INDENT)
+        << INDENT << "return nullptr;\n" << outdent(INDENT);
     s << INDENT << "cppResult = " << CPP_SELF_VAR << " " << cppOpName << " cppArg;\n";
     s << INDENT << "return ";
     writeToPythonConversion(s, flagsType, nullptr, QLatin1String("cppResult"));
@@ -5245,6 +5287,12 @@ QString CppGenerator::getSimpleClassInitFunctionName(const AbstractMetaClass *me
     return initFunctionName;
 }
 
+QString CppGenerator::getSimpleClassStaticFieldsInitFunctionName(const AbstractMetaClass *metaClass) const
+{
+    return QLatin1String("init_") + getSimpleClassInitFunctionName(metaClass)
+        + QLatin1String("StaticFields");
+}
+
 QString CppGenerator::getInitFunctionName(const GeneratorContext &context) const
 {
     return !context.forSmartPointer()
@@ -5447,18 +5495,6 @@ void CppGenerator::writeClassRegister(QTextStream &s,
     if (metaClass->hasSignals())
         writeSignalInitialization(s, metaClass);
 
-    // Write static fields
-    const AbstractMetaFieldList &fields = metaClass->fields();
-    for (const AbstractMetaField *field : fields) {
-        if (!field->isStatic())
-            continue;
-        s << INDENT << QLatin1String("PyDict_SetItemString(reinterpret_cast<PyTypeObject *>(") + cpythonTypeName(metaClass) + QLatin1String(")->tp_dict, \"");
-        s << field->name() << "\", ";
-        writeToPythonConversion(s, field->type(), metaClass, metaClass->qualifiedCppName() + QLatin1String("::") + field->name());
-        s << ");\n";
-    }
-    s << Qt::endl;
-
     // class inject-code target/end
     if (!classTypeEntry->codeSnips().isEmpty()) {
         s << Qt::endl;
@@ -5488,6 +5524,29 @@ void CppGenerator::writeClassRegister(QTextStream &s,
     s << "}\n";
 }
 
+void CppGenerator::writeStaticFieldInitialization(QTextStream &s,
+                                                  const AbstractMetaClass *metaClass)
+{
+    s << "\nvoid " << getSimpleClassStaticFieldsInitFunctionName(metaClass)
+        << "()\n{\n" << INDENT << "auto dict = reinterpret_cast<PyTypeObject *>("
+        << cpythonTypeName(metaClass) << ")->tp_dict;\n";
+    const auto &fields = metaClass->fields();
+    for (const AbstractMetaField *field : fields) {
+        if (field->isStatic()) {
+            QString cppName = field->originalName();
+            if (cppName.isEmpty())
+                cppName = field->name();
+            const QString name = field->enclosingClass()->qualifiedCppName()
+                + QLatin1String("::") + cppName;
+            s << INDENT << "PyDict_SetItemString(dict, \"" << field->name()
+              << "\",\n" << INDENT << "                     ";
+            writeToPythonConversion(s, field->type(), metaClass, name);
+            s << ");\n";
+        }
+    }
+    s << "\n}\n";
+}
+
 void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, const GeneratorContext &context) const
 {
     const AbstractMetaClass *metaClass = context.metaClass();
@@ -5898,11 +5957,18 @@ bool CppGenerator::finishGeneration()
     }
     const AbstractMetaClassList lst = classesTopologicalSorted(additionalDependencies);
 
+    QVector<const AbstractMetaClass *> classesWithStaticFields;
+
     for (const AbstractMetaClass *cls : lst){
         if (shouldGenerate(cls)) {
             writeInitFunc(s_classInitDecl, s_classPythonDefines, INDENT,
                           getSimpleClassInitFunctionName(cls),
                           cls->typeEntry()->targetLangEnclosingEntry());
+            if (cls->hasStaticFields()) {
+                s_classInitDecl << "void "
+                    << getSimpleClassStaticFieldsInitFunctionName(cls) << "();\n";
+                classesWithStaticFields.append(cls);
+            }
         }
     }
 
@@ -5936,7 +6002,6 @@ bool CppGenerator::finishGeneration()
         s << "#include <pyside.h>\n";
         s << "#include <pysideqenum.h>\n";
         s << "#include <feature_select.h>\n";
-        s << "#include <qapp_macro.h>\n";
     }
 
     s << "#include \"" << getModuleHeaderFileName() << '"' << Qt::endl << Qt::endl;
@@ -6205,6 +6270,14 @@ bool CppGenerator::finishGeneration()
         s << INDENT << "Shiboken::Module::registerTypes(module, " << cppApiVariableName() << ");\n";
     s << INDENT << "Shiboken::Module::registerTypeConverters(module, " << convertersVariableName() << ");\n";
 
+    // Static fields are registered last since they may use converter functions
+    // of the previously registered types (PYSIDE-1529).
+    if (!classesWithStaticFields.isEmpty()) {
+        s << "\n// Static field initialization\n";
+        for (auto cls : qAsConst(classesWithStaticFields))
+            s << getSimpleClassStaticFieldsInitFunctionName(cls) << "();\n";
+    }
+
     s << '\n' << INDENT << "if (PyErr_Occurred()) {\n" << indent(INDENT)
         << INDENT << "PyErr_Print();\n"
         << INDENT << "Py_FatalError(\"can't initialize module " << moduleName() << "\");\n"
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.h b/sources/shiboken2/generator/shiboken2/cppgenerator.h
index 41bd17f2..64396d61 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.h
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.h
@@ -247,7 +247,8 @@ private:
 
     void writeAddPythonToCppConversion(QTextStream &s, const QString &converterVar, const QString &pythonToCppFunc, const QString &isConvertibleFunc);
 
-    void writeNamedArgumentResolution(QTextStream &s, const AbstractMetaFunction *func, bool usePyArgs);
+    void writeNamedArgumentResolution(QTextStream &s, const AbstractMetaFunction *func,
+                                      bool usePyArgs, const OverloadData &overloadData);
 
     /// Returns a string containing the name of an argument for the given function and argument index.
     QString argumentNameFromIndex(const AbstractMetaFunction *func, int argIndex, const AbstractMetaClass **wrappedClass);
@@ -256,6 +257,7 @@ private:
 
     QString getInitFunctionName(const GeneratorContext &context) const;
     QString getSimpleClassInitFunctionName(const AbstractMetaClass *metaClass) const;
+    QString getSimpleClassStaticFieldsInitFunctionName(const AbstractMetaClass *metaClass) const;
 
     void writeSignatureStrings(QTextStream &s, QTextStream &signatureStream,
                                const QString &arrayName,
@@ -264,6 +266,8 @@ private:
                             const AbstractMetaClass *metaClass,
                             const GeneratorContext &classContext,
                             QTextStream &signatureStream);
+    void writeStaticFieldInitialization(QTextStream &s,
+                                        const AbstractMetaClass *metaClass);
     void writeClassDefinition(QTextStream &s,
                               const AbstractMetaClass *metaClass,
                               const GeneratorContext &classContext);
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index 5d8685b9..42850e87 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -46,7 +46,6 @@
 static const char AVOID_PROTECTED_HACK[] = "avoid-protected-hack";
 static const char PARENT_CTOR_HEURISTIC[] = "enable-parent-ctor-heuristic";
 static const char RETURN_VALUE_HEURISTIC[] = "enable-return-value-heuristic";
-static const char ENABLE_PYSIDE_EXTENSIONS[] = "enable-pyside-extensions";
 static const char DISABLE_VERBOSE_ERROR_MESSAGES[] = "disable-verbose-error-messages";
 static const char USE_ISNULL_AS_NB_NONZERO[] = "use-isnull-as-nb_nonzero";
 static const char WRAPPER_DIAGNOSTICS[] = "wrapper-diagnostics";
@@ -356,7 +355,7 @@ QString ShibokenGenerator::fullPythonClassName(const AbstractMetaClass *metaClas
     return fullClassName;
 }
 
-QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunction *func)
+QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunction *func, bool forceFunc)
 {
     QString funcName;
     if (func->isOperatorOverload())
@@ -365,10 +364,14 @@ QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunction *fu
        funcName = func->name();
     if (func->ownerClass()) {
         QString fullClassName = fullPythonClassName(func->ownerClass());
-        if (func->isConstructor())
+        if (func->isConstructor()) {
             funcName = fullClassName;
-        else
+            if (forceFunc)
+                funcName.append(QLatin1String(".__init__"));
+        }
+        else {
             funcName.prepend(fullClassName + QLatin1Char('.'));
+        }
     }
     else {
         funcName = packageName() + QLatin1Char('.') + func->name();
@@ -2563,7 +2566,8 @@ AbstractMetaFunctionList ShibokenGenerator::getFunctionOverloads(const AbstractM
 
 Generator::OptionDescriptions ShibokenGenerator::options() const
 {
-    return OptionDescriptions()
+    OptionDescriptions result = Generator::options();
+    result
         << qMakePair(QLatin1String(AVOID_PROTECTED_HACK),
                      QLatin1String("Avoid the use of the '#define protected public' hack."))
         << qMakePair(QLatin1String(DISABLE_VERBOSE_ERROR_MESSAGES),
@@ -2571,9 +2575,6 @@ Generator::OptionDescriptions ShibokenGenerator::options() const
                                    "but safe few kB on the generated bindings."))
         << qMakePair(QLatin1String(PARENT_CTOR_HEURISTIC),
                      QLatin1String("Enable heuristics to detect parent relationship on constructors."))
-        << qMakePair(QLatin1String(ENABLE_PYSIDE_EXTENSIONS),
-                     QLatin1String("Enable PySide extensions, such as support for signal/slots,\n"
-                                   "use this if you are creating a binding for a Qt-based library."))
         << qMakePair(QLatin1String(RETURN_VALUE_HEURISTIC),
                      QLatin1String("Enable heuristics to detect parent relationship on return values\n"
                                    "(USE WITH CAUTION!)"))
@@ -2582,14 +2583,15 @@ Generator::OptionDescriptions ShibokenGenerator::options() const
                                    "the value of boolean casts"))
         << qMakePair(QLatin1String(WRAPPER_DIAGNOSTICS),
                      QLatin1String("Generate diagnostic code around wrappers"));
+    return result;
 }
 
-bool ShibokenGenerator::handleOption(const QString &key, const QString & /* value */)
+bool ShibokenGenerator::handleOption(const QString &key, const QString &value)
 {
+    if (Generator::handleOption(key, value))
+        return true;
     if (key == QLatin1String(PARENT_CTOR_HEURISTIC))
         return (m_useCtorHeuristic = true);
-    if (key == QLatin1String(ENABLE_PYSIDE_EXTENSIONS))
-        return (m_usePySideExtensions = true);
     if (key == QLatin1String(RETURN_VALUE_HEURISTIC))
         return (m_userReturnValueHeuristic = true);
     if (key == QLatin1String(DISABLE_VERBOSE_ERROR_MESSAGES))
@@ -2691,11 +2693,6 @@ bool ShibokenGenerator::useReturnValueHeuristic() const
     return m_userReturnValueHeuristic;
 }
 
-bool ShibokenGenerator::usePySideExtensions() const
-{
-    return m_usePySideExtensions;
-}
-
 bool ShibokenGenerator::useIsNullAsNbNonZero() const
 {
     return m_useIsNullAsNbNonZero;
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
index 6d36026c..c776ac8c 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
@@ -90,9 +90,6 @@ public:
     /// Returns a list of all ancestor classes for the given class.
     AbstractMetaClassList getAllAncestors(const AbstractMetaClass *metaClass) const;
 
-    /// Returns true if the user enabled PySide extensions.
-    bool usePySideExtensions() const;
-
 protected:
     bool doSetup() override;
 
@@ -234,7 +231,7 @@ protected:
     QString wrapperName(const AbstractMetaClass *metaClass) const;
 
     QString fullPythonClassName(const AbstractMetaClass *metaClass);
-    QString fullPythonFunctionName(const AbstractMetaFunction *func);
+    QString fullPythonFunctionName(const AbstractMetaFunction *func, bool forceFunc);
 
     bool wrapperDiagnostics() const { return m_wrapperDiagnostics; }
 
@@ -564,7 +561,6 @@ private:
 
     bool m_useCtorHeuristic = false;
     bool m_userReturnValueHeuristic = false;
-    bool m_usePySideExtensions = false;
     bool m_verboseErrorMessagesDisabled = false;
     bool m_useIsNullAsNbNonZero = false;
     bool m_avoidProtectedHack = false;
diff --git a/sources/shiboken2/libshiboken/CMakeLists.txt b/sources/shiboken2/libshiboken/CMakeLists.txt
index a209dc71..96effd28 100644
--- a/sources/shiboken2/libshiboken/CMakeLists.txt
+++ b/sources/shiboken2/libshiboken/CMakeLists.txt
@@ -29,13 +29,35 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/sbkversion.h.in"
 configure_file("${CMAKE_CURRENT_SOURCE_DIR}/embed/signature_bootstrap.py"
                "${CMAKE_CURRENT_BINARY_DIR}/embed/signature_bootstrap.py" @ONLY)
 
+# Variable from enclosing scope.
+# list(TRANSFORM shiboken_python_files
+#      PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/../shibokenmodule/files.dir/shibokensupport/"
+#      OUTPUT_VARIABLE embedded_shiboken_files)
+# Replacement for CMake version < 3.12:
+set(embedded_shiboken_files "")
+foreach(item IN LISTS shiboken_python_files)
+    list(APPEND embedded_shiboken_files
+                "${CMAKE_CURRENT_SOURCE_DIR}/../shibokenmodule/files.dir/shibokensupport/${item}")
+endforeach()
+
+if (QUIET_BUILD)
+    set(embedding_option "--quiet")
+else()
+    set(embedding_option "")
+endif()
+
 add_custom_command(
     OUTPUT  "${CMAKE_CURRENT_BINARY_DIR}/embed/signature_bootstrap_inc.h"
     OUTPUT  "${CMAKE_CURRENT_BINARY_DIR}/embed/signature_inc.h"
     COMMAND ${PYTHON_EXECUTABLE} -E
             "${CMAKE_CURRENT_SOURCE_DIR}/embed/embedding_generator.py"
             --cmake-dir "${CMAKE_CURRENT_BINARY_DIR}/embed"
-            --limited-api ${PYTHON_LIMITED_API})
+            --limited-api ${PYTHON_LIMITED_API}
+            ${embedding_option}
+    DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/embed/embedding_generator.py"
+            "${CMAKE_CURRENT_SOURCE_DIR}/embed/signature_bootstrap.py"
+            ${embedded_shiboken_files}
+    )
 
 set(libshiboken_MAJOR_VERSION ${shiboken_MAJOR_VERSION})
 set(libshiboken_MINOR_VERSION ${shiboken_MINOR_VERSION})
@@ -57,7 +79,6 @@ sbkstaticstrings.cpp
 bindingmanager.cpp
 threadstatesaver.cpp
 shibokenbuffer.cpp
-qapp_macro.cpp
 pep384impl.cpp
 voidptr.cpp
 typespec.cpp
@@ -142,7 +163,6 @@ install(FILES
         shibokenbuffer.h
         sbkpython.h
         pep384impl.h
-        qapp_macro.h
         voidptr.h
         typespec.h
         bufferprocs_py37.h
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp
index d866d133..7ac7fada 100644
--- a/sources/shiboken2/libshiboken/basewrapper.cpp
+++ b/sources/shiboken2/libshiboken/basewrapper.cpp
@@ -56,7 +56,6 @@
 #include <algorithm>
 #include "threadstatesaver.h"
 #include "signature.h"
-#include "qapp_macro.h"
 #include "voidptr.h"
 
 #include <iostream>
@@ -96,6 +95,13 @@ static void SbkObjectTypeDealloc(PyObject *pyObj);
 static PyObject *SbkObjectTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *kwds);
 
 static SelectableFeatureHook SelectFeatureSet = nullptr;
+static DestroyQAppHook DestroyQApplication = nullptr;
+
+// PYSIDE-1470: Provide a hook to kill an Application from Shiboken.
+void setDestroyQApplication(DestroyQAppHook func)
+{
+    DestroyQApplication = func;
+}
 
 static PyObject *Sbk_TypeGet___dict__(PyTypeObject *type, void *context);   // forward
 
@@ -319,6 +325,11 @@ static int SbkObject_traverse(PyObject *self, visitproc visit, void *arg)
 
     if (sbkSelf->ob_dict)
         Py_VISIT(sbkSelf->ob_dict);
+
+#if PY_VERSION_HEX >= 0x03090000
+    // This was not needed before Python 3.9 (Python issue 35810 and 40217)
+    Py_VISIT(Py_TYPE(self));
+#endif
     return 0;
 }
 
@@ -422,9 +433,7 @@ static void SbkDeallocWrapperCommon(PyObject *pyObj, bool canDelete)
     // be invoked and it trying to delete this object while it is still in
     // progress from the first time around, resulting in a double delete and a
     // crash.
-    // PYSIDE-571: Some objects do not use GC, so check this!
-    if (PyObject_IS_GC(pyObj))
-        PyObject_GC_UnTrack(pyObj);
+    PyObject_GC_UnTrack(pyObj);
 
     // Check that Python is still initialized as sometimes this is called by a static destructor
     // after Python interpeter is shutdown.
@@ -536,6 +545,48 @@ void SbkObjectTypeDealloc(PyObject *pyObj)
     }
 }
 
+////////////////////////////////////////////////////////////////////////////
+//
+// Support for the qApp macro.
+//
+// qApp is a macro in Qt5. In Python, we simulate that a little by a
+// variable that monitors Q*Application.instance().
+// This variable is also able to destroy the app by qApp.shutdown().
+//
+
+PyObject *MakeQAppWrapper(PyTypeObject *type)
+{
+    static PyObject *qApp_last = nullptr;
+
+    // protecting from multiple application instances
+    if (!(type == nullptr || qApp_last == Py_None)) {
+        const char *res_name = qApp_last != nullptr
+            ? PepType_GetNameStr(Py_TYPE(qApp_last)) : "<Unknown>";
+        const char *type_name = PepType_GetNameStr(type);
+        PyErr_Format(PyExc_RuntimeError, "Please destroy the %s singleton before"
+            " creating a new %s instance.", res_name, type_name);
+        return nullptr;
+    }
+
+    // monitoring the last application state
+    PyObject *qApp_curr = type != nullptr ? PyObject_GC_New(PyObject, type) : Py_None;
+    static PyObject *builtins = PyEval_GetBuiltins();
+    if (PyDict_SetItem(builtins, Shiboken::PyName::qApp(), qApp_curr) < 0)
+        return nullptr;
+    qApp_last = qApp_curr;
+    // Note: This Py_INCREF would normally be wrong because the qApp
+    // object already has a reference from PyObject_GC_New. But this is
+    // exactly the needed reference that keeps qApp alive from alone!
+    Py_INCREF(qApp_curr);
+    // PYSIDE-1470: As a side effect, the interactive "_" variable tends to
+    // create reference cycles. It was found when using gc.collect(). But using
+    // PyGC_collect() inside the C code had no effect in the interactive shell.
+    // The cycle exists only in the eval loop of the interpreter!
+    if (PyDict_GetItem(builtins, Shiboken::PyName::underscore()))
+        PyDict_SetItem(builtins, Shiboken::PyName::underscore(), Py_None);
+    return qApp_curr;
+}
+
 //////////////////////////////////////////////////////////////////////////////
 //
 // PYSIDE-1019: Support switchable extensions
@@ -550,9 +601,11 @@ void SbkObjectTypeDealloc(PyObject *pyObj)
 //   SbkObject_GenericSetAttr       PyObject_GenericSetAttr
 //
 
-void initSelectableFeature(SelectableFeatureHook func)
+SelectableFeatureHook initSelectableFeature(SelectableFeatureHook func)
 {
+    auto ret = SelectFeatureSet;
     SelectFeatureSet = func;
+    return ret;
 }
 
 static PyObject *mangled_type_getattro(PyTypeObject *type, PyObject *name)
@@ -574,7 +627,7 @@ static PyObject *Sbk_TypeGet___dict__(PyTypeObject *type, void *context)
      * This is the override for getting a dict.
      */
     auto dict = type->tp_dict;
-    if (dict == NULL)
+    if (dict == nullptr)
         Py_RETURN_NONE;
     if (SelectFeatureSet != nullptr)
         dict = SelectFeatureSet(type);
@@ -625,6 +678,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);
+}
+
 //
 //////////////////////////////////////////////////////////////////////////////
 
@@ -718,10 +778,13 @@ static PyObject *SbkObjectTypeTpNew(PyTypeObject *metatype, PyObject *args, PyOb
     sotp->d_func = nullptr;
     sotp->is_user_type = 1;
 
+    // PYSIDE-1463: Prevent feature switching while in the creation process
+    auto saveFeature = initSelectableFeature(nullptr);
     for (SbkObjectType *base : bases) {
         if (PepType_SOTP(base)->subtype_init)
             PepType_SOTP(base)->subtype_init(newType, args, kwds);
     }
+    initSelectableFeature(saveFeature);
     return reinterpret_cast<PyObject *>(newType);
 }
 
@@ -744,39 +807,25 @@ static PyObject *_setupNew(SbkObject *self, PyTypeObject *subtype)
     self->ob_dict = nullptr;
     self->weakreflist = nullptr;
     self->d = d;
+    PyObject_GC_Track(reinterpret_cast<PyObject *>(self));
     return reinterpret_cast<PyObject *>(self);
 }
 
 PyObject *SbkObjectTpNew(PyTypeObject *subtype, PyObject *, PyObject *)
 {
     SbkObject *self = PyObject_GC_New(SbkObject, subtype);
-    PyObject *res = _setupNew(self, subtype);
-    PyObject_GC_Track(reinterpret_cast<PyObject *>(self));
-    return res;
+    return _setupNew(self, subtype);
 }
 
 PyObject *SbkQAppTpNew(PyTypeObject *subtype, PyObject *, PyObject *)
 {
-    // PYSIDE-571:
-    // For qApp, we need to create a singleton Python object.
-    // We cannot track this with the GC, because it is a static variable!
-
-    // Python 2 has a weird handling of flags in derived classes that Python 3
-    // does not have. Observed with bug_307.py.
-    // But it could theoretically also happen with Python3.
-    // Therefore we enforce that there is no GC flag, ever!
-
-    // PYSIDE-560:
-    // We avoid to use this in Python 3, because we have a hard time to get
-    // write access to these flags
-#ifndef IS_PY3K
-    if (PyType_HasFeature(subtype, Py_TPFLAGS_HAVE_GC)) {
-        subtype->tp_flags &= ~Py_TPFLAGS_HAVE_GC;
-        subtype->tp_free = PyObject_Del;
-    }
-#endif
     auto self = reinterpret_cast<SbkObject *>(MakeQAppWrapper(subtype));
-    return self == nullptr ? nullptr : _setupNew(self, subtype);
+    if (self == nullptr)
+        return nullptr;
+    auto ret = _setupNew(self, subtype);
+    auto priv = self->d;
+    priv->isQAppSingleton = 1;
+    return ret;
 }
 
 PyObject *SbkDummyNew(PyTypeObject *type, PyObject *, PyObject *)
@@ -854,7 +903,7 @@ PyObject *FallbackRichCompare(PyObject *self, PyObject *other, int op)
                      opstrings[op],
                      self->ob_type->tp_name,
                      other->ob_type->tp_name);
-        return NULL;
+        return nullptr;
     }
     Py_INCREF(res);
     return res;
@@ -968,9 +1017,10 @@ void init()
 }
 
 // setErrorAboutWrongArguments now gets overload info from the signature module.
-void setErrorAboutWrongArguments(PyObject *args, const char *funcName)
+// Info can be nullptr and contains extra info.
+void setErrorAboutWrongArguments(PyObject *args, const char *funcName, PyObject *info)
 {
-    SetError_Argument(args, funcName);
+    SetError_Argument(args, funcName, info);
 }
 
 class FindBaseTypeVisitor : public HierarchyVisitor
@@ -1265,6 +1315,12 @@ bool wasCreatedByPython(SbkObject *pyObj)
 
 void callCppDestructors(SbkObject *pyObj)
 {
+    auto priv = pyObj->d;
+    if (priv->isQAppSingleton && DestroyQApplication) {
+        // PYSIDE-1470: Allow to destroy the application from Shiboken.
+        DestroyQApplication();
+        return;
+    }
     PyTypeObject *type = Py_TYPE(pyObj);
     SbkObjectTypePrivate *sotp = PepType_SOTP(type);
     if (sotp->is_multicpp) {
@@ -1277,18 +1333,19 @@ void callCppDestructors(SbkObject *pyObj)
         sotp->cpp_dtor(pyObj->d->cptr[0]);
     }
 
+    if (priv->validCppObject && priv->containsCppWrapper) {
+        BindingManager::instance().releaseWrapper(pyObj);
+    }
+
     /* invalidate needs to be called before deleting pointer array because
        it needs to delete entries for them from the BindingManager hash table;
        also release wrapper explicitly if object contains C++ wrapper because
        invalidate doesn't */
     invalidate(pyObj);
-    if (pyObj->d->validCppObject && pyObj->d->containsCppWrapper) {
-      BindingManager::instance().releaseWrapper(pyObj);
-    }
 
-    delete[] pyObj->d->cptr;
-    pyObj->d->cptr = nullptr;
-    pyObj->d->validCppObject = false;
+    delete[] priv->cptr;
+    priv->cptr = nullptr;
+    priv->validCppObject = false;
 }
 
 bool hasOwnership(SbkObject *pyObj)
diff --git a/sources/shiboken2/libshiboken/basewrapper.h b/sources/shiboken2/libshiboken/basewrapper.h
index 31083522..a79a9309 100644
--- a/sources/shiboken2/libshiboken/basewrapper.h
+++ b/sources/shiboken2/libshiboken/basewrapper.h
@@ -93,18 +93,25 @@ typedef void (*ObjectDestructor)(void *);
 
 typedef void (*SubTypeInitHook)(SbkObjectType *, PyObject *, PyObject *);
 
-// PYSIDE-1019: Set the function to select the current feature.
+/// PYSIDE-1019: Set the function to select the current feature.
+/// Return value is the previous content.
 typedef PyObject *(*SelectableFeatureHook)(PyTypeObject *);
-LIBSHIBOKEN_API void initSelectableFeature(SelectableFeatureHook func);
+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);
 
+/// PYSIDE-1470: Set the function to kill a Q*Application.
+typedef void(*DestroyQAppHook)();
+LIBSHIBOKEN_API void setDestroyQApplication(DestroyQAppHook func);
 
 extern LIBSHIBOKEN_API PyTypeObject *SbkObjectType_TypeF(void);
 extern LIBSHIBOKEN_API SbkObjectType *SbkObject_TypeF(void);
@@ -118,8 +125,12 @@ struct LIBSHIBOKEN_API SbkObjectType
 };
 
 LIBSHIBOKEN_API PyObject *SbkObjectTpNew(PyTypeObject *subtype, PyObject *, PyObject *);
-// the special case of a switchable singleton
-LIBSHIBOKEN_API PyObject *SbkQAppTpNew(PyTypeObject *subtype, PyObject *args, PyObject *kwds);
+
+/// The special case of a switchable singleton Q*Application.
+LIBSHIBOKEN_API PyObject *SbkQAppTpNew(PyTypeObject *subtype, PyObject *, PyObject *);
+
+/// Create a new Q*Application wrapper and monitor it.
+LIBSHIBOKEN_API PyObject *MakeQAppWrapper(PyTypeObject *type);
 
 /**
  *  PYSIDE-832: Use object_dealloc instead of nullptr.
@@ -157,8 +168,10 @@ void callCppDestructor(void *cptr)
     delete reinterpret_cast<T *>(cptr);
 }
 
-// setErrorAboutWrongArguments now gets overload info from the signature module.
-LIBSHIBOKEN_API void setErrorAboutWrongArguments(PyObject *args, const char *funcName);
+// setErrorAboutWrongArguments now gets overload information from the signature module.
+// The extra info argument can contain additional data about the error.
+LIBSHIBOKEN_API void setErrorAboutWrongArguments(PyObject *args, const char *funcName,
+                                                 PyObject *info);
 
 namespace ObjectType {
 
diff --git a/sources/shiboken2/libshiboken/basewrapper_p.h b/sources/shiboken2/libshiboken/basewrapper_p.h
index 64f7941b..60fba13c 100644
--- a/sources/shiboken2/libshiboken/basewrapper_p.h
+++ b/sources/shiboken2/libshiboken/basewrapper_p.h
@@ -97,6 +97,9 @@ struct SbkObjectPrivate
     unsigned int validCppObject : 1;
     /// Marked as true when the object constructor was called
     unsigned int cppObjectCreated : 1;
+    /// PYSIDE-1470: Marked as true if this is the Q*Application singleton.
+    /// This bit allows app deletion from shiboken?.delete() .
+    unsigned int isQAppSingleton : 1;
     /// Information about the object parents and children, may be null.
     Shiboken::ParentInfo *parentInfo;
     /// Manage reference count of objects that are referred to but not owned from.
diff --git a/sources/shiboken2/libshiboken/bindingmanager.cpp b/sources/shiboken2/libshiboken/bindingmanager.cpp
index 78c03556..5d69e923 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) {
@@ -299,12 +302,13 @@ PyObject *BindingManager::getOverride(const void *cptr,
         // They cannot be overridden (make that sure by the metaclass).
         return nullptr;
     }
-    PyObject *pyMethodName = nameCache[(flag & 1) != 0];  // borrowed
+    bool is_snake = flag & 0x01;
+    PyObject *pyMethodName = nameCache[is_snake];  // borrowed
     if (pyMethodName == nullptr) {
         if (propFlag)
             methodName += 2;    // skip the propFlag and ':'
-        pyMethodName = Shiboken::String::getSnakeCaseName(methodName, flag);
-        nameCache[(flag & 1) != 0] = pyMethodName;
+        pyMethodName = Shiboken::String::getSnakeCaseName(methodName, is_snake);
+        nameCache[is_snake] = pyMethodName;
     }
 
     if (wrapper->ob_dict) {
diff --git a/sources/shiboken2/libshiboken/embed/embedding_generator.py b/sources/shiboken2/libshiboken/embed/embedding_generator.py
index 15f63649..a9a58ee0 100644
--- a/sources/shiboken2/libshiboken/embed/embedding_generator.py
+++ b/sources/shiboken2/libshiboken/embed/embedding_generator.py
@@ -82,7 +82,7 @@ def runpy(cmd, **kw):
     subprocess.call([sys.executable, '-E'] + cmd.split(), **kw)
 
 
-def create_zipfile(limited_api):
+def create_zipfile(limited_api, quiet):
     """
     Collect all Python files, compile them, create a zip file
     and make a chunked base64 encoded file from it.
@@ -129,11 +129,28 @@ def create_zipfile(limited_api):
     with open(inc_name, "w") as inc:
         _embed_file(tmp, inc)
     tmp.close()
+
     # also generate a simple embeddable .pyc file for signature_bootstrap.pyc
     boot_name = "signature_bootstrap.py" if limited_api else "signature_bootstrap.pyc"
     with open(boot_name, "rb") as ldr, open("signature_bootstrap_inc.h", "w") as inc:
         _embed_bytefile(ldr, inc, limited_api)
     os.chdir(cur_dir)
+    if quiet:
+        return
+
+    # have a look at our populated folder unless quiet option
+    def list_files(startpath):
+        for root, dirs, files in os.walk(startpath):
+            level = root.replace(startpath, '').count(os.sep)
+            indent = ' ' * 4 * (level)
+            print('+ {}{}/'.format(indent, os.path.basename(root)))
+            subindent = ' ' * 4 * (level + 1)
+            for f in files:
+                print('+ {}{}'.format(subindent, f))
+
+    print("++++ Current contents of")
+    list_files(work_dir)
+    print("++++")
 
 
 def _embed_file(fin, fout):
@@ -236,7 +253,8 @@ if __name__ == "__main__":
     parser = argparse.ArgumentParser()
     parser.add_argument('--cmake-dir', nargs="?")
     parser.add_argument('--limited-api', type=str2bool)
+    parser.add_argument('--quiet', action='store_true')
     args = parser.parse_args()
     if args.cmake_dir:
         work_dir = os.path.abspath(args.cmake_dir)
-    create_zipfile(args.limited_api)
+    create_zipfile(args.limited_api, args.quiet)
diff --git a/sources/shiboken2/libshiboken/embed/signature_bootstrap.py b/sources/shiboken2/libshiboken/embed/signature_bootstrap.py
index b7d9d279..90286426 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
@@ -110,14 +111,15 @@ def bootstrap():
     rp = os.path.realpath(os.path.dirname(root.__file__))
     # This can be the shiboken2 directory or the binary module, so search.
     look_for = os.path.join("files.dir", "shibokensupport", "signature", "loader.py")
-    while len(rp) > 3 and not os.path.exists(os.path.join(rp, look_for)):
-        rp = os.path.abspath(os.path.join(rp, ".."))
+    while not os.path.exists(os.path.join(rp, look_for)):
+        dir = os.path.dirname(rp)
+        if dir == rp:  # Hit root, '/', 'C:\', '\\server\share'
+            break
+        rp = dir
 
     # 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")
@@ -128,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)
@@ -175,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/pep384impl.cpp b/sources/shiboken2/libshiboken/pep384impl.cpp
index cb804256..a7233034 100644
--- a/sources/shiboken2/libshiboken/pep384impl.cpp
+++ b/sources/shiboken2/libshiboken/pep384impl.cpp
@@ -751,14 +751,16 @@ _Pep_PrivateMangle(PyObject *self, PyObject *name)
 #endif // IS_PY2
     Shiboken::AutoDecRef privateobj(PyObject_GetAttr(
         reinterpret_cast<PyObject *>(Py_TYPE(self)), Shiboken::PyMagicName::name()));
-#ifndef Py_LIMITED_API
+#if !defined(Py_LIMITED_API) && PY_VERSION_HEX < 0x03010000
     return _Py_Mangle(privateobj, name);
 #else
-    // For some reason, _Py_Mangle is not in the Limited API. Why?
-    size_t plen = PyUnicode_GET_LENGTH(privateobj);
+    // PYSIDE-1436: _Py_Mangle is no longer exposed; implement it always.
+    // The rest of this function is our own implementation of _Py_Mangle.
+    // Please compare the original function in compile.c .
+    size_t plen = PyUnicode_GET_LENGTH(privateobj.object());
     /* Strip leading underscores from class name */
     size_t ipriv = 0;
-    while (PyUnicode_READ_CHAR(privateobj, ipriv) == '_')
+    while (PyUnicode_READ_CHAR(privateobj.object(), ipriv) == '_')
         ipriv++;
     if (ipriv == plen) {
         Py_INCREF(name);
diff --git a/sources/shiboken2/libshiboken/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h
index 7a6f57fc..eb65596c 100644
--- a/sources/shiboken2/libshiboken/pep384impl.h
+++ b/sources/shiboken2/libshiboken/pep384impl.h
@@ -40,6 +40,11 @@
 #ifndef PEP384IMPL_H
 #define PEP384IMPL_H
 
+// PYSIDE-1436: Adapt to Python 3.10
+#if PY_VERSION_HEX < 0x030900A4
+#  define Py_SET_REFCNT(obj, refcnt) ((Py_REFCNT(obj) = (refcnt)), (void)0)
+#endif
+
 extern "C"
 {
 
@@ -327,7 +332,7 @@ LIBSHIBOKEN_API PyObject *PyRun_String(const char *, int, PyObject *, PyObject *
 // But this is no problem as we check it's validity for every version.
 
 #define PYTHON_BUFFER_VERSION_COMPATIBLE    (PY_VERSION_HEX >= 0x03030000 && \
-                                             PY_VERSION_HEX <  0x0309FFFF)
+                                             PY_VERSION_HEX <  0x030AFFFF)
 #if !PYTHON_BUFFER_VERSION_COMPATIBLE
 # error Please check the buffer compatibility for this python version!
 #endif
diff --git a/sources/shiboken2/libshiboken/qapp_macro.cpp b/sources/shiboken2/libshiboken/qapp_macro.cpp
deleted file mode 100644
index 3ef3a51c..00000000
--- a/sources/shiboken2/libshiboken/qapp_macro.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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$
-**
-****************************************************************************/
-
-#include "basewrapper.h"
-#include "autodecref.h"
-
-extern "C"
-{
-
-#include "qapp_macro.h"
-
-////////////////////////////////////////////////////////////////////////////
-//
-// Support for the qApp macro.
-//
-// qApp is a macro in Qt5. In Python, we simulate that a little by a
-// variable that monitors Q*Application.instance().
-// This variable is also able to destroy the app by qApp.shutdown().
-//
-
-static PyObject *qApp_var = nullptr;
-static PyObject *qApp_content = nullptr;
-
-static PyObject *
-monitor_qApp_var(PyObject *qApp)
-{
-    static bool init_done;
-    static PyObject *builtins = PyEval_GetBuiltins();
-
-    if (!init_done) {
-        qApp_var = Py_BuildValue("s", "qApp");
-        if (qApp_var == nullptr)
-            return nullptr;
-        // This is a borrowed reference
-        Py_INCREF(builtins);
-        init_done = true;
-    }
-
-    if (PyDict_SetItem(builtins, qApp_var, qApp) < 0)
-        return nullptr;
-    qApp_content = qApp;
-    Py_INCREF(qApp);
-    return qApp;
-}
-
-PyObject *
-MakeQAppWrapper(PyTypeObject *type)
-{
-    if (type == nullptr)
-        type = Py_TYPE(Py_None);
-    if (!(type == Py_TYPE(Py_None) || Py_TYPE(qApp_content) == Py_TYPE(Py_None))) {
-        const char *res_name = PepType_GetNameStr(Py_TYPE(qApp_content));
-        const char *type_name = PepType_GetNameStr(type);
-        PyErr_Format(PyExc_RuntimeError, "Please destroy the %s singleton before"
-            " creating a new %s instance.", res_name, type_name);
-        return nullptr;
-    }
-    PyObject *self = type != Py_TYPE(Py_None) ? PyObject_New(PyObject, type) : Py_None;
-    return monitor_qApp_var(self);
-}
-
-} //extern "C"
-
-// end of module
diff --git a/sources/shiboken2/libshiboken/qapp_macro.h b/sources/shiboken2/libshiboken/qapp_macro.h
deleted file mode 100644
index 9abd17c1..00000000
--- a/sources/shiboken2/libshiboken/qapp_macro.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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$
-**
-****************************************************************************/
-
-#ifndef QAPP_MACRO_H
-#define QAPP_MACRO_H
-
-#include "sbkpython.h"
-
-extern "C"
-{
-
-LIBSHIBOKEN_API PyObject *MakeQAppWrapper(PyTypeObject *type);
-
-} // extern "C"
-
-#endif // QAPP_MACRO_H
diff --git a/sources/shiboken2/libshiboken/sbkarrayconverter.cpp b/sources/shiboken2/libshiboken/sbkarrayconverter.cpp
index fd09efda..b828aa8e 100644
--- a/sources/shiboken2/libshiboken/sbkarrayconverter.cpp
+++ b/sources/shiboken2/libshiboken/sbkarrayconverter.cpp
@@ -90,7 +90,6 @@ SbkArrayConverter *createArrayConverter(IsArrayConvertibleToCppFunc toCppCheckFu
 
 static PythonToCppFunc unimplementedArrayCheck(PyObject *, int, int)
 {
-    warning(PyExc_RuntimeWarning, 0, "SbkConverter: Unimplemented C++ array type.");
     return nullptr;
 }
 
diff --git a/sources/shiboken2/libshiboken/sbkconverter_p.h b/sources/shiboken2/libshiboken/sbkconverter_p.h
index d8716207..6febaa14 100644
--- a/sources/shiboken2/libshiboken/sbkconverter_p.h
+++ b/sources/shiboken2/libshiboken/sbkconverter_p.h
@@ -539,7 +539,7 @@ struct Primitive<std::nullptr_t> : TwoPrimitive<std::nullptr_t>
 {
     static PyObject *toPython(const void * /* cppIn */)
     {
-        return Py_None;
+        Py_RETURN_NONE;
     }
     static void toCpp(PyObject *, void *cppOut)
     {
diff --git a/sources/shiboken2/libshiboken/sbkenum.cpp b/sources/shiboken2/libshiboken/sbkenum.cpp
index 369b264e..7dc73dfb 100644
--- a/sources/shiboken2/libshiboken/sbkenum.cpp
+++ b/sources/shiboken2/libshiboken/sbkenum.cpp
@@ -46,13 +46,13 @@
 #include "sbkdbg.h"
 #include "autodecref.h"
 #include "sbkpython.h"
+#include "signature.h"
 
 #include <string.h>
 #include <cstring>
 #include <vector>
 
-#define SBK_ENUM(ENUM) reinterpret_cast<SbkEnumObject *>(ENUM)
-#define SBK_TYPE_CHECK(o) (strcmp(Py_TYPE(Py_TYPE(o))->tp_name, "Shiboken.EnumType") == 0)
+#define SbkEnumType_Check(o) (Py_TYPE(Py_TYPE(o)) == SbkEnumType_TypeF())
 typedef PyObject *(*enum_func)(PyObject *, PyObject *);
 
 extern "C"
@@ -77,9 +77,11 @@ struct SbkEnumObject
     PyObject *ob_name;
 };
 
+static PyTypeObject *SbkEnum_TypeF();   // forward
+
 static PyObject *SbkEnumObject_repr(PyObject *self)
 {
-    const SbkEnumObject *enumObj = SBK_ENUM(self);
+    const SbkEnumObject *enumObj = reinterpret_cast<SbkEnumObject *>(self);
     if (enumObj->ob_name)
         return Shiboken::String::fromFormat("%s.%s", (Py_TYPE(self))->tp_name, PyBytes_AS_STRING(enumObj->ob_name));
     else
@@ -88,7 +90,7 @@ static PyObject *SbkEnumObject_repr(PyObject *self)
 
 static PyObject *SbkEnumObject_name(PyObject *self, void *)
 {
-    auto *enum_self = SBK_ENUM(self);
+    auto *enum_self = reinterpret_cast<SbkEnumObject *>(self);
 
     if (enum_self->ob_name == nullptr)
         Py_RETURN_NONE;
@@ -103,6 +105,11 @@ static PyObject *SbkEnum_tp_new(PyTypeObject *type, PyObject *args, PyObject *)
     if (!PyArg_ParseTuple(args, "|l:__new__", &itemValue))
         return nullptr;
 
+    if (type == SbkEnum_TypeF()) {
+        PyErr_Format(PyExc_TypeError, "You cannot use %s directly", type->tp_name);
+        return nullptr;
+    }
+
     SbkEnumObject *self = PyObject_New(SbkEnumObject, type);
     if (!self)
         return nullptr;
@@ -112,6 +119,11 @@ static PyObject *SbkEnum_tp_new(PyTypeObject *type, PyObject *args, PyObject *)
     return reinterpret_cast<PyObject *>(self);
 }
 
+static const char *SbkEnum_SignatureStrings[] = {
+    "Shiboken.Enum(self,itemValue:int=0)",
+    nullptr}; // Sentinel
+
+
 void enum_object_dealloc(PyObject *ob)
 {
     auto self = reinterpret_cast<SbkEnumObject *>(ob);
@@ -129,12 +141,12 @@ static PyObject *enum_op(enum_func f, PyObject *a, PyObject *b) {
     // We are not allowing floats
     if (!PyFloat_Check(valA) && !PyFloat_Check(valB)) {
         // Check if both variables are SbkEnumObject
-        if (SBK_TYPE_CHECK(valA)) {
-            valA = PyLong_FromLong(SBK_ENUM(valA)->ob_value);
+        if (SbkEnumType_Check(valA)) {
+            valA = PyLong_FromLong(reinterpret_cast<SbkEnumObject *>(valA)->ob_value);
             enumA = true;
         }
-        if (SBK_TYPE_CHECK(valB)) {
-            valB = PyLong_FromLong(SBK_ENUM(valB)->ob_value);
+        if (SbkEnumType_Check(valB)) {
+            valB = PyLong_FromLong(reinterpret_cast<SbkEnumObject *>(valB)->ob_value);
             enumB = true;
         }
     }
@@ -152,7 +164,6 @@ static PyObject *enum_op(enum_func f, PyObject *a, PyObject *b) {
         Py_DECREF(valA);
     if (enumB)
         Py_DECREF(valB);
-
     return result;
 }
 
@@ -166,7 +177,7 @@ static PyObject *enum_op(enum_func f, PyObject *a, PyObject *b) {
  */
 static PyObject *enum_int(PyObject *v)
 {
-    return PyInt_FromLong(SBK_ENUM(v)->ob_value);
+    return PyInt_FromLong(reinterpret_cast<SbkEnumObject *>(v)->ob_value);
 }
 
 static PyObject *enum_and(PyObject *self, PyObject *b)
@@ -176,7 +187,7 @@ static PyObject *enum_and(PyObject *self, PyObject *b)
 
 static PyObject *enum_or(PyObject *self, PyObject *b)
 {
-return enum_op(PyNumber_Or, self, b);
+    return enum_op(PyNumber_Or, self, b);
 }
 
 static PyObject *enum_xor(PyObject *self, PyObject *b)
@@ -186,7 +197,7 @@ static PyObject *enum_xor(PyObject *self, PyObject *b)
 
 static int enum_bool(PyObject *v)
 {
-    return (SBK_ENUM(v)->ob_value > 0);
+    return (reinterpret_cast<SbkEnumObject *>(v)->ob_value > 0);
 }
 
 static PyObject *enum_add(PyObject *self, PyObject *v)
@@ -201,7 +212,7 @@ static PyObject *enum_subtract(PyObject *self, PyObject *v)
 
 static PyObject *enum_multiply(PyObject *self, PyObject *v)
 {
-return enum_op(PyNumber_Multiply, self, v);
+    return enum_op(PyNumber_Multiply, self, v);
 }
 
 #ifndef IS_PY3K
@@ -223,12 +234,12 @@ static PyObject *enum_richcompare(PyObject *self, PyObject *other, int op)
     if (!PyFloat_Check(valA) && !PyFloat_Check(valB)) {
 
         // Check if both variables are SbkEnumObject
-        if (SBK_TYPE_CHECK(valA)) {
-            valA = PyLong_FromLong(SBK_ENUM(valA)->ob_value);
+        if (SbkEnumType_Check(valA)) {
+            valA = PyLong_FromLong(reinterpret_cast<SbkEnumObject *>(valA)->ob_value);
             enumA = true;
         }
-        if (SBK_TYPE_CHECK(valB)) {
-            valB = PyLong_FromLong(SBK_ENUM(valB)->ob_value);
+        if (SbkEnumType_Check(valB)) {
+            valB = PyLong_FromLong(reinterpret_cast<SbkEnumObject *>(valB)->ob_value);
             enumB =true;
         }
     }
@@ -284,24 +295,6 @@ static PyObject *SbkEnumTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObje
 
 static PyType_Slot SbkEnumType_Type_slots[] = {
     {Py_tp_dealloc, (void *)SbkEnumTypeDealloc},
-    {Py_nb_add, (void *)enum_add},
-    {Py_nb_subtract, (void *)enum_subtract},
-    {Py_nb_multiply, (void *)enum_multiply},
-#ifndef IS_PY3K
-    {Py_nb_divide, (void *)enum_divide},
-#endif
-    {Py_nb_positive, (void *)enum_int},
-#ifdef IS_PY3K
-    {Py_nb_bool, (void *)enum_bool},
-#else
-    {Py_nb_nonzero, (void *)enum_bool},
-    {Py_nb_long, (void *)enum_int},
-#endif
-    {Py_nb_and, (void *)enum_and},
-    {Py_nb_xor, (void *)enum_xor},
-    {Py_nb_or, (void *)enum_or},
-    {Py_nb_int, (void *)enum_int},
-    {Py_nb_index, (void *)enum_int},
     {Py_tp_base, (void *)&PyType_Type},
     {Py_tp_alloc, (void *)PyType_GenericAlloc},
     {Py_tp_new, (void *)SbkEnumTypeTpNew},
@@ -312,7 +305,7 @@ static PyType_Slot SbkEnumType_Type_slots[] = {
     {0, nullptr}
 };
 static PyType_Spec SbkEnumType_Type_spec = {
-    "1:Shiboken.EnumType",
+    "1:Shiboken.EnumMeta",
     0,    // filled in later
     sizeof(PyMemberDef),
     Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_CHECKTYPES,
@@ -370,8 +363,6 @@ PyObject *SbkEnumTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *kwd
 //
 extern "C" {
 
-static void init_enum();  // forward
-
 static PyObject *enum_unpickler = nullptr;
 
 // Pickling: reduce the Qt Enum object
@@ -441,16 +432,23 @@ static bool _init_enum()
         PyErr_Clear();
         mod = shibo.object();
     }
+    // publish Shiboken.Enum so that the signature gets initialized
+    if (PyObject_SetAttrString(mod, "Enum", reinterpret_cast<PyObject *>(SbkEnum_TypeF())) < 0)
+        return false;
+    if (InitSignatureStrings(SbkEnum_TypeF(), SbkEnum_SignatureStrings) < 0)
+        return false;
     enum_unpickler = PyObject_GetAttrString(mod, "_unpickle_enum");
     if (enum_unpickler == nullptr)
         return false;
     return true;
 }
 
-static void init_enum()
+void init_enum()
 {
-    if (!(enum_unpickler || _init_enum()))
+    static bool is_initialized = false;
+    if (!(is_initialized || enum_unpickler || _init_enum()))
         Py_FatalError("could not load enum pickling helper function");
+    is_initialized = true;
 }
 
 static PyMethodDef SbkEnumObject_Methods[] = {
@@ -507,7 +505,6 @@ PyObject *getEnumItemFromValue(PyTypeObject *enumType, long itemValue)
 }
 
 static PyTypeObject *createEnum(const char *fullName, const char *cppName,
-                                const char */* shortName */,
                                 PyTypeObject *flagsType)
 {
     PyTypeObject *enumType = newTypeWithName(fullName, cppName, flagsType);
@@ -520,7 +517,7 @@ static PyTypeObject *createEnum(const char *fullName, const char *cppName,
 
 PyTypeObject *createGlobalEnum(PyObject *module, const char *name, const char *fullName, const char *cppName, PyTypeObject *flagsType)
 {
-    PyTypeObject *enumType = createEnum(fullName, cppName, name, flagsType);
+    PyTypeObject *enumType = createEnum(fullName, cppName, flagsType);
     if (enumType && PyModule_AddObject(module, name, reinterpret_cast<PyObject *>(enumType)) < 0) {
         Py_DECREF(enumType);
         return nullptr;
@@ -535,7 +532,7 @@ PyTypeObject *createGlobalEnum(PyObject *module, const char *name, const char *f
 
 PyTypeObject *createScopedEnum(SbkObjectType *scope, const char *name, const char *fullName, const char *cppName, PyTypeObject *flagsType)
 {
-    PyTypeObject *enumType = createEnum(fullName, cppName, name, flagsType);
+    PyTypeObject *enumType = createEnum(fullName, cppName, flagsType);
     if (enumType && PyDict_SetItemString(reinterpret_cast<PyTypeObject *>(scope)->tp_dict, name,
             reinterpret_cast<PyObject *>(enumType)) < 0) {
         Py_DECREF(enumType);
@@ -625,7 +622,10 @@ newItem(PyTypeObject *enumType, long itemValue, const char *itemName)
     return reinterpret_cast<PyObject *>(enumObj);
 }
 
-static PyType_Slot SbkNewType_slots[] = {
+} // namespace Shiboken
+} // namespace Enum
+
+static PyType_Slot SbkNewEnum_slots[] = {
     {Py_tp_repr, (void *)SbkEnumObject_repr},
     {Py_tp_str, (void *)SbkEnumObject_repr},
     {Py_tp_getset, (void *)SbkEnumGetSetList},
@@ -654,14 +654,22 @@ static PyType_Slot SbkNewType_slots[] = {
     {Py_tp_dealloc, (void *)enum_object_dealloc},
     {0, nullptr}
 };
-static PyType_Spec SbkNewType_spec = {
-    "missing Enum name", // to be inserted later
+static PyType_Spec SbkNewEnum_spec = {
+    "1:Shiboken.Enum",
     sizeof(SbkEnumObject),
     0,
-    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES,
-    SbkNewType_slots,
+    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_CHECKTYPES,
+    SbkNewEnum_slots,
 };
 
+static PyTypeObject *SbkEnum_TypeF()
+{
+    static auto type = SbkType_FromSpec(&SbkNewEnum_spec);
+    return reinterpret_cast<PyTypeObject *>(type);
+}
+
+namespace Shiboken { namespace Enum {
+
 static void
 copyNumberMethods(PyTypeObject *flagsType,
                   PyType_Slot number_slots[],
@@ -727,20 +735,25 @@ newTypeWithName(const char *name,
     PyType_Slot newslots[99] = {};  // enough but not too big for the stack
     PyType_Spec newspec;
     newspec.name = strdup(name);
-    newspec.basicsize = SbkNewType_spec.basicsize;
-    newspec.itemsize = SbkNewType_spec.itemsize;
-    newspec.flags = SbkNewType_spec.flags;
+    newspec.basicsize = SbkNewEnum_spec.basicsize;
+    newspec.itemsize = SbkNewEnum_spec.itemsize;
+    newspec.flags = SbkNewEnum_spec.flags;
     // we must append all the number methods, so rebuild everything:
     int idx = 0;
-    while (SbkNewType_slots[idx].slot) {
-        newslots[idx].slot = SbkNewType_slots[idx].slot;
-        newslots[idx].pfunc = SbkNewType_slots[idx].pfunc;
+    while (SbkNewEnum_slots[idx].slot) {
+        newslots[idx].slot = SbkNewEnum_slots[idx].slot;
+        newslots[idx].pfunc = SbkNewEnum_slots[idx].pfunc;
         ++idx;
     }
     if (numbers_fromFlag)
         copyNumberMethods(numbers_fromFlag, newslots, &idx);
     newspec.slots = newslots;
-    auto *type = reinterpret_cast<PyTypeObject *>(SbkType_FromSpec(&newspec));
+    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();
     Py_TYPE(type) = SbkEnumType_TypeF();
 
     auto *enumType = reinterpret_cast<SbkEnumType *>(type);
diff --git a/sources/shiboken2/libshiboken/sbkenum.h b/sources/shiboken2/libshiboken/sbkenum.h
index c294c17d..236f4a15 100644
--- a/sources/shiboken2/libshiboken/sbkenum.h
+++ b/sources/shiboken2/libshiboken/sbkenum.h
@@ -46,6 +46,9 @@
 extern "C"
 {
 
+/// exposed for the signature module
+LIBSHIBOKEN_API void init_enum();
+
 extern LIBSHIBOKEN_API PyTypeObject *SbkEnumType_TypeF(void);
 struct SbkObjectType;
 struct SbkConverter;
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings.cpp b/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
index 5559d58d..58d32f21 100644
--- a/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings.cpp
@@ -58,7 +58,10 @@ STATIC_STRING_IMPL(fset, "fset")
 STATIC_STRING_IMPL(loads, "loads")
 STATIC_STRING_IMPL(multi, "multi")
 STATIC_STRING_IMPL(name, "name")
+STATIC_STRING_IMPL(qApp, "qApp")
 STATIC_STRING_IMPL(result, "result")
+STATIC_STRING_IMPL(select_id, "select_id")
+STATIC_STRING_IMPL(underscore, "_")
 STATIC_STRING_IMPL(value, "value")
 STATIC_STRING_IMPL(values, "values")
 
@@ -87,6 +90,7 @@ STATIC_STRING_IMPL(get, "__get__")
 STATIC_STRING_IMPL(members, "__members__")
 STATIC_STRING_IMPL(module, "__module__")
 STATIC_STRING_IMPL(name, "__name__")
+STATIC_STRING_IMPL(property_methods, "__property_methods__")
 STATIC_STRING_IMPL(qualname, "__qualname__")
 STATIC_STRING_IMPL(self, "__self__")
 
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings.h b/sources/shiboken2/libshiboken/sbkstaticstrings.h
index b72fa989..4aaef814 100644
--- a/sources/shiboken2/libshiboken/sbkstaticstrings.h
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings.h
@@ -58,6 +58,8 @@ LIBSHIBOKEN_API PyObject *loads();
 LIBSHIBOKEN_API PyObject *multi();
 LIBSHIBOKEN_API PyObject *name();
 LIBSHIBOKEN_API PyObject *result();
+LIBSHIBOKEN_API PyObject *select_id();
+LIBSHIBOKEN_API PyObject *underscore();
 LIBSHIBOKEN_API PyObject *value();
 LIBSHIBOKEN_API PyObject *values();
 } // namespace PyName
@@ -69,10 +71,12 @@ LIBSHIBOKEN_API PyObject *dict();
 LIBSHIBOKEN_API PyObject *doc();
 LIBSHIBOKEN_API PyObject *ecf();
 LIBSHIBOKEN_API PyObject *file();
+LIBSHIBOKEN_API PyObject *func();
 LIBSHIBOKEN_API PyObject *get();
 LIBSHIBOKEN_API PyObject *members();
 LIBSHIBOKEN_API PyObject *module();
 LIBSHIBOKEN_API PyObject *name();
+LIBSHIBOKEN_API PyObject *property_methods();
 LIBSHIBOKEN_API PyObject *qualname();
 LIBSHIBOKEN_API PyObject *self();
 } // namespace PyMagicName
diff --git a/sources/shiboken2/libshiboken/sbkstaticstrings_p.h b/sources/shiboken2/libshiboken/sbkstaticstrings_p.h
index c33fa029..419eeeb1 100644
--- a/sources/shiboken2/libshiboken/sbkstaticstrings_p.h
+++ b/sources/shiboken2/libshiboken/sbkstaticstrings_p.h
@@ -51,6 +51,7 @@ PyObject *marshal();
 PyObject *method();
 PyObject *mro();
 PyObject *overload();
+PyObject *qApp();
 PyObject *staticmethod();
 } // namespace PyName
 namespace PyMagicName
diff --git a/sources/shiboken2/libshiboken/sbkstring.cpp b/sources/shiboken2/libshiboken/sbkstring.cpp
index 918aae75..077fb531 100644
--- a/sources/shiboken2/libshiboken/sbkstring.cpp
+++ b/sources/shiboken2/libshiboken/sbkstring.cpp
@@ -247,7 +247,7 @@ static void finalizeStaticStrings()
 {
     auto &set = staticStrings();
     for (PyObject *ob : set) {
-        Py_REFCNT(ob) = 1;
+        Py_SET_REFCNT(ob, 1);
         Py_DECREF(ob);
     }
     set.clear();
diff --git a/sources/shiboken2/libshiboken/shibokenbuffer.cpp b/sources/shiboken2/libshiboken/shibokenbuffer.cpp
index dd6e4632..8d44878a 100644
--- a/sources/shiboken2/libshiboken/shibokenbuffer.cpp
+++ b/sources/shiboken2/libshiboken/shibokenbuffer.cpp
@@ -74,6 +74,29 @@ void *Shiboken::Buffer::getPointer(PyObject *pyObj, Py_ssize_t *size)
     return const_cast<void *>(buffer);
 }
 
+void *Shiboken::Buffer::copyData(PyObject *pyObj, Py_ssize_t *sizeIn)
+{
+    void *result = nullptr;
+    Py_ssize_t size = 0;
+
+    Py_buffer view;
+    if (PyObject_GetBuffer(pyObj, &view, PyBUF_ND) == 0) {
+        size = view.len;
+        if (size) {
+            result = std::malloc(size);
+            if (result != nullptr)
+                std::memcpy(result, view.buf, size);
+            else
+                size = 0;
+        }
+        PyBuffer_Release(&view);
+    }
+
+    if (sizeIn != nullptr)
+        *sizeIn = size;
+    return result;
+}
+
 PyObject *Shiboken::Buffer::newObject(void *memory, Py_ssize_t size, Type type)
 {
     if (size == 0)
diff --git a/sources/shiboken2/libshiboken/shibokenbuffer.h b/sources/shiboken2/libshiboken/shibokenbuffer.h
index dc9f8d89..512d9db4 100644
--- a/sources/shiboken2/libshiboken/shibokenbuffer.h
+++ b/sources/shiboken2/libshiboken/shibokenbuffer.h
@@ -79,6 +79,14 @@ namespace Buffer
      */
     LIBSHIBOKEN_API void *getPointer(PyObject *pyObj, Py_ssize_t *size = nullptr);
 
+    /**
+     * Returns a copy of the buffer data which should be free'd.
+     *
+     * If the \p pyObj is a non-contiguous buffer a Python error is set.
+     * nullptr is returned for empty buffers.
+     */
+    LIBSHIBOKEN_API void *copyData(PyObject *pyObj, Py_ssize_t *size = nullptr);
+
 } // namespace Buffer
 } // namespace Shiboken
 
diff --git a/sources/shiboken2/libshiboken/signature.h b/sources/shiboken2/libshiboken/signature.h
index b77cc0f4..0459d866 100644
--- a/sources/shiboken2/libshiboken/signature.h
+++ b/sources/shiboken2/libshiboken/signature.h
@@ -45,7 +45,7 @@ extern "C"
 
 LIBSHIBOKEN_API int InitSignatureStrings(PyTypeObject *, const char *[]);
 LIBSHIBOKEN_API void FinishSignatureInitialization(PyObject *, const char *[]);
-LIBSHIBOKEN_API void SetError_Argument(PyObject *, const char *);
+LIBSHIBOKEN_API void SetError_Argument(PyObject *, const char *, PyObject *);
 LIBSHIBOKEN_API PyObject *Sbk_TypeGet___signature__(PyObject *, PyObject *);
 LIBSHIBOKEN_API PyObject *Sbk_TypeGet___doc__(PyObject *);
 LIBSHIBOKEN_API PyObject *GetFeatureDict();
diff --git a/sources/shiboken2/libshiboken/signature/signature.cpp b/sources/shiboken2/libshiboken/signature/signature.cpp
index 085d751a..3051c50d 100644
--- a/sources/shiboken2/libshiboken/signature/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature/signature.cpp
@@ -209,8 +209,12 @@ PyObject *GetSignature_Wrapper(PyObject *ob, PyObject *modifier)
     if (dict == nullptr)
         return nullptr;
     PyObject *props = PyDict_GetItem(dict, func_name);
-    if (props == nullptr)
+    if (props == nullptr) {
+        // handle `__init__` like the class itself
+        if (strcmp(String::toCString(func_name), "__init__") == 0)
+            return GetSignature_TypeMod(objclass, modifier);
         Py_RETURN_NONE;
+    }
     return _GetSignature_Cached(props, PyName::method(), modifier);
 }
 
@@ -431,7 +435,86 @@ void FinishSignatureInitialization(PyObject *module, const char *signatures[])
     }
 }
 
-void SetError_Argument(PyObject *args, const char *func_name)
+static PyObject *adjustFuncName(const char *func_name)
+{
+    /*
+     * PYSIDE-1019: Modify the function name expression according to feature.
+     *
+     * - snake_case
+     *      The function name must be converted.
+     * - full_property
+     *      The property name must be used and "fset" appended.
+     *
+     *          modname.subname.classsname.propname.fset
+     *
+     *      Class properties must use the expression
+     *
+     *          modname.subname.classsname.__dict__['propname'].fset
+     *
+     * Note that fget is impossible because there are no parameters.
+     */
+    static const char mapping_name[] = "shibokensupport.signature.mapping";
+    static PyObject *sys_modules = PySys_GetObject(const_cast<char *>("modules"));
+    static PyObject *mapping = PyDict_GetItemString(sys_modules, mapping_name);
+    static PyObject *ns = PyModule_GetDict(mapping);
+
+    char _path[200 + 1] = {};
+    const char *_name = strrchr(func_name, '.');
+    strncat(_path, func_name, _name - func_name);
+    ++_name;
+
+    // This is a very cheap call into `mapping.py`.
+    PyObject *update_mapping = PyDict_GetItemString(ns, "update_mapping");
+    AutoDecRef res(PyObject_CallFunctionObjArgs(update_mapping, nullptr));
+    if (res.isNull())
+        return nullptr;
+
+    // Run `eval` on the type string to get the object.
+    AutoDecRef obtype(PyRun_String(_path, Py_eval_input, ns, ns));
+    if (PyModule_Check(obtype.object())) {
+        // This is a plain function. Return the unmangled name.
+        return String::fromCString(func_name);
+    }
+    assert(PyType_Check(obtype));   // This was not true for __init__!
+
+    // Find the feature flags
+    auto type = reinterpret_cast<PyTypeObject *>(obtype.object());
+    auto dict = type->tp_dict;
+    int id = SbkObjectType_GetReserved(type);
+    id = id < 0 ? 0 : id;   // if undefined, set to zero
+    auto lower = id & 0x01;
+    auto is_prop = id & 0x02;
+    bool is_class_prop = false;
+
+    // Compute all needed info.
+    PyObject *name = String::getSnakeCaseName(_name, lower);
+    PyObject *prop_name;
+    if (is_prop) {
+        PyObject *prop_methods = PyDict_GetItem(dict, PyMagicName::property_methods());
+        prop_name = PyDict_GetItem(prop_methods, name);
+        if (prop_name != nullptr) {
+            PyObject *prop = PyDict_GetItem(dict, prop_name);
+            is_class_prop = Py_TYPE(prop) != &PyProperty_Type;
+        }
+    }
+
+    // Finally, generate the correct path expression.
+    char _buf[250 + 1] = {};
+    if (is_prop) {
+        auto _prop_name = String::toCString(prop_name);
+        if (is_class_prop)
+            sprintf(_buf, "%s.__dict__['%s'].fset", _path, _prop_name);
+        else
+            sprintf(_buf, "%s.%s.fset", _path, _prop_name);
+    }
+    else {
+        auto _name = String::toCString(name);
+        sprintf(_buf, "%s.%s", _path, _name);
+    }
+    return String::fromCString(_buf);
+}
+
+void SetError_Argument(PyObject *args, const char *func_name, PyObject *info)
 {
     /*
      * This function replaces the type error construction with extra
@@ -440,8 +523,24 @@ void SetError_Argument(PyObject *args, const char *func_name)
      */
     init_module_1();
     init_module_2();
-    AutoDecRef res(PyObject_CallFunction(pyside_globals->seterror_argument_func,
-                                         const_cast<char *>("(Os)"), args, func_name));
+
+    // PYSIDE-1305: Handle errors set by fillQtProperties.
+    if (PyErr_Occurred()) {
+        PyObject *e, *v, *t;
+        // Note: These references are all borrowed.
+        PyErr_Fetch(&e, &v, &t);
+        info = v;
+    }
+    // PYSIDE-1019: Modify the function name expression according to feature.
+    AutoDecRef new_func_name(adjustFuncName(func_name));
+    if (new_func_name.isNull()) {
+        PyErr_Print();
+        Py_FatalError("seterror_argument failed to call update_mapping");
+    }
+    if (info == nullptr)
+        info = Py_None;
+    AutoDecRef res(PyObject_CallFunctionObjArgs(pyside_globals->seterror_argument_func,
+                                                args, new_func_name.object(), info, nullptr));
     if (res.isNull()) {
         PyErr_Print();
         Py_FatalError("seterror_argument did not receive a result");
diff --git a/sources/shiboken2/libshiboken/signature/signature_globals.cpp b/sources/shiboken2/libshiboken/signature/signature_globals.cpp
index 6af64682..81810280 100644
--- a/sources/shiboken2/libshiboken/signature/signature_globals.cpp
+++ b/sources/shiboken2/libshiboken/signature/signature_globals.cpp
@@ -48,6 +48,7 @@
 #include "sbkstring.h"
 #include "sbkstaticstrings.h"
 #include "sbkstaticstrings_p.h"
+#include "sbkenum.h"
 
 #include "signature_p.h"
 
@@ -109,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));
@@ -289,6 +290,8 @@ void init_module_2(void)
         // Therefore we set init_done prior to init_phase_2().
         init_done = 1;
         init_phase_2(pyside_globals, signature_methods);
+        // Enum must be initialized when signatures exist, not earlier.
+        init_enum();
     }
 }
 
diff --git a/sources/shiboken2/shiboken_version.py b/sources/shiboken2/shiboken_version.py
index 009db0bf..9ec9b0e7 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 = "2"
+patch_version = "7"
 
 # For example: "a", "b", "rc"
 # (which means "alpha", "beta", "release candidate").
diff --git a/sources/shiboken2/shibokenmodule/CMakeLists.txt b/sources/shiboken2/shibokenmodule/CMakeLists.txt
index b14de5c9..9b2b5852 100644
--- a/sources/shiboken2/shibokenmodule/CMakeLists.txt
+++ b/sources/shiboken2/shibokenmodule/CMakeLists.txt
@@ -42,37 +42,12 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/_config.py"
 configure_file("${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in"
                "${CMAKE_CURRENT_BINARY_DIR}/__init__.py" @ONLY)
 
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/__feature__.py"
-               "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/__feature__.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/__init__.py"
-               "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/__init__.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/__init__.py"
-               "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/__init__.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/errorhandler.py"
-               "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/errorhandler.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/layout.py"
-               "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/layout.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/loader.py"
-               "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/loader.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/importhandler.py"
-               "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/importhandler.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/mapping.py"
-               "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/mapping.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/parser.py"
-               "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/parser.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/lib/__init__.py"
-               "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/lib/__init__.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/lib/enum_sig.py"
-               "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/lib/enum_sig.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/lib/tool.py"
-               "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/lib/tool.py" COPYONLY)
-if (PYTHON_VERSION_MAJOR EQUAL 3)
-else()
-    configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/backport_inspect.py"
-                   "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/backport_inspect.py" COPYONLY)
-    configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/typing27.py"
-                   "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/typing27.py" COPYONLY)
-endif()
+# Variable from enclosing scope.
+foreach(item IN LISTS shiboken_python_files)
+    configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/${item}"
+                   "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/${item}" COPYONLY)
+endforeach()
+
 install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/files.dir"
         DESTINATION "${PYTHON_SITE_PACKAGES}/shiboken2")
 
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/__feature__.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/feature.py
similarity index 95%
rename from sources/shiboken2/shibokenmodule/files.dir/shibokensupport/__feature__.py
rename to sources/shiboken2/shibokenmodule/files.dir/shibokensupport/feature.py
index ece3d2ed..e2edfe39 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/__feature__.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/feature.py
@@ -132,13 +132,10 @@ def _import(name, *args, **kwargs):
         sys.modules["PySide2.QtCore"].__init_feature__()
         return sys.modules["__feature__"]
 
-    if name.split(".")[0] == "PySide2":
-        # This is a module that imports PySide2.
-        flag = existing if isinstance(existing, int) else 0
-    else:
-        # This is some other module. Ignore it in switching.
-        flag = -1
-    pyside_feature_dict[importing_module] = flag
+    if importing_module not in pyside_feature_dict:
+        # Ignore new modules if not from PySide.
+        default = 0 if name.split(".")[0] == "PySide2" else -1
+        pyside_feature_dict[importing_module] = default
     return original_import(name, *args, **kwargs)
 
 _is_initialized = False
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py
index 6ed4c0ed..352644f7 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py
@@ -95,15 +95,33 @@ def matched_type(args, sigs):
     return None
 
 
-def seterror_argument(args, func_name):
-    update_mapping()
+def seterror_argument(args, func_name, info):
     func = None
     try:
         func = eval(func_name, namespace)
     except Exception as e:
-        msg = "Internal error evaluating " + func_name + " :"  + str(e)
+        msg = "Internal error evaluating {func_name}: {e}".format(**locals())
         return TypeError, msg
+    if info and type(info) is str:
+        err = TypeError
+        if info == "<":
+            msg = "{func_name}(): not enough arguments".format(**locals())
+        elif info == ">":
+            msg = "{func_name}(): too many arguments".format(**locals())
+        elif info.isalnum():
+            msg = "{func_name}(): got multiple values for keyword argument '{info}'".format(**locals())
+        else:
+            msg = "{func_name}(): {info}".format(**locals())
+            err = AttributeError
+        return err, msg
+    if info and type(info) is dict:
+        keyword = tuple(info)[0]
+        msg = "{func_name}(): unsupported keyword '{keyword}'".format(**locals())
+        return AttributeError, msg
     sigs = get_signature(func, "typeerror")
+    if not sigs:
+        msg = "{func_name}({args}) is wrong (missing signature)".format(**locals())
+        return TypeError, msg
     if type(sigs) != list:
         sigs = [sigs]
     if type(args) != tuple:
@@ -144,7 +162,7 @@ def make_helptext(func):
         sigs = [sigs]
     try:
         func_name = func.__name__
-    except AttribureError:
+    except AttributeError:
         func_name = func.__func__.__name__
     sigtext = "\n".join(func_name + str(sig) for sig in sigs)
     msg = sigtext + "\n\n" + existing_doc if check_string_type(existing_doc) else sigtext
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
index 371b3ca4..088a93aa 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
@@ -50,8 +50,9 @@ by producing a lot of clarity.
 """
 
 import sys
+import types
 from shibokensupport.signature import inspect
-from shibokensupport.signature import get_signature
+from shibokensupport.signature import get_signature as get_sig
 
 
 class ExactEnumerator(object):
@@ -64,19 +65,28 @@ class ExactEnumerator(object):
     """
 
     def __init__(self, formatter, result_type=dict):
-        global EnumType
+        global EnumMeta
         try:
             # Lazy import
             from PySide2.QtCore import Qt
-            EnumType = type(Qt.Key)
+            EnumMeta = type(Qt.Key)
         except ImportError:
-            EnumType = None
+            EnumMeta = None
 
         self.fmt = formatter
         self.result_type = result_type
         self.fmt.level = 0
         self.fmt.after_enum = self.after_enum
         self._after_enum = False
+        self.fmt.is_method = self.is_method
+
+    def is_method(self):
+        """
+        Is this function a method?
+        We check if it is a simple function.
+        """
+        tp = type(self.func)
+        return tp not in (types.BuiltinFunctionType, types.FunctionType)
 
     def after_enum(self):
         ret = self._after_enum
@@ -93,8 +103,6 @@ class ExactEnumerator(object):
             self.fmt.class_name = None
             for class_name, klass in members:
                 ret.update(self.klass(class_name, klass))
-            if isinstance(klass, EnumType):
-                raise SystemError("implement enum instances at module level")
             for func_name, func in functions:
                 ret.update(self.function(func_name, func))
             return ret
@@ -129,10 +137,11 @@ class ExactEnumerator(object):
                 signature = getattr(thing, "__signature__", None)
                 if signature is not None:
                     functions.append((func_name, thing))
-            elif type(type(thing)) is EnumType:
-                enums.append((thing_name, thing))
+            elif type(type(thing)) is EnumMeta:
+                # take the real enum name, not what is in the dict
+                enums.append((thing_name, type(thing).__qualname__, thing))
         init_signature = getattr(klass, "__signature__", None)
-        enums.sort(key=lambda tup: tup[1])  # sort by enum value
+        enums.sort(key=lambda tup: tup[1 : 3])  # sort by class then enum value
         self.fmt.have_body = bool(subclasses or functions or enums or init_signature)
 
         with self.fmt.klass(class_name, class_str):
@@ -140,8 +149,8 @@ class ExactEnumerator(object):
             self.fmt.class_name = class_name
             if hasattr(self.fmt, "enum"):
                 # this is an optional feature
-                for enum_name, value in enums:
-                    with self.fmt.enum(class_name, enum_name, int(value)):
+                for enum_name, enum_class_name, value in enums:
+                    with self.fmt.enum(enum_class_name, enum_name, int(value)):
                         pass
             for subclass_name, subclass in subclasses:
                 if klass == subclass:
@@ -154,18 +163,23 @@ class ExactEnumerator(object):
                 self.fmt.class_name = class_name
             ret.update(self.function("__init__", klass))
             for func_name, func in functions:
-                ret.update(self.function(func_name, func))
+                if func_name != "__init__":
+                    ret.update(self.function(func_name, func))
             self.fmt.level -= 1
         return ret
 
+    @staticmethod
+    def get_signature(func):
+        return func.__signature__
+
     def function(self, func_name, func):
-        self.fmt.level += 1
+        self.func = func    # for is_method()
         ret = self.result_type()
-        signature = func.__signature__
+        signature = self.get_signature(func)
         if signature is not None:
-            with self.fmt.function(func_name, signature, modifier) as key:
+            with self.fmt.function(func_name, signature) as key:
                 ret[key] = signature
-        self.fmt.level -= 1
+        del self.func
         return ret
 
 
@@ -191,13 +205,14 @@ class SimplifyingEnumerator(ExactEnumerator):
 
     def function(self, func_name, func):
         ret = self.result_type()
-        signature = get_signature(func, 'existence')
+        signature = get_sig(func, 'existence')
         sig = stringify(signature) if signature is not None else None
         if sig is not None and func_name not in ("next", "__next__", "__div__"):
             with self.fmt.function(func_name, sig) as key:
                 ret[key] = sig
         return ret
 
+
 class HintingEnumerator(ExactEnumerator):
     """
     HintingEnumerator enumerates all signatures in a module slightly changed.
@@ -206,11 +221,6 @@ class HintingEnumerator(ExactEnumerator):
     hinting stubs. Only default values are replaced by "...".
     """
 
-    def function(self, func_name, func):
-        ret = self.result_type()
-        signature = get_signature(func, 'hintingstub')
-        if signature is not None:
-            with self.fmt.function(func_name, signature) as key:
-                ret[key] = signature
-        return ret
-
+    @staticmethod
+    def get_signature(func):
+        return get_sig(func, "hintingstub")
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py
index 24e75e42..c8dbd51c 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py
@@ -47,6 +47,7 @@ On the function with_metaclass see the answer from Martijn Pieters on
 https://stackoverflow.com/questions/18513821/python-metaclass-understanding-the-with-metaclass
 """
 
+from inspect import currentframe
 from textwrap import dedent
 
 
@@ -151,4 +152,11 @@ def with_metaclass(meta, *bases):
             return meta.__prepare__(name, bases)
     return type.__new__(metaclass, 'temporary_class', (), {})
 
+
+# A handy tool that shows the current line number and indents.
+def lno(level):
+    lineno = currentframe().f_back.f_lineno
+    spaces = level * "  "
+    return "{}{}".format(lineno, spaces)
+
 # eof
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
index 6cee5468..02229939 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
@@ -101,8 +101,8 @@ def create_signature(props, key):
     return layout.create_signature(props, key)
 
 # name used in signature.cpp
-def seterror_argument(args, func_name):
-    return errorhandler.seterror_argument(args, func_name)
+def seterror_argument(args, func_name, info):
+    return errorhandler.seterror_argument(args, func_name, info)
 
 # name used in signature.cpp
 def make_helptext(func):
@@ -114,7 +114,7 @@ def finish_import(module):
 
 
 import signature_bootstrap
-from shibokensupport import signature, __feature__
+from shibokensupport import signature, feature as __feature__
 signature.get_signature = signature_bootstrap.get_signature
 # PYSIDE-1019: Publish the __feature__ dictionary.
 __feature__.pyside_feature_dict = signature_bootstrap.pyside_feature_dict
@@ -195,8 +195,9 @@ def move_into_pyside_package():
     try:
         import PySide2.support
     except ModuleNotFoundError:
-        PySide2.support = types.ModuleType("PySide2.support")
-    put_into_package(PySide2.support, __feature__)
+        # This can happen in the embedding case.
+        put_into_package(PySide2, shibokensupport, "support")
+    put_into_package(PySide2.support, __feature__, "__feature__")
     put_into_package(PySide2.support, signature)
     put_into_package(PySide2.support.signature, mapping)
     put_into_package(PySide2.support.signature, errorhandler)
@@ -205,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)
@@ -216,20 +218,23 @@ 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.
     move_into_pyside_package()
+    # PYSIDE-1502: Make sure that support can be imported.
+    try:
+        import PySide2.support
+    except ModuleNotFoundError as e:
+        print("PySide2.support could not be imported. "
+              "This is a serious configuration error.", file=sys.stderr)
+        raise
     # PYSIDE-1019: Modify `__import__` to be `__feature__` aware.
     # __feature__ is already in sys.modules, so this is actually no import
-    try:
-        import PySide2.support.__feature__
-        sys.modules["__feature__"] = PySide2.support.__feature__
-        PySide2.support.__feature__.original_import = __builtins__["__import__"]
-        __builtins__["__import__"] = PySide2.support.__feature__._import
-        # Maybe we should optimize that and change `__import__` from C, instead?
-    except ModuleNotFoundError:
-        print("__feature__ could not be imported. "
-              "This is an unsolved PyInstaller problem.", file=sys.stderr)
+    import PySide2.support.__feature__
+    sys.modules["__feature__"] = PySide2.support.__feature__
+    PySide2.support.__feature__.original_import = __builtins__["__import__"]
+    __builtins__["__import__"] = PySide2.support.__feature__._import
 
 # end of file
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
index 6fadd19d..69f1a326 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
@@ -300,6 +300,7 @@ type_map.update({
     "zero(object)": None,
     "zero(str)": "",
     "zero(typing.Any)": None,
+    "zero(Any)": None,
     })
 
 type_map.update({
@@ -351,6 +352,10 @@ type_map.update({
     "self"  : "self",
     })
 
+# PYSIDE-1538: We need to treat "std::optional" accordingly.
+type_map.update({
+    "std.optional": typing.Optional,
+    })
 
 # The Shiboken Part
 def init_Shiboken():
@@ -361,6 +366,8 @@ def init_Shiboken():
     })
     return locals()
 
+# side effect of different shiboken namings
+init_shiboken2 = init_shiboken2_shiboken2 = init_Shiboken
 
 def init_minimal():
     type_map.update({
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
index 20c791cc..3e448d9e 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
@@ -43,10 +43,11 @@ import sys
 import re
 import warnings
 import types
+import typing
 import keyword
 import functools
 from shibokensupport.signature.mapping import (type_map, update_mapping,
-    namespace, typing, _NotCalled, ResultVariable, ArrayLikeVariable)
+    namespace, _NotCalled, ResultVariable, ArrayLikeVariable)
 from shibokensupport.signature.lib.tool import (SimpleNamespace,
     build_brace_pattern)
 
@@ -196,7 +197,7 @@ def _resolve_value(thing, valtype, line):
     if res is not None:
         type_map[thing] = res
         return res
-    warnings.warn("""pyside_type_init:
+    warnings.warn("""pyside_type_init:_resolve_value
 
         UNRECOGNIZED:   {!r}
         OFFENDING LINE: {!r}
@@ -222,7 +223,7 @@ def _resolve_arraytype(thing, line):
 def to_string(thing):
     if isinstance(thing, str):
         return thing
-    if hasattr(thing, "__name__"):
+    if hasattr(thing, "__name__") and thing.__module__ != "typing":
         dot = "." in str(thing)
         name = get_name(thing)
         return thing.__module__ + "." + name if dot else name
@@ -239,16 +240,6 @@ def handle_matrix(arg):
     return eval(result, namespace)
 
 
-debugging_aid = """
-from inspect import currentframe
-
-def lno(level):
-    lineno = currentframe().f_back.f_lineno
-    spaces = level * "  "
-    return "{lineno}{spaces}".format(**locals())
-"""
-
-
 def _resolve_type(thing, line, level, var_handler):
     # Capture total replacements, first. Happens in
     # "PySide2.QtCore.QCborStreamReader.StringResult[PySide2.QtCore.QByteArray]"
@@ -277,7 +268,15 @@ def _resolve_type(thing, line, level, var_handler):
             pieces.append(to_string(part))
         thing = ", ".join(pieces)
         result = "{contr}[{thing}]".format(**locals())
-        return eval(result, namespace)
+        # PYSIDE-1538: Make sure that the eval does not crash.
+        try:
+            return eval(result, namespace)
+        except Exception as e:
+            warnings.warn("""pyside_type_init:_resolve_type
+
+                UNRECOGNIZED:   {!r}
+                OFFENDING LINE: {!r}
+                """.format(result, line), RuntimeWarning)
     return _resolve_value(thing, None, line)
 
 
@@ -380,7 +379,9 @@ def fix_variables(props, line):
         if not isinstance(ann, ResultVariable):
             continue
         # We move the variable to the end and remove it.
-        retvars.append(ann.type)
+        # PYSIDE-1409: If the variable was the first arg, we move it to the front.
+        # XXX This algorithm should probably be replaced by more introspection.
+        retvars.insert(0 if idx == 0 else len(retvars), ann.type)
         deletions.append(idx)
         del annos[name]
     for idx in reversed(deletions):
diff --git a/sources/shiboken2/tests/samplebinding/time_test.py b/sources/shiboken2/tests/samplebinding/time_test.py
index f8b35e7b..3b8f232c 100644
--- a/sources/shiboken2/tests/samplebinding/time_test.py
+++ b/sources/shiboken2/tests/samplebinding/time_test.py
@@ -130,6 +130,7 @@ class TimeTest(unittest.TestCase):
         result = time.somethingCompletelyDifferent(1, 2, ImplicitConv.CtorOne)
         self.assertEqual(result, Time.ThreeArgs)
 
+    # PYSIDE-1436: These tests crash at shutdown due to `assert(Not)?Equal`.
     def testCompareWithPythonTime(self):
         time = Time(12, 32, 5)
         py = datetime.time(12, 32, 5)
diff --git a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
index 595afb9a..70fabcf7 100644
--- a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
@@ -1953,6 +1953,7 @@
                     %PYARG_0 = Py_False;
                 else
                     %PYARG_0 = Py_True;
+                Py_INCREF(%PYARG_0);
             }
           </inject-code>
         </add-function>
@@ -1970,6 +1971,7 @@
                     %PYARG_0 = Py_True;
                 else
                     %PYARG_0 = Py_False;
+                Py_INCREF(%PYARG_0);
             }
           </inject-code>
         </add-function>
diff --git a/tools/create_changelog.py b/tools/create_changelog.py
index 8f5ea7ad..7fbff8be 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)
 
 
diff --git a/tools/debug_renamer.py b/tools/debug_renamer.py
new file mode 100644
index 00000000..da5beb12
--- /dev/null
+++ b/tools/debug_renamer.py
@@ -0,0 +1,122 @@
+#############################################################################
+##
+## 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$
+##
+#############################################################################
+
+"""
+debug_renamer.py
+================
+
+This script renames object addresses in debug protocols to useful names.
+Comparing output will produce minimal deltas.
+
+
+Problem:
+--------
+
+In the debugging output of PYSIDE-79, we want to study different output
+before and after applying some change to the implementation.
+
+We have support from the modified Python interpreter that creates full
+traces of every object creation and increment/decrement of refcounts.
+
+The comparison between "before" and "after" gets complicated because
+the addresses of objects do not compare well.
+
+
+Input format:
+-------------
+The Python output lines are of this format:
+
+mode filename:lineno funcname object_id typename object_refcount
+
+Mode can be "INC", "DEC", "XINC", XDEC", "NEW, "NEWV".
+
+On "NEW" or "NEWV", an object is created and the refcount is always 1.
+On "DEC" or "XDEC", when refcount is 0, the object is deleted.
+
+
+Operation
+---------
+
+The script reads from <stdin> until EOF. It produces output where the
+object_id field is removed and some text is combined with object_typename
+to produce a unique object name.
+
+
+Example
+-------
+
+You can create reference debugging output by using the modified interpreter at
+
+    https://github.com/ctismer/cpython/tree/3.9-refdebug
+
+and pipe the error output through this script.
+This is work in flux that might change quite often.
+
+
+To Do List
+----------
+
+The script should be re-worked to be more flexible, without relying on
+the number of coulumns but with some intelligent guessing.
+
+Names of objects which are already deleted should be monitored and
+not by chance be re-used.
+"""
+
+import sys
+from collections import OrderedDict
+
+
+def make_name(type_name, name_pos):
+    """
+    Build a name by using uppercase letters and numbers
+    """
+    if name_pos < 26:
+        name = chr(ord("A") + name_pos)
+        return f"{type_name}_{name}"
+    return f"{type_name}_{str(name_pos)}"
+
+
+mode_tokens = "NEW NEWV INC DEC XINC XDEC".split()
+known_types = {}
+
+while 1:
+    line = sys.stdin.readline()
+    if not line:
+        break
+    fields = line.split()
+    if len(fields) != 6 or fields[0] not in mode_tokens:
+        print(line.rstrip())
+        continue
+    mode, fname_lno, funcname, object_id, typename, refcount = fields
+    if typename not in known_types:
+        known_types[typename] = OrderedDict()
+    obj_store = known_types[typename]
+    if object_id not in obj_store:
+        obj_store[object_id] = make_name(typename, len(obj_store))
+    print(f"{mode} {fname_lno} {funcname} {obj_store[object_id]} {refcount}")
diff --git a/tools/leak_finder.py b/tools/leak_finder.py
new file mode 100644
index 00000000..5b510288
--- /dev/null
+++ b/tools/leak_finder.py
@@ -0,0 +1,196 @@
+#############################################################################
+##
+## 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$
+##
+#############################################################################
+
+"""
+leak_finder.py
+==============
+
+This script finds memory leaks in Python.
+
+Usage:
+------
+
+Place one or more lines which should be tested for leaks in a loop:
+
+    from leak_finder import LeakFinder
+    ...
+    lf = LeakFinder()
+    for i in range(1000):
+        leaking_statement()
+    lf.find_leak()
+
+
+Theory
+------
+
+How to find a leak?
+
+We repeatedly perform an action and observe if that has an unexpected
+side effect. There are typically two observations:
+
+* one object is growing its refcount (a pseudo-leak)
+* we get many new objects of one type (a true leak)
+
+A difficulty in trying to get leak info is avoiding side effects
+of the measurement. Early attempts with lists of refcounts were
+unsuccessful. Using array.array for counting refcounts avoids that.
+
+
+Algorithm
+---------
+We record a snapshot of all objects in a list and a parallel array
+of refcounts.
+
+Then we do some computation and do the same snapshot again.
+
+The structure of a list of all objects is extending at the front for
+some reason. That makes the captured structures easy to compare.
+We reverse that list and array and have for the objects:
+
+    len(all2) >= len(all1)
+
+    all1[idx] == all2[idx] for idx in range(len(all1))
+
+When taking the second snapshot, the objects still have references from
+the first snapshot.
+For objects with no effect, the following relation is true:
+
+    refs1[idx] == refs2[idx] - 1 for idx in range(len(all1))
+
+All other objects are potential pseudo-leaks, because they waste
+references but no objects in the first place.
+
+Then we look at the newly created objects:
+These objects are real leaks if their number is growing with the probe
+size. For analysis, the number of new objects per type is counted.
+"""
+
+import sys
+import gc
+import array
+import unittest
+
+# this comes from Python, too
+from test import support
+
+try:
+    sys.getobjects
+    have_debug = True
+except AttributeError:
+    have_debug = False
+
+
+class LeakFinder(object):
+    def __init__(self):
+        self.all, self.refs = self._make_snapshot()
+
+    @staticmethod
+    def _make_snapshot():
+        gc.collect()
+        # get all objects
+        all = sys.getobjects(0)
+        # get an array with the refcounts
+        g = sys.getrefcount
+        refs = array.array("l", (g(obj) for obj in all))
+        # the lists have the same endind. Make comparison easier.
+        all.reverse()
+        refs.reverse()
+        return all, refs
+
+    @staticmethod
+    def _short_repr(x, limit=76):
+        s = repr(x)
+        if len(s) > limit:
+            s = s[:limit] + "..."
+        return s
+
+    def find_leak(self):
+        all1 = self.all
+        refs1 = self.refs
+        del self.all, self.refs
+        all2, refs2 = self._make_snapshot()
+        common = len(all1)
+        del all1
+
+        srepr = self._short_repr
+        # look into existing objects for increased refcounts
+        first = True
+        for idx in range(common):
+            ref = refs2[idx] - refs1[idx] - 1
+            if abs(ref) <= 10:
+                continue
+            obj = all2[idx]
+            if first:
+                print()
+            first = False
+            print(f"Fake Leak ref={ref} obj={srepr(obj)}")
+
+        # look at the extra objects by type size
+        types = {}
+        for idx in range(common, len(all2)):
+            obj = all2[idx]
+            typ = type(obj)
+            if typ not in types:
+                types[typ] = []
+            types[typ].append(obj)
+        first = True
+        for typ in types:
+            oblis = types[typ]
+            ref = len(oblis)
+            if ref <= 10:
+                continue
+            try:
+                oblis.sort()
+            except TypeError:
+                pass
+            if first:
+                print()
+            first = False
+            left, mid, right = oblis[0], oblis[ref // 2], oblis[-1]
+            print(f"True Leak ref={ref} typ={typ} left={left} mid={mid} right={right}")
+
+
+class TestDemo(unittest.TestCase):
+
+    @unittest.skipUnless(have_debug, 'You need a debug build with "--with-trace-refs"')
+    def test_demo(self):
+        # create a pseudo leak and a true leak
+        fake_leak_obj = []
+        true_leak_obj = []
+        lf = LeakFinder()
+        refs_before = sys.gettotalrefcount()
+        for idx in range(100):
+            fake_leak_obj.append("same string")
+            true_leak_obj.append(idx + 1000)    # avoiding cached low numbers
+        refs_after = sys.gettotalrefcount()
+        lf.find_leak()
+        self.assertNotAlmostEqual(refs_after - refs_before, 0, delta=10)
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/tools/license_changer.py b/tools/license_changer.py
new file mode 100644
index 00000000..0c3443b8
--- /dev/null
+++ b/tools/license_changer.py
@@ -0,0 +1,85 @@
+#############################################################################
+##
+## Copyright (C) 2021 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python project.
+##
+## $QT_BEGIN_LICENSE:COMM$
+##
+## 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.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from argparse import ArgumentParser, RawTextHelpFormatter
+import os
+from pathlib import Path
+import subprocess
+import sys
+
+
+DESC = """
+Tool to adapt licenses to a commercial LTS branch
+Requires the qtsdk/tqtc-qtsdk and qtqa repos to be checked out as siblings.
+"""
+
+
+REPO_DIR = Path(__file__).resolve().parents[1]
+
+
+EXCLUSIONS = ['/build_scripts/', '/coin/', '/doc/', '/examples/',
+              '/testing/', '/tests/',
+              '/coin_build_instructions.py', '/coin_test_instructions.py',
+              '/ez_setup.py', '/setup.py', '/testrunner.py']
+
+
+if __name__ == '__main__':
+    argument_parser = ArgumentParser(description=DESC,
+                                     formatter_class=RawTextHelpFormatter)
+    argument_parser.add_argument('--dry-run', '-d', action='store_true',
+                                 help='Dry run, print commands')
+    options = argument_parser.parse_args()
+    dry_run = options.dry_run
+
+    license_changer = (REPO_DIR.parent / 'tqtc-qtsdk' / 'packaging-tools'
+                       / 'release_tools' / 'license_changer.pl')
+    print('Checking ', license_changer)
+    if not license_changer.is_file:
+        print('Not found, please clone the qtsdk/tqtc-qtsdk repo')
+        sys.exit(1)
+    template = (REPO_DIR.parent / 'qtqa' / 'tests' / 'prebuild'
+                / 'license' / 'templates' / 'header.COMM')
+    print('Checking ', template)
+    if not template.is_file():
+        print('Not found, please clone the qtqa repo')
+        sys.exit(1)
+
+    os.chdir(REPO_DIR)
+    fixed_cmd = [str(license_changer), '--path', str(REPO_DIR),
+                 '--headerfile', str(template)]
+    for e in EXCLUSIONS:
+        fixed_cmd.append('--exclude')
+        fixed_cmd.append(e)
+
+    for license in ['GPL-EXCEPT', 'GPL', 'LGPL']:
+        log = f'license_{license.lower()}_log.txt'
+        cmd = fixed_cmd
+        cmd.extend(['--replacehdr', license, '--errorlog', log])
+        cmds = ' '.join(cmd)
+        print('Running: ', cmds)
+        if not dry_run:
+            ex = subprocess.call(cmd)
+            if ex != 0:
+                print('FAIL! ', cmds)
+                sys.exit(1)
+
+    if not dry_run:
+        subprocess.call(['git', 'diff'])
diff --git a/sources/pyside2/pyside_version.py b/tools/license_check.py
similarity index 69%
copy from sources/pyside2/pyside_version.py
copy to tools/license_check.py
index 009db0bf..052c41ca 100644
--- a/sources/pyside2/pyside_version.py
+++ b/tools/license_check.py
@@ -1,9 +1,9 @@
 #############################################################################
 ##
-## Copyright (C) 2019 The Qt Company Ltd.
+## Copyright (C) 2021 The Qt Company Ltd.
 ## Contact: https://www.qt.io/licensing/
 ##
-## This file is part of Qt for Python.
+## This file is part of the Qt for Python project.
 ##
 ## $QT_BEGIN_LICENSE:LGPL$
 ## Commercial License Usage
@@ -37,19 +37,34 @@
 ##
 #############################################################################
 
-major_version = "5"
-minor_version = "15"
-patch_version = "2"
+import os
+from pathlib import Path
+import subprocess
+import sys
 
-# For example: "a", "b", "rc"
-# (which means "alpha", "beta", "release candidate").
-# An empty string means the generated package will be an official release.
-release_version_type = ""
 
-# For example: "1", "2" (which means "beta1", "beta2", if type is "b").
-pre_release_version = ""
+"""Tool to run a license check
+
+Requires the qtqa repo to be checked out as sibling.
+"""
+
+
+REPO_DIR = Path(__file__).resolve().parents[1]
+
 
 if __name__ == '__main__':
-    # Used by CMake.
-    print('{0};{1};{2};{3};{4}'.format(major_version, minor_version, patch_version,
-                                       release_version_type, pre_release_version))
+    license_check = (REPO_DIR.parent / 'qtqa' / 'tests' / 'prebuild'
+                     / 'license' / 'tst_licenses.pl')
+    print('Checking ', license_check)
+    if not license_check.is_file():
+        print('Not found, please clone the qtqa repo')
+        sys.exit(1)
+
+    os.environ['QT_MODULE_TO_TEST'] = str(REPO_DIR)
+    cmd = [str(license_check), '-m', 'pyside-setup']
+    cmds = ' '.join(cmd)
+    print('Running: ', cmds)
+    ex = subprocess.call(cmd)
+    if ex != 0:
+        print('FAIL! ', cmds)
+        sys.exit(1)
diff --git a/tools/uic_test.py b/tools/uic_test.py
new file mode 100644
index 00000000..6c1f2b88
--- /dev/null
+++ b/tools/uic_test.py
@@ -0,0 +1,123 @@
+#############################################################################
+##
+## Copyright (C) 2021 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python project.
+##
+## $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$
+##
+#############################################################################
+
+import os
+import re
+import subprocess
+import sys
+import tempfile
+from argparse import ArgumentParser, RawTextHelpFormatter
+from pathlib import Path
+from textwrap import dedent
+from typing import Optional, Tuple
+
+
+VERSION = 2
+
+
+DESC = """Runs uic on a set of UI files and displays the resulting widgets."""
+
+
+TEMP_DIR = Path(tempfile.gettempdir())
+
+
+def get_class_name(file: Path) -> Tuple[Optional[str], Optional[str]]:
+    """Return class name and widget name of UI file."""
+    pattern = re.compile('^\s*<widget class="(\w+)" name="(\w+)"\s*>.*$')
+    for l in Path(file).read_text().splitlines():
+        match = pattern.match(l)
+        if match:
+            return (match.group(1), match.group(2))
+    return (None, None)
+
+
+def test_file(file: str, uic: bool=False) -> bool:
+    """Run uic on a UI file and show the resulting UI."""
+    path = Path(file)
+    (klass, name) = get_class_name(path)
+    if not klass:
+        print(f'{file} does not appear to be a UI file', file=sys.stderr)
+        return False
+    py_klass = f'Ui_{name}'
+    py_file_basename = py_klass.lower()
+    py_file = TEMP_DIR / (py_file_basename + '.py')
+    py_main = TEMP_DIR / 'main.py'
+    cmd = ['uic', '-g', 'python'] if uic else [f'pyside{VERSION}-uic']
+    cmd.extend(['-o', os.fspath(py_file), file])
+    try:
+        subprocess.call(cmd)
+    except FileNotFoundError as e:
+        print(str(e) + " (try -u for uic)", file=sys.stderr)
+        return False
+    main_source = dedent(f'''\
+        import sys
+        from PySide{VERSION}.QtWidgets import QApplication, {klass}
+        from {py_file_basename} import {py_klass}
+
+        if __name__ == "__main__":
+            app = QApplication(sys.argv)
+            ui = {py_klass}()
+            widget = {klass}()
+            ui.setupUi(widget)
+            widget.show()
+            sys.exit(app.exec_())''')
+    py_main.write_text(main_source)
+    exit_code = subprocess.call([sys.executable, os.fspath(py_main)])
+    py_main.unlink()
+    py_file.unlink()
+    return exit_code == 0
+
+
+if __name__ == '__main__':
+    argument_parser = ArgumentParser(description=DESC,
+                                     formatter_class=RawTextHelpFormatter)
+    argument_parser.add_argument('--uic', '-u', action='store_true',
+                                 help='Use uic instead of pyside-uic')
+    argument_parser.add_argument("files", help="UI Files",
+                                 nargs='+', type=str)
+    options = argument_parser.parse_args()
+    failed = 0
+    count = len(options.files)
+    for i, file in enumerate(options.files):
+        print(f'{i+1}/{count} {file}')
+        if not test_file(file, options.uic):
+            failed += 1
+    if failed != 0:
+        print(f'{failed}/{count} failed.')
+    sys.exit(failed)



More information about the Neon-commits mailing list