aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2019-04-24 14:24:06 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-04-24 14:24:09 +0200
commit8b892f71b749a623724ccecca881972a33c9d559 (patch)
tree88d7a2371481cafd559d4895efa41b6f166ed8ac
parentfff6ea0059b7394869166a01674a9afa230bc3a9 (diff)
parenta7038d87ba6ec3b2beeee166930c24f290f6478f (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
-rw-r--r--.gitignore145
-rw-r--r--build_scripts/platforms/windows_desktop.py6
-rw-r--r--build_scripts/utils.py2
-rw-r--r--coin_test_instructions.py9
-rw-r--r--examples/examples.pyproject1
-rw-r--r--examples/installer_test/hello.py103
-rw-r--r--examples/installer_test/hello_app.spec85
-rw-r--r--examples/utils/pyside2_config.py4
-rw-r--r--sources/pyside2/PySide2/Qt3DAnimation/typesystem_3danimation.xml2
-rw-r--r--sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml2
-rw-r--r--sources/pyside2/PySide2/Qt3DExtras/typesystem_3dextras.xml2
-rw-r--r--sources/pyside2/PySide2/Qt3DInput/typesystem_3dinput.xml2
-rw-r--r--sources/pyside2/PySide2/Qt3DLogic/typesystem_3dlogic.xml2
-rw-r--r--sources/pyside2/PySide2/Qt3DRender/typesystem_3drender.xml2
-rw-r--r--sources/pyside2/PySide2/QtAxContainer/typesystem_axcontainer.xml2
-rw-r--r--sources/pyside2/PySide2/QtCharts/typesystem_charts.xml2
-rw-r--r--sources/pyside2/PySide2/QtConcurrent/typesystem_concurrent.xml2
-rw-r--r--sources/pyside2/PySide2/QtCore/typesystem_core_common.xml2
-rw-r--r--sources/pyside2/PySide2/QtCore/typesystem_core_mac.xml2
-rw-r--r--sources/pyside2/PySide2/QtCore/typesystem_core_win.xml2
-rw-r--r--sources/pyside2/PySide2/QtCore/typesystem_core_x11.xml2
-rw-r--r--sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml2
-rw-r--r--sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml25
-rw-r--r--sources/pyside2/PySide2/QtGui/typesystem_gui_mac.xml2
-rw-r--r--sources/pyside2/PySide2/QtGui/typesystem_gui_win.xml2
-rw-r--r--sources/pyside2/PySide2/QtGui/typesystem_gui_x11.xml2
-rw-r--r--sources/pyside2/PySide2/QtHelp/typesystem_help.xml2
-rw-r--r--sources/pyside2/PySide2/QtLocation/typesystem_location.xml2
-rw-r--r--sources/pyside2/PySide2/QtMacExtras/typesystem_macextras.xml2
-rw-r--r--sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia.xml2
-rw-r--r--sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml2
-rw-r--r--sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_forward_declarations.xml2
-rw-r--r--sources/pyside2/PySide2/QtMultimediaWidgets/typesystem_multimediawidgets.xml2
-rw-r--r--sources/pyside2/PySide2/QtNetwork/typesystem_network.xml2
-rw-r--r--sources/pyside2/PySide2/QtOpenGL/typesystem_opengl.xml2
-rw-r--r--sources/pyside2/PySide2/QtPositioning/typesystem_positioning.xml2
-rw-r--r--sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport_common.xml2
-rw-r--r--sources/pyside2/PySide2/QtQml/typesystem_qml.xml2
-rw-r--r--sources/pyside2/PySide2/QtQuick/typesystem_quick.xml2
-rw-r--r--sources/pyside2/PySide2/QtQuickWidgets/typesystem_quickwidgets.xml2
-rw-r--r--sources/pyside2/PySide2/QtRemoteObjects/typesystem_remoteobjects.xml2
-rw-r--r--sources/pyside2/PySide2/QtScript/typesystem_script.xml2
-rw-r--r--sources/pyside2/PySide2/QtScriptTools/typesystem_scripttools.xml2
-rw-r--r--sources/pyside2/PySide2/QtScxml/typesystem_scxml.xml2
-rw-r--r--sources/pyside2/PySide2/QtSensors/typesystem_sensors.xml2
-rw-r--r--sources/pyside2/PySide2/QtSql/typesystem_sql.xml2
-rw-r--r--sources/pyside2/PySide2/QtSvg/typesystem_svg.xml2
-rw-r--r--sources/pyside2/PySide2/QtTest/typesystem_test.xml2
-rw-r--r--sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml2
-rw-r--r--sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml2
-rw-r--r--sources/pyside2/PySide2/QtWebChannel/typesystem_webchannel.xml2
-rw-r--r--sources/pyside2/PySide2/QtWebEngine/typesystem_webengine.xml2
-rw-r--r--sources/pyside2/PySide2/QtWebEngineCore/typesystem_webenginecore.xml2
-rw-r--r--sources/pyside2/PySide2/QtWebEngineWidgets/typesystem_webenginewidgets.xml2
-rw-r--r--sources/pyside2/PySide2/QtWebKit/typesystem_webkit.xml2
-rw-r--r--sources/pyside2/PySide2/QtWebKitWidgets/typesystem_webkitwidgets.xml2
-rw-r--r--sources/pyside2/PySide2/QtWebSockets/typesystem_websockets.xml2
-rw-r--r--sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml2
-rw-r--r--sources/pyside2/PySide2/QtWidgets/typesystem_widgets_mac.xml2
-rw-r--r--sources/pyside2/PySide2/QtWidgets/typesystem_widgets_win.xml2
-rw-r--r--sources/pyside2/PySide2/QtWidgets/typesystem_widgets_x11.xml2
-rw-r--r--sources/pyside2/PySide2/QtWinExtras/typesystem_winextras.xml2
-rw-r--r--sources/pyside2/PySide2/QtX11Extras/typesystem_x11extras.xml2
-rw-r--r--sources/pyside2/PySide2/QtXml/typesystem_xml.xml2
-rw-r--r--sources/pyside2/PySide2/QtXmlPatterns/typesystem_xmlpatterns.xml2
-rw-r--r--sources/pyside2/PySide2/glue/qtcore.cpp4
-rw-r--r--sources/pyside2/PySide2/glue/qtgui.cpp10
-rw-r--r--sources/pyside2/PySide2/support/generate_pyi.py6
-rw-r--r--sources/pyside2/PySide2/templates/core_common.xml2
-rw-r--r--sources/pyside2/PySide2/templates/datavisualization_common.xml2
-rw-r--r--sources/pyside2/PySide2/templates/gui_common.xml2
-rw-r--r--sources/pyside2/PySide2/templates/opengl_common.xml2
-rw-r--r--sources/pyside2/PySide2/templates/webkitwidgets_common.xml2
-rw-r--r--sources/pyside2/PySide2/templates/widgets_common.xml2
-rw-r--r--sources/pyside2/PySide2/templates/xml_common.xml2
-rw-r--r--sources/pyside2/doc/CMakeLists.txt8
-rw-r--r--sources/pyside2/doc/contents.rst1
-rw-r--r--sources/pyside2/doc/deployment-cxfreeze.rst130
-rw-r--r--sources/pyside2/doc/deployment-fbs.rst106
-rw-r--r--sources/pyside2/doc/deployment-pyinstaller.rst124
-rw-r--r--sources/pyside2/doc/deployment.rst70
-rw-r--r--sources/pyside2/doc/faq.rst4
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst6
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/dialog.rst6
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/uifiles.rst8
-rw-r--r--sources/pyside2/doc/tutorials/examples/tabbedbrowser.rst1
-rw-r--r--sources/pyside2/tests/pysidetest/typesystem_pysidetest.xml2
-rw-r--r--sources/shiboken2/ApiExtractor/CMakeLists.txt78
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp431
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.h2
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h45
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp42
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h19
-rw-r--r--sources/shiboken2/ApiExtractor/apiextractor.cpp1
-rw-r--r--sources/shiboken2/ApiExtractor/messages.cpp6
-rw-r--r--sources/shiboken2/ApiExtractor/messages.h2
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.cpp56
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.h6
-rw-r--r--sources/shiboken2/ApiExtractor/tests/CMakeLists.txt24
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp37
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.cpp5
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp107
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h25
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem_p.h7
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem_typedefs.h4
-rw-r--r--sources/shiboken2/CMakeLists.txt18
-rw-r--r--sources/shiboken2/doc/typesystem_specifying_types.rst24
-rw-r--r--sources/shiboken2/generator/CMakeLists.txt33
-rw-r--r--sources/shiboken2/generator/generator.cpp4
-rw-r--r--sources/shiboken2/generator/main.cpp6
-rw-r--r--sources/shiboken2/generator/qtdoc/CMakeLists.txt21
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp2
-rw-r--r--sources/shiboken2/generator/shiboken2/CMakeLists.txt28
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp39
-rw-r--r--sources/shiboken2/generator/shiboken2/overloaddata.cpp2
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp5
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.h2
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.cpp30
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.h2
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.h1
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp252
-rw-r--r--sources/shiboken2/libshiboken/signature.h4
-rw-r--r--sources/shiboken2/shibokenmodule/CMakeLists.txt18
-rw-r--r--sources/shiboken2/shibokenmodule/__init__.py.in21
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py1
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py3
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py14
-rw-r--r--sources/shiboken2/tests/CMakeLists.txt3
-rw-r--r--sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt5
-rw-r--r--sources/shiboken2/tests/libminimal/CMakeLists.txt4
-rw-r--r--sources/shiboken2/tests/libother/CMakeLists.txt8
-rw-r--r--sources/shiboken2/tests/libsample/CMakeLists.txt4
-rw-r--r--sources/shiboken2/tests/libsmart/CMakeLists.txt4
-rw-r--r--sources/shiboken2/tests/minimalbinding/CMakeLists.txt11
-rw-r--r--sources/shiboken2/tests/minimalbinding/typesystem_minimal.xml2
-rw-r--r--sources/shiboken2/tests/otherbinding/CMakeLists.txt17
-rw-r--r--sources/shiboken2/tests/otherbinding/typesystem_other.xml2
-rw-r--r--sources/shiboken2/tests/samplebinding/CMakeLists.txt11
-rw-r--r--sources/shiboken2/tests/samplebinding/typesystem_sample.xml2
-rw-r--r--sources/shiboken2/tests/smartbinding/CMakeLists.txt11
-rw-r--r--sources/shiboken2/tests/smartbinding/typesystem_smart.xml2
-rw-r--r--testing/wheel_tester.py44
143 files changed, 1680 insertions, 871 deletions
diff --git a/.gitignore b/.gitignore
index 526bdb211..84257ad33 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,17 +1,152 @@
-/build_*
-/dist_*
+## PySide2
/pyside*_build
/pyside*_install
/PySide
/PySide-*.*.*
/SciTE.*
/pysideuic
-*.egg-info
-*.pyc
+
distribute-*.egg
distribute-*.tar.gz
explore2
build_history/2*
+
*.qdocconf
*.qdocconf.in
-__pycache__
+
+*.egg-info
+*.pyc
+
+## C++
+
+# Prerequisites
+*.d
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+*.smod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+
+## Python
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+pip-wheel-metadata/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Translations
+*.mo
+*.pot
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+.python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don’t work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+## CMake
+CMakeLists.txt.user
+CMakeCache.txt
+CMakeFiles
+CMakeScripts
+Testing
+Makefile
+cmake_install.cmake
+install_manifest.txt
+compile_commands.json
+CTestTestfile.cmake
+_deps
diff --git a/build_scripts/platforms/windows_desktop.py b/build_scripts/platforms/windows_desktop.py
index b94c2e1c8..ae0d66682 100644
--- a/build_scripts/platforms/windows_desktop.py
+++ b/build_scripts/platforms/windows_desktop.py
@@ -276,13 +276,15 @@ def copy_msvc_redist_files(vars, redist_target_path):
os.makedirs(redist_target_path)
# Extract Qt dependency dlls when building on Qt CI.
- in_coin = os.environ.get("QTEST_ENVIRONMENT", None) == "ci"
- if in_coin:
+ in_coin = os.environ.get('COIN_LAUNCH_PARAMETERS', None)
+ if in_coin is not None:
redist_url = "http://download.qt.io/development_releases/prebuilt/vcredist/"
zip_file = "pyside_qt_deps_64.7z"
if "{target_arch}".format(**vars) == "32":
zip_file = "pyside_qt_deps_32.7z"
download_and_extract_7z(redist_url + zip_file, redist_target_path)
+ else:
+ print("Qt dependency DLLs (MSVC redist) will not be downloaded and extracted.")
copydir(redist_target_path,
"{st_build_dir}/{st_package_name}",
diff --git a/build_scripts/utils.py b/build_scripts/utils.py
index 6aafb7588..460c1b21f 100644
--- a/build_scripts/utils.py
+++ b/build_scripts/utils.py
@@ -392,7 +392,7 @@ def run_process_output(args, initial_env=None):
std_out = subprocess.Popen(args,
env = initial_env,
universal_newlines = 1,
- stdout=subprocess.PIPE).stdout
+ stdout=subprocess.PIPE).stdout
result = []
for raw_line in std_out.readlines():
line = raw_line if sys.version_info >= (3,) else raw_line.decode('utf-8')
diff --git a/coin_test_instructions.py b/coin_test_instructions.py
index d928b6857..5b08c773e 100644
--- a/coin_test_instructions.py
+++ b/coin_test_instructions.py
@@ -1,6 +1,6 @@
#############################################################################
##
-## Copyright (C) 2018 The Qt Company Ltd.
+## Copyright (C) 2019 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of Qt for Python.
@@ -46,6 +46,7 @@ from build_scripts.utils import rmtree
from build_scripts.utils import acceptCITestConfiguration
from build_scripts.utils import get_ci_qmake_path
import os
+import sys
# Values must match COIN thrift
CI_HOST_OS = option_value("os")
@@ -68,7 +69,7 @@ def call_testrunner(python_ver, buildnro):
_pExe, _env, env_pip, env_python = get_qtci_virtualEnv(python_ver, CI_HOST_OS, CI_HOST_ARCH, CI_TARGET_ARCH)
rmtree(_env, True)
run_instruction(["virtualenv", "-p", _pExe, _env], "Failed to create virtualenv")
- install_pip_dependencies(env_pip, ["numpy", "PyOpenGL", "setuptools", "six"])
+ install_pip_dependencies(env_pip, ["numpy", "PyOpenGL", "setuptools", "six", "pyinstaller"])
install_pip_wheel_package(env_pip)
cmd = [env_python, "testrunner.py", "test",
"--blacklist", "build_history/blacklist.txt",
@@ -77,8 +78,8 @@ def call_testrunner(python_ver, buildnro):
qmake_path = get_ci_qmake_path(CI_ENV_INSTALL_DIR, CI_HOST_OS)
- # Try to install built wheels, and build some buildable examples.
- if CI_RELEASE_CONF:
+ # Try to install built wheels, and build some buildable examples (except macOS/Python 2.16)
+ if CI_RELEASE_CONF and CI_HOST_OS != 'MacOS' or sys.version_info[0] == 3:
wheel_tester_path = os.path.join("testing", "wheel_tester.py")
cmd = [env_python, wheel_tester_path, qmake_path]
run_instruction(cmd, "Error while running wheel_tester.py")
diff --git a/examples/examples.pyproject b/examples/examples.pyproject
index 5c96e9978..559989f9f 100644
--- a/examples/examples.pyproject
+++ b/examples/examples.pyproject
@@ -16,6 +16,7 @@
"declarative/signals/qmltopy3/main.py",
"declarative/signals/qmltopy4/main.py",
"declarative/usingmodel.py",
+ "installer_test/hello.py"
"macextras/macpasteboardmime.py",
"multimedia/audiooutput.py",
"multimedia/camera.py",
diff --git a/examples/installer_test/hello.py b/examples/installer_test/hello.py
new file mode 100644
index 000000000..77b050206
--- /dev/null
+++ b/examples/installer_test/hello.py
@@ -0,0 +1,103 @@
+# This Python file uses the following encoding: utf-8
+# It has been edited by fix-complaints.py .
+
+#############################################################################
+##
+## Copyright (C) 2019 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$
+##
+#############################################################################
+
+"""
+hello.py
+--------
+
+This simple script shows a label with changing "Hello World" messages.
+It can be used directly as a script, but we use it also to automatically
+test PyInstaller. See testing/wheel_tester.py .
+
+When used with PyInstaller, it automatically stops its execution after
+2 seconds.
+"""
+from __future__ import print_function
+
+import sys
+import random
+import platform
+import time
+
+from PySide2.QtWidgets import (QApplication, QLabel, QPushButton,
+ QVBoxLayout, QWidget)
+from PySide2.QtCore import Slot, Qt, QTimer
+
+class MyWidget(QWidget):
+ def __init__(self):
+ QWidget.__init__(self)
+
+ self.hello = ["Hallo Welt", "你好,世界", "Hei maailma",
+ "Hola Mundo", "Привет мир"]
+
+ self.button = QPushButton("Click me!")
+ self.text = QLabel("Hello World embedded={}".format(sys.pyside_uses_embedding))
+ self.text.setAlignment(Qt.AlignCenter)
+
+ self.layout = QVBoxLayout()
+ self.layout.addWidget(self.text)
+ self.layout.addWidget(self.button)
+ self.setLayout(self.layout)
+
+ # Connecting the signal
+ self.button.clicked.connect(self.magic)
+
+ @Slot()
+ def magic(self):
+ self.text.setText(random.choice(self.hello))
+
+if __name__ == "__main__":
+ print("Start of hello.py ", time.ctime())
+ print(" sys.version = {}".format(sys.version.splitlines()[0]))
+ print(" platform.platform() = {}".format(platform.platform()))
+
+ app = QApplication()
+
+ widget = MyWidget()
+ widget.resize(800, 600)
+ widget.show()
+ if sys.pyside_uses_embedding:
+ milliseconds = 2 * 1000 # run 2 second
+ QTimer.singleShot(milliseconds, app.quit)
+ retcode = app.exec_()
+ print("End of hello.py ", time.ctime())
+ sys.exit(retcode)
diff --git a/examples/installer_test/hello_app.spec b/examples/installer_test/hello_app.spec
new file mode 100644
index 000000000..d096ab170
--- /dev/null
+++ b/examples/installer_test/hello_app.spec
@@ -0,0 +1,85 @@
+# This Python file uses the following encoding: utf-8
+# It has been edited by fix-complaints.py .
+
+#############################################################################
+##
+## Copyright (C) 2019 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$
+##
+#############################################################################
+
+"""
+hello_app.spec
+
+This is almost the spec file generated by running PyInstaller.
+Just the paths were adjusted and made relative.
+As an effect, all the analysis is avoided, and the log file of
+wheel_tester.py went down from 775 lines to 278 lines. :-)
+"""
+
+block_cipher = None
+
+
+a = Analysis(['hello.py'],
+ pathex=['pyinstaller'],
+ binaries=[],
+ datas=[],
+ hiddenimports=[],
+ hookspath=[],
+ runtime_hooks=[],
+ excludes=[],
+ win_no_prefer_redirects=False,
+ win_private_assemblies=False,
+ cipher=block_cipher,
+ noarchive=False)
+pyz = PYZ(a.pure, a.zipped_data,
+ cipher=block_cipher)
+exe = EXE(pyz,
+ a.scripts,
+ [],
+ exclude_binaries=True,
+ name='hello_app',
+ debug=False,
+ bootloader_ignore_signals=False,
+ strip=False,
+ upx=True,
+ console=True )
+coll = COLLECT(exe,
+ a.binaries,
+ a.zipfiles,
+ a.datas,
+ strip=False,
+ upx=True,
+ name='hello_app')
diff --git a/examples/utils/pyside2_config.py b/examples/utils/pyside2_config.py
index c62b38cad..973410100 100644
--- a/examples/utils/pyside2_config.py
+++ b/examples/utils/pyside2_config.py
@@ -1,6 +1,6 @@
#############################################################################
##
-## Copyright (C) 2018 The Qt Company Ltd.
+## Copyright (C) 2019 The Qt Company Ltd.
## Contact: http://www.qt.io/licensing/
##
## This file is part of the Qt for Python examples of the Qt Toolkit.
@@ -149,7 +149,7 @@ def shared_library_suffix():
def import_suffixes():
if (sys.version_info >= (3, 4)):
- import importlib
+ import importlib.machinery
return importlib.machinery.EXTENSION_SUFFIXES
else:
import imp
diff --git a/sources/pyside2/PySide2/Qt3DAnimation/typesystem_3danimation.xml b/sources/pyside2/PySide2/Qt3DAnimation/typesystem_3danimation.xml
index cf72b8402..567d7e25a 100644
--- a/sources/pyside2/PySide2/Qt3DAnimation/typesystem_3danimation.xml
+++ b/sources/pyside2/PySide2/Qt3DAnimation/typesystem_3danimation.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml b/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml
index 83e96abe7..b7369f4a1 100644
--- a/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml
+++ b/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/Qt3DExtras/typesystem_3dextras.xml b/sources/pyside2/PySide2/Qt3DExtras/typesystem_3dextras.xml
index 54f4df3df..25fe11a59 100644
--- a/sources/pyside2/PySide2/Qt3DExtras/typesystem_3dextras.xml
+++ b/sources/pyside2/PySide2/Qt3DExtras/typesystem_3dextras.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/Qt3DInput/typesystem_3dinput.xml b/sources/pyside2/PySide2/Qt3DInput/typesystem_3dinput.xml
index 6107f0b26..a74c3ab93 100644
--- a/sources/pyside2/PySide2/Qt3DInput/typesystem_3dinput.xml
+++ b/sources/pyside2/PySide2/Qt3DInput/typesystem_3dinput.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/Qt3DLogic/typesystem_3dlogic.xml b/sources/pyside2/PySide2/Qt3DLogic/typesystem_3dlogic.xml
index ec9ed9ef6..1583f9e29 100644
--- a/sources/pyside2/PySide2/Qt3DLogic/typesystem_3dlogic.xml
+++ b/sources/pyside2/PySide2/Qt3DLogic/typesystem_3dlogic.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/Qt3DRender/typesystem_3drender.xml b/sources/pyside2/PySide2/Qt3DRender/typesystem_3drender.xml
index 9843a4591..be06a3135 100644
--- a/sources/pyside2/PySide2/Qt3DRender/typesystem_3drender.xml
+++ b/sources/pyside2/PySide2/Qt3DRender/typesystem_3drender.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtAxContainer/typesystem_axcontainer.xml b/sources/pyside2/PySide2/QtAxContainer/typesystem_axcontainer.xml
index 427a6f051..27746237a 100644
--- a/sources/pyside2/PySide2/QtAxContainer/typesystem_axcontainer.xml
+++ b/sources/pyside2/PySide2/QtAxContainer/typesystem_axcontainer.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtCharts/typesystem_charts.xml b/sources/pyside2/PySide2/QtCharts/typesystem_charts.xml
index 14224751c..b8550ef2c 100644
--- a/sources/pyside2/PySide2/QtCharts/typesystem_charts.xml
+++ b/sources/pyside2/PySide2/QtCharts/typesystem_charts.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtConcurrent/typesystem_concurrent.xml b/sources/pyside2/PySide2/QtConcurrent/typesystem_concurrent.xml
index bdf4e6fa7..7e7bd9bcc 100644
--- a/sources/pyside2/PySide2/QtConcurrent/typesystem_concurrent.xml
+++ b/sources/pyside2/PySide2/QtConcurrent/typesystem_concurrent.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
index 17773be05..ef8b1b4c5 100644
--- a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
+++ b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_mac.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_mac.xml
index c1a1abcb3..6e1a55557 100644
--- a/sources/pyside2/PySide2/QtCore/typesystem_core_mac.xml
+++ b/sources/pyside2/PySide2/QtCore/typesystem_core_mac.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_win.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_win.xml
index afd733b35..8e3fa6f5e 100644
--- a/sources/pyside2/PySide2/QtCore/typesystem_core_win.xml
+++ b/sources/pyside2/PySide2/QtCore/typesystem_core_win.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_x11.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_x11.xml
index c3cbd3666..88cbf7638 100644
--- a/sources/pyside2/PySide2/QtCore/typesystem_core_x11.xml
+++ b/sources/pyside2/PySide2/QtCore/typesystem_core_x11.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml b/sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml
index 94e6f4b88..f10aeea3e 100644
--- a/sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml
+++ b/sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml
index eaff93345..cadfc33fa 100644
--- a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml
+++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
@@ -2878,6 +2878,9 @@
<modify-function signature="setAttributeArray(const char*,const float*,int,int)">
<modify-argument index="2"><array/></modify-argument>
</modify-function>
+ <modify-function signature="setAttributeArray(int,const float*,int,int)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
<modify-function signature="setAttributeValue(int,const float*,int,int)">
<modify-argument index="2"><array/></modify-argument>
</modify-function>
@@ -2902,6 +2905,26 @@
<modify-function signature="setUniformValueArray(const char*,const unsigned int*,int)">
<modify-argument index="2"><array/></modify-argument>
</modify-function>
+ <!-- Add explicit signatures for the setUniformValue functions -->
+ <modify-function signature="setUniformValue(const char*, GLfloat)" remove="all"/>
+ <modify-function signature="setUniformValue(const char*, GLint)" remove="all"/>
+ <modify-function signature="setUniformValue(const char*, GLuint)" remove="all"/>
+ <modify-function signature="setUniformValue(int, GLfloat)" remove="all"/>
+ <modify-function signature="setUniformValue(int, GLint)" remove="all"/>
+ <modify-function signature="setUniformValue(int, GLuint)" remove="all"/>
+ <!-- No need for a signature for GLuint, since Qt (internally) calls the same function: glUniform1i -->
+ <add-function signature="setUniformValue1f(const char*, float)" return-type="void">
+ <inject-code file="../glue/qtgui.cpp" snippet="qopenglshaderprogram_setuniformvalue_float"/>
+ </add-function>
+ <add-function signature="setUniformValue1i(const char*, int)" return-type="void">
+ <inject-code file="../glue/qtgui.cpp" snippet="qopenglshaderprogram_setuniformvalue_int"/>
+ </add-function>
+ <add-function signature="setUniformValue1f(int, float)" return-type="void">
+ <inject-code file="../glue/qtgui.cpp" snippet="qopenglshaderprogram_setuniformvalue_float"/>
+ </add-function>
+ <add-function signature="setUniformValue1i(int, int)" return-type="void">
+ <inject-code file="../glue/qtgui.cpp" snippet="qopenglshaderprogram_setuniformvalue_int"/>
+ </add-function>
</object-type>
<object-type name="QOpenGLTexture" since="5.2">
<enum-type name="BindingTarget"/>
diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_mac.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_mac.xml
index 4d24d5703..8b071a18b 100644
--- a/sources/pyside2/PySide2/QtGui/typesystem_gui_mac.xml
+++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_mac.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_win.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_win.xml
index 66d47d330..6386cbd25 100644
--- a/sources/pyside2/PySide2/QtGui/typesystem_gui_win.xml
+++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_win.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_x11.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_x11.xml
index 66d47d330..6386cbd25 100644
--- a/sources/pyside2/PySide2/QtGui/typesystem_gui_x11.xml
+++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_x11.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtHelp/typesystem_help.xml b/sources/pyside2/PySide2/QtHelp/typesystem_help.xml
index 922dcde5d..cd62f8afd 100644
--- a/sources/pyside2/PySide2/QtHelp/typesystem_help.xml
+++ b/sources/pyside2/PySide2/QtHelp/typesystem_help.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtLocation/typesystem_location.xml b/sources/pyside2/PySide2/QtLocation/typesystem_location.xml
index d1885756e..6792992cf 100644
--- a/sources/pyside2/PySide2/QtLocation/typesystem_location.xml
+++ b/sources/pyside2/PySide2/QtLocation/typesystem_location.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtMacExtras/typesystem_macextras.xml b/sources/pyside2/PySide2/QtMacExtras/typesystem_macextras.xml
index 0fecf0459..d62ce48b8 100644
--- a/sources/pyside2/PySide2/QtMacExtras/typesystem_macextras.xml
+++ b/sources/pyside2/PySide2/QtMacExtras/typesystem_macextras.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia.xml b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia.xml
index ebd003bf0..323c50ba8 100644
--- a/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia.xml
+++ b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml
index a976c42fc..2e69f98e0 100644
--- a/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml
+++ b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_forward_declarations.xml b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_forward_declarations.xml
index fec0e2806..733e9b262 100644
--- a/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_forward_declarations.xml
+++ b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_forward_declarations.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtMultimediaWidgets/typesystem_multimediawidgets.xml b/sources/pyside2/PySide2/QtMultimediaWidgets/typesystem_multimediawidgets.xml
index 550ae17eb..690220528 100644
--- a/sources/pyside2/PySide2/QtMultimediaWidgets/typesystem_multimediawidgets.xml
+++ b/sources/pyside2/PySide2/QtMultimediaWidgets/typesystem_multimediawidgets.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml b/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml
index 897b2efbc..e128d431e 100644
--- a/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml
+++ b/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtOpenGL/typesystem_opengl.xml b/sources/pyside2/PySide2/QtOpenGL/typesystem_opengl.xml
index a234e95d6..27c515170 100644
--- a/sources/pyside2/PySide2/QtOpenGL/typesystem_opengl.xml
+++ b/sources/pyside2/PySide2/QtOpenGL/typesystem_opengl.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtPositioning/typesystem_positioning.xml b/sources/pyside2/PySide2/QtPositioning/typesystem_positioning.xml
index 718b0b3e1..5a7208950 100644
--- a/sources/pyside2/PySide2/QtPositioning/typesystem_positioning.xml
+++ b/sources/pyside2/PySide2/QtPositioning/typesystem_positioning.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport_common.xml b/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport_common.xml
index 5026997c1..c11a6e046 100644
--- a/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport_common.xml
+++ b/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport_common.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtQml/typesystem_qml.xml b/sources/pyside2/PySide2/QtQml/typesystem_qml.xml
index ef370ad02..b61b28c07 100644
--- a/sources/pyside2/PySide2/QtQml/typesystem_qml.xml
+++ b/sources/pyside2/PySide2/QtQml/typesystem_qml.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml b/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml
index 2dc90b9e0..64b4e8412 100644
--- a/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml
+++ b/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtQuickWidgets/typesystem_quickwidgets.xml b/sources/pyside2/PySide2/QtQuickWidgets/typesystem_quickwidgets.xml
index e44ef8e6d..b77e06573 100644
--- a/sources/pyside2/PySide2/QtQuickWidgets/typesystem_quickwidgets.xml
+++ b/sources/pyside2/PySide2/QtQuickWidgets/typesystem_quickwidgets.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtRemoteObjects/typesystem_remoteobjects.xml b/sources/pyside2/PySide2/QtRemoteObjects/typesystem_remoteobjects.xml
index 8058cb56c..d8d54b4fb 100644
--- a/sources/pyside2/PySide2/QtRemoteObjects/typesystem_remoteobjects.xml
+++ b/sources/pyside2/PySide2/QtRemoteObjects/typesystem_remoteobjects.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtScript/typesystem_script.xml b/sources/pyside2/PySide2/QtScript/typesystem_script.xml
index f87e4cfdf..1fdad5d47 100644
--- a/sources/pyside2/PySide2/QtScript/typesystem_script.xml
+++ b/sources/pyside2/PySide2/QtScript/typesystem_script.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtScriptTools/typesystem_scripttools.xml b/sources/pyside2/PySide2/QtScriptTools/typesystem_scripttools.xml
index 770a2f25f..eefa09a54 100644
--- a/sources/pyside2/PySide2/QtScriptTools/typesystem_scripttools.xml
+++ b/sources/pyside2/PySide2/QtScriptTools/typesystem_scripttools.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtScxml/typesystem_scxml.xml b/sources/pyside2/PySide2/QtScxml/typesystem_scxml.xml
index f6402f7e8..c00052c2f 100644
--- a/sources/pyside2/PySide2/QtScxml/typesystem_scxml.xml
+++ b/sources/pyside2/PySide2/QtScxml/typesystem_scxml.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtSensors/typesystem_sensors.xml b/sources/pyside2/PySide2/QtSensors/typesystem_sensors.xml
index 5c82db229..31c0d2f53 100644
--- a/sources/pyside2/PySide2/QtSensors/typesystem_sensors.xml
+++ b/sources/pyside2/PySide2/QtSensors/typesystem_sensors.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtSql/typesystem_sql.xml b/sources/pyside2/PySide2/QtSql/typesystem_sql.xml
index c8a56a213..408b5cdce 100644
--- a/sources/pyside2/PySide2/QtSql/typesystem_sql.xml
+++ b/sources/pyside2/PySide2/QtSql/typesystem_sql.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtSvg/typesystem_svg.xml b/sources/pyside2/PySide2/QtSvg/typesystem_svg.xml
index 6523ce541..079a79e96 100644
--- a/sources/pyside2/PySide2/QtSvg/typesystem_svg.xml
+++ b/sources/pyside2/PySide2/QtSvg/typesystem_svg.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtTest/typesystem_test.xml b/sources/pyside2/PySide2/QtTest/typesystem_test.xml
index ea231f2ee..f7facaf7d 100644
--- a/sources/pyside2/PySide2/QtTest/typesystem_test.xml
+++ b/sources/pyside2/PySide2/QtTest/typesystem_test.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml b/sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml
index fee04f444..48a5bc9f4 100644
--- a/sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml
+++ b/sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml b/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml
index c3b800454..7b27e8783 100644
--- a/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml
+++ b/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtWebChannel/typesystem_webchannel.xml b/sources/pyside2/PySide2/QtWebChannel/typesystem_webchannel.xml
index a1cfb91f2..c47d5fa08 100644
--- a/sources/pyside2/PySide2/QtWebChannel/typesystem_webchannel.xml
+++ b/sources/pyside2/PySide2/QtWebChannel/typesystem_webchannel.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtWebEngine/typesystem_webengine.xml b/sources/pyside2/PySide2/QtWebEngine/typesystem_webengine.xml
index 9b38bc1e6..7d0875a2c 100644
--- a/sources/pyside2/PySide2/QtWebEngine/typesystem_webengine.xml
+++ b/sources/pyside2/PySide2/QtWebEngine/typesystem_webengine.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtWebEngineCore/typesystem_webenginecore.xml b/sources/pyside2/PySide2/QtWebEngineCore/typesystem_webenginecore.xml
index 67399b54f..eb1ab3d61 100644
--- a/sources/pyside2/PySide2/QtWebEngineCore/typesystem_webenginecore.xml
+++ b/sources/pyside2/PySide2/QtWebEngineCore/typesystem_webenginecore.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtWebEngineWidgets/typesystem_webenginewidgets.xml b/sources/pyside2/PySide2/QtWebEngineWidgets/typesystem_webenginewidgets.xml
index cd4cd8a91..e0821a114 100644
--- a/sources/pyside2/PySide2/QtWebEngineWidgets/typesystem_webenginewidgets.xml
+++ b/sources/pyside2/PySide2/QtWebEngineWidgets/typesystem_webenginewidgets.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtWebKit/typesystem_webkit.xml b/sources/pyside2/PySide2/QtWebKit/typesystem_webkit.xml
index 5feb61343..e92417f26 100644
--- a/sources/pyside2/PySide2/QtWebKit/typesystem_webkit.xml
+++ b/sources/pyside2/PySide2/QtWebKit/typesystem_webkit.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtWebKitWidgets/typesystem_webkitwidgets.xml b/sources/pyside2/PySide2/QtWebKitWidgets/typesystem_webkitwidgets.xml
index dfabff81d..7760c1c3d 100644
--- a/sources/pyside2/PySide2/QtWebKitWidgets/typesystem_webkitwidgets.xml
+++ b/sources/pyside2/PySide2/QtWebKitWidgets/typesystem_webkitwidgets.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtWebSockets/typesystem_websockets.xml b/sources/pyside2/PySide2/QtWebSockets/typesystem_websockets.xml
index cd81439cb..4257a998b 100644
--- a/sources/pyside2/PySide2/QtWebSockets/typesystem_websockets.xml
+++ b/sources/pyside2/PySide2/QtWebSockets/typesystem_websockets.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
index a41a27c33..207c3e831 100644
--- a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
+++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_mac.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_mac.xml
index b9aec3923..af607ce1e 100644
--- a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_mac.xml
+++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_mac.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_win.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_win.xml
index 5bacf63fb..4c51907fe 100644
--- a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_win.xml
+++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_win.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_x11.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_x11.xml
index 5bacf63fb..4c51907fe 100644
--- a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_x11.xml
+++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_x11.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtWinExtras/typesystem_winextras.xml b/sources/pyside2/PySide2/QtWinExtras/typesystem_winextras.xml
index 2ffd7905d..ec17428a1 100644
--- a/sources/pyside2/PySide2/QtWinExtras/typesystem_winextras.xml
+++ b/sources/pyside2/PySide2/QtWinExtras/typesystem_winextras.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtX11Extras/typesystem_x11extras.xml b/sources/pyside2/PySide2/QtX11Extras/typesystem_x11extras.xml
index 5958f5a99..73fc2b77c 100644
--- a/sources/pyside2/PySide2/QtX11Extras/typesystem_x11extras.xml
+++ b/sources/pyside2/PySide2/QtX11Extras/typesystem_x11extras.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtXml/typesystem_xml.xml b/sources/pyside2/PySide2/QtXml/typesystem_xml.xml
index 59343543a..e1750fb80 100644
--- a/sources/pyside2/PySide2/QtXml/typesystem_xml.xml
+++ b/sources/pyside2/PySide2/QtXml/typesystem_xml.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/QtXmlPatterns/typesystem_xmlpatterns.xml b/sources/pyside2/PySide2/QtXmlPatterns/typesystem_xmlpatterns.xml
index dedcfdd7c..1e8eec083 100644
--- a/sources/pyside2/PySide2/QtXmlPatterns/typesystem_xmlpatterns.xml
+++ b/sources/pyside2/PySide2/QtXmlPatterns/typesystem_xmlpatterns.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp
index 6259724c3..fde016548 100644
--- a/sources/pyside2/PySide2/glue/qtcore.cpp
+++ b/sources/pyside2/PySide2/glue/qtcore.cpp
@@ -1139,11 +1139,7 @@ if (PyBytes_Check(%PYARG_1)) {
Shiboken::SbkType<QByteArray>()->tp_as_buffer = &SbkQByteArrayBufferProc;
Shiboken::SbkType<QByteArray>()->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
#else
-#ifdef Py_LIMITED_API
PepType_AS_BUFFER(Shiboken::SbkType<QByteArray>()) = &SbkQByteArrayBufferProc;
-#else
-Shiboken::SbkType<QByteArray>()->tp_as_buffer = &SbkQByteArrayBufferProc;
-#endif
#endif
// @snippet qbytearray-py3
diff --git a/sources/pyside2/PySide2/glue/qtgui.cpp b/sources/pyside2/PySide2/glue/qtgui.cpp
index 4ae3eef75..aef9e4b59 100644
--- a/sources/pyside2/PySide2/glue/qtgui.cpp
+++ b/sources/pyside2/PySide2/glue/qtgui.cpp
@@ -115,6 +115,16 @@ if (doc) {
}
// @snippet qtextblock-userdata
+// @snippet qopenglshaderprogram_setuniformvalue_float
+float value = %2;
+%CPPSELF.setUniformValue(%1, value);
+// @snippet qopenglshaderprogram_setuniformvalue_float
+
+// @snippet qopenglshaderprogram_setuniformvalue_int
+int value = %2;
+%CPPSELF.setUniformValue(%1, value);
+// @snippet qopenglshaderprogram_setuniformvalue_int
+
// @snippet qpolygon-reduce
PyObject *points = PyList_New(%CPPSELF.count());
for (int i = 0, i_max = %CPPSELF.count(); i < i_max; ++i){
diff --git a/sources/pyside2/PySide2/support/generate_pyi.py b/sources/pyside2/PySide2/support/generate_pyi.py
index 3b4b3409a..f286e34f1 100644
--- a/sources/pyside2/PySide2/support/generate_pyi.py
+++ b/sources/pyside2/PySide2/support/generate_pyi.py
@@ -256,11 +256,7 @@ def generate_pyi(import_name, outpath, options):
logger.info("Generated: {outfilepath}".format(**locals()))
if is_py3:
# Python 3: We can check the file directly if the syntax is ok.
- try:
- subprocess.check_output([sys.executable, outfilepath])
- except Exception as e:
- print("+++ Problem executing test, although it works")
- traceback.print_exc(file=sys.stdout)
+ subprocess.check_output([sys.executable, outfilepath])
return 1
diff --git a/sources/pyside2/PySide2/templates/core_common.xml b/sources/pyside2/PySide2/templates/core_common.xml
index 7c2ae3a77..4b74c6b55 100644
--- a/sources/pyside2/PySide2/templates/core_common.xml
+++ b/sources/pyside2/PySide2/templates/core_common.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/templates/datavisualization_common.xml b/sources/pyside2/PySide2/templates/datavisualization_common.xml
index ee040c977..d5434dc75 100644
--- a/sources/pyside2/PySide2/templates/datavisualization_common.xml
+++ b/sources/pyside2/PySide2/templates/datavisualization_common.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/templates/gui_common.xml b/sources/pyside2/PySide2/templates/gui_common.xml
index d25d50014..363422c8f 100644
--- a/sources/pyside2/PySide2/templates/gui_common.xml
+++ b/sources/pyside2/PySide2/templates/gui_common.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/templates/opengl_common.xml b/sources/pyside2/PySide2/templates/opengl_common.xml
index 46299d8d7..ee7b021dd 100644
--- a/sources/pyside2/PySide2/templates/opengl_common.xml
+++ b/sources/pyside2/PySide2/templates/opengl_common.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/templates/webkitwidgets_common.xml b/sources/pyside2/PySide2/templates/webkitwidgets_common.xml
index 43e560c5f..9d0c8e587 100644
--- a/sources/pyside2/PySide2/templates/webkitwidgets_common.xml
+++ b/sources/pyside2/PySide2/templates/webkitwidgets_common.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/templates/widgets_common.xml b/sources/pyside2/PySide2/templates/widgets_common.xml
index e63785bb2..9ce01e79a 100644
--- a/sources/pyside2/PySide2/templates/widgets_common.xml
+++ b/sources/pyside2/PySide2/templates/widgets_common.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/PySide2/templates/xml_common.xml b/sources/pyside2/PySide2/templates/xml_common.xml
index b13a10c25..0a6ae4906 100644
--- a/sources/pyside2/PySide2/templates/xml_common.xml
+++ b/sources/pyside2/PySide2/templates/xml_common.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
/****************************************************************************
**
diff --git a/sources/pyside2/doc/CMakeLists.txt b/sources/pyside2/doc/CMakeLists.txt
index b5bde885a..36f770367 100644
--- a/sources/pyside2/doc/CMakeLists.txt
+++ b/sources/pyside2/doc/CMakeLists.txt
@@ -90,16 +90,12 @@ add_custom_target(qdoc
add_custom_target(apidoc
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/rst
COMMAND ${SHIBOKEN_PYTHON_INTERPRETER} ${SPHINX_BUILD} -b html ${CMAKE_CURRENT_BINARY_DIR}/rst html
- #copying shiboken2 and ApiExtractor doc htmls
- COMMENT "Copying over the Shiboken2 and ApiExtractor doc HTMLs..."
+ #copying shiboken2 (including ApiExtractor) doc htmls
+ COMMENT "Copying over the Shiboken2 doc HTMLs..."
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken2
- COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken2/ApiExtractor
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_BINARY_DIR}/../../shiboken2/doc/html
${CMAKE_CURRENT_BINARY_DIR}/html/shiboken2
- COMMAND ${CMAKE_COMMAND} -E copy_directory
- ${CMAKE_CURRENT_BINARY_DIR}/../../shiboken2/ApiExtractor/doc/html
- ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken2/ApiExtractor
)
# create conf.py based on conf.py.in
diff --git a/sources/pyside2/doc/contents.rst b/sources/pyside2/doc/contents.rst
index d6b7f6ffb..675a5b73a 100644
--- a/sources/pyside2/doc/contents.rst
+++ b/sources/pyside2/doc/contents.rst
@@ -8,6 +8,7 @@
faq.rst
gettingstarted.rst
tutorials/index.rst
+ deployment.rst
pysideapi2.rst
licenses.rst
diff --git a/sources/pyside2/doc/deployment-cxfreeze.rst b/sources/pyside2/doc/deployment-cxfreeze.rst
new file mode 100644
index 000000000..40b65621b
--- /dev/null
+++ b/sources/pyside2/doc/deployment-cxfreeze.rst
@@ -0,0 +1,130 @@
+=====================
+|project| & cx_Freeze
+=====================
+
+`cx_Freeze <https://anthony-tuininga.github.io/cx_Freeze/>`_ allows you to freeze your Python
+application into executables.
+The supported platforms are Linux, macOS, Windows, FreeBSD, among others.
+
+
+You can read the `official documentation <https://cx-freeze.readthedocs.io/en/latest/index.html>`_
+to clarify any further question, and remember to contribute to
+the project by `filing issues <https://sourceforge.net/projects/cx-freeze/>`_
+if you find any, or contributing to `their development <https://bitbucket.org/anthony_tuininga/cx_freeze/src>`_.
+
+Preparation
+===========
+
+Installing `cx_Freeze` can be done via **pip**::
+
+ pip install cx_freeze
+
+If you are using a virtual environment, remember to activate it before
+installing `cx_Freeze` into it.
+
+After the installation, you will have the `cxfreeze` binary to deploy
+your application.
+
+Freezing an application
+=======================
+
+There are three options to work with `cx_Freeze`:
+
+ 1. Using the `cxfreeze` script.
+ 2. Creating `setup.py` script to build the project.
+ 3. Using the module classes directly (for advanced purposes).
+
+We will cover the first two uses cases.
+
+Creating an example
+-------------------
+
+Now, consider the following simple script, named `hello.py`::
+
+ import sys
+ import random
+ from PySide2.QtWidgets import (QApplication, QLabel, QPushButton,
+ QVBoxLayout, QWidget)
+ from PySide2.QtCore import Slot, Qt
+
+ class MyWidget(QWidget):
+ def __init__(self):
+ QWidget.__init__(self)
+
+ self.hello = ["Hallo Welt", "你好,世界", "Hei maailma",
+ "Hola Mundo", "Привет мир"]
+
+ self.button = QPushButton("Click me!")
+ self.text = QLabel("Hello World")
+ self.text.setAlignment(Qt.AlignCenter)
+
+ self.layout = QVBoxLayout()
+ self.layout.addWidget(self.text)
+ self.layout.addWidget(self.button)
+ self.setLayout(self.layout)
+
+ # Connecting the signal
+ self.button.clicked.connect(self.magic)
+
+ @Slot()
+ def magic(self):
+ self.text.setText(random.choice(self.hello))
+
+ if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ widget = MyWidget()
+ widget.resize(800, 600)
+ widget.show()
+
+ sys.exit(app.exec_())
+
+
+Using `cxfreeze` executable
+---------------------------
+
+The command line to proceed will look like this::
+
+ cxfreeze hello.py
+
+This command will create a `dist/` directory that will contain the
+executable and a `lib/` directory including all the shared libraries.
+
+To launch the application, you need to just go to the `dist/` directory
+and execute the file::
+
+ cd dist/
+ ./main
+
+
+Using a setuptools script
+-------------------------
+
+For this process, you will need an additional script called `setup.py`::
+
+ import sys
+ from cx_Freeze import setup, Executable
+
+ setup(name = "MyApp",
+ version = "0.1",
+ description = "My GUI App",
+ executables = [Executable("hello.py")])
+
+After that, you need to build the project using it::
+
+ python setup.py build
+
+This step will create a `build/` directory with the following structure::
+
+ build
+ └── exe.linux-x86_64-3.7
+ └── lib
+ └── main
+
+The first directory inside `build/` will depend on the platform
+you are using, in this case a `x86_64` Linux using Python 3.7.
+The structure is the same as previously described, and you can simply
+enter the directory and execute the file::
+
+ cd build/exe.linux-x86_64-3.7
+ ./main
diff --git a/sources/pyside2/doc/deployment-fbs.rst b/sources/pyside2/doc/deployment-fbs.rst
new file mode 100644
index 000000000..94c52a08b
--- /dev/null
+++ b/sources/pyside2/doc/deployment-fbs.rst
@@ -0,0 +1,106 @@
+===============
+|project| & fbs
+===============
+
+`fbs <https://build-system.fman.io>`_ provides a powerful environment for packaging,
+creating installers, and signing your application, but also for managing the application's updates.
+Since it is based on PyInstaller, it currently supports Linux, macOS, and Windows.
+
+You can read the `official tutorial <https://github.com/mherrmann/fbs-tutorial>`_ for more
+details on how to use `fbs`, or check the
+`documentation <https://build-system.fman.io/manual/>`_ for a complete set of features and
+options.
+
+Preparation
+===========
+
+Installing `fbs` can be done via **pip**::
+
+ pip install fbs pyinstaller==3.4
+
+If you are using a virtual environment, remember to activate it before
+installing it.
+
+After the installation, you will be able to use the `fbs` executable.
+
+Starting a new project
+======================
+
+`fbs` provides nice features that allow you to create a base
+project structure by executing the following command::
+
+ fbs startproject
+
+This process will prompt you to answer many questions to configure the details
+of your project, like:
+
+ * Application name
+ * Author name
+ * Qt bindings (PySide2 or PyQt5)
+ * Bundle indentified (for macOS)
+
+After the process finishes, you will have a `src/` directory that
+will contain the following structure::
+
+ └── src
+ ├── build
+ │ └── settings
+ └── main
+ ├── icons
+ │ ├── base
+ │ ├── linux
+ │ └── mac
+ └── python
+
+Inside the `settings` directory you can find a couple of `json` files
+that you can edit to include more information about your project.
+
+The main file will be under the `python` directory, and its content by default is::
+
+ from fbs_runtime.application_context import ApplicationContext
+ from PySide2.QtWidgets import QMainWindow
+
+ import sys
+
+ class AppContext(ApplicationContext): # 1. Subclass ApplicationContext
+ def run(self): # 2. Implement run()
+ window = QMainWindow()
+ version = self.build_settings['version']
+ window.setWindowTitle("MyApp v" + version)
+ window.resize(250, 150)
+ window.show()
+ return self.app.exec_() # 3. End run() with this line
+
+ if __name__ == '__main__':
+ appctxt = AppContext() # 4. Instantiate the subclass
+ exit_code = appctxt.run() # 5. Invoke run()
+ sys.exit(exit_code)
+
+The example will show an empty `QMainWindow`, and you can execute it by running::
+
+ fbs run
+
+Freezing the application
+========================
+
+Once you verify that the application is properly working,
+you can continue with the freezing process::
+
+ fbs freeze
+
+After the process finishes, you will get a message stating the location
+of your executable, e.g.::
+
+ Done. You can now run `target/MyApp/MyApp`. If that doesn't work, see
+ https://build-system.fman.io/troubleshooting.
+
+
+Then executing the application will result in the same window
+you saw with the `fbs run` command::
+
+ cd target/MyApp/
+ ./MyApp
+
+.. note:: This is the case for Linux. For other platforms like macOS, you will need to
+ enter the directory: `target/MyApp.app/Contents/MacOS`, and for
+ Windows you will find a `MyApp.exe` executable.
diff --git a/sources/pyside2/doc/deployment-pyinstaller.rst b/sources/pyside2/doc/deployment-pyinstaller.rst
new file mode 100644
index 000000000..8e6a76052
--- /dev/null
+++ b/sources/pyside2/doc/deployment-pyinstaller.rst
@@ -0,0 +1,124 @@
+=======================
+|project| & PyInstaller
+=======================
+
+`PyInstaller <https://www.pyinstaller.org/>`_ allows you to freeze your python
+application into a stand-alone executable.
+The supported platforms are Linux, macOS, Windows, FreeBSD, and others.
+
+One of the main goals of `PyInstaller` is to be compatible with 3rd-party
+Python modules, e.g.: |pymodname|.
+
+You can read the `official documentation <https://www.pyinstaller.org/documentation.html>`_
+to clarify any further question, and remember to contribute to
+`the project <https://github.com/pyinstaller/pyinstaller>`_
+by filing issues if you find any, or contributing to their development.
+
+Preparation
+===========
+
+Installing `PyInstaller` can be done via **pip**::
+
+ pip install pyinstaller
+
+If you are using a virtual environment, remember to activate it before
+installing `PyInstaller` into it.
+
+After the installation, the `pyinstaller` binary will be located in the `bin/`
+directory of your virtual environment, or where your Python executable is located.
+
+If that directory is not in your `PATH`, you need to include the whole path
+when executing `pyinstaller`.
+
+.. warning:: If you already have PySide2 or Shiboken2 installed in your system, PyInstaller will pick them
+ instead of your virtual environment ones.
+
+Freezing an application
+=======================
+
+`PyInstaller` has many options that you can use.
+To learn more about them you can just run `pyinstaller -h`.
+
+Two main features are the option to package the whole project
+(including the shared libraries) into one executable file (`--onefile`),
+and to prepare a directory that will contain
+an executable next to all the used libraries.
+
+Additionally, for Windows you can enable opening a console during the
+execution with the option `-c` (or equivalent `--console` or `--nowindowed`).
+Further, you can specify to not open such console window
+on macOS and Windows with the option `-w` (or equivalent `--windowed` or `--noconsole`).
+
+Creating an example
+-------------------
+
+Now, consider the following simple script, named `hello.py`::
+
+ import sys
+ import random
+ from PySide2.QtWidgets import (QApplication, QLabel, QPushButton,
+ QVBoxLayout, QWidget)
+ from PySide2.QtCore import Slot, Qt
+
+ class MyWidget(QWidget):
+ def __init__(self):
+ QWidget.__init__(self)
+
+ self.hello = ["Hallo Welt", "你好,世界", "Hei maailma",
+ "Hola Mundo", "Привет мир"]
+
+ self.button = QPushButton("Click me!")
+ self.text = QLabel("Hello World")
+ self.text.setAlignment(Qt.AlignCenter)
+
+ self.layout = QVBoxLayout()
+ self.layout.addWidget(self.text)
+ self.layout.addWidget(self.button)
+ self.setLayout(self.layout)
+
+ # Connecting the signal
+ self.button.clicked.connect(self.magic)
+
+ @Slot()
+ def magic(self):
+ self.text.setText(random.choice(self.hello))
+
+ if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ widget = MyWidget()
+ widget.resize(800, 600)
+ widget.show()
+
+ sys.exit(app.exec_())
+
+
+Since it has a UI, we will use the `--windowed` option.
+
+The command line to proceed will look like this::
+
+ pyinstaller --name="MyApplication" --windowed hello.py
+
+This process will create a `dist/` and `build/` directory.
+The executable and all the shared libraries required by your application
+will be placed inside `dist/MyApplication`.
+
+To execute the frozen application you can go inside `dist/MyApplication` and
+execute the program::
+
+ cd dist/MyApplication/
+ ./MyApplication
+
+.. note:: The directory inside `dist/` and the executable will have the same name.
+
+If you prefer to have everything bundled into one executable, i.e.:
+no shared libraries next to the executable, you can use the option
+`--onefile`::
+
+ pyinstaller --name="MyApplication" --windowed --onefile hello.py
+
+This process will take a bit longer, but in the end you will discover
+an executable inside the `dist/` directory that you can execute::
+
+ cd dist/
+ ./MyApplication
diff --git a/sources/pyside2/doc/deployment.rst b/sources/pyside2/doc/deployment.rst
new file mode 100644
index 000000000..582e38992
--- /dev/null
+++ b/sources/pyside2/doc/deployment.rst
@@ -0,0 +1,70 @@
+==========
+Deployment
+==========
+
+Deploying or freezing an application is a crucial part of many Python projects.
+Most large projects are not based on a single Python file, so
+the distribution of these applications becomes more difficult.
+
+The options for a project are:
+ 1. Sending a normal zip-file with the application's content.
+ 2. Building a proper `Python package (wheel) <https://packaging.python.org/>`_.
+ 3. Freezing the application in a single binary file, or into a directory.
+
+For the **third** option, there are many available tools:
+ * `PyInstaller <https://www.pyinstaller.org/>`_,
+ * `cx_Freeze <https://anthony-tuininga.github.io/cx_Freeze/>`_,
+ * `py2exe <http://www.py2exe.org/>`_,
+ * `py2app <https://py2app.readthedocs.io/en/latest/>`_,
+
+Since |project| is a cross-platform framework,
+we would like to focus on solutions that at least work on
+the three major platform supported by Qt: Linux, macOS, and Windows.
+
+The following table summarizes the above mentioned tools support:
+
+=========== ======= ===== ===== =======
+Name License Linux macOS Windows
+=========== ======= ===== ===== =======
+py2exe MIT no no yes
+py2app MIT no yes no
+cx_Freeze MIT yes yes yes
+PyInstaller GPL yes yes yes
+=========== ======= ===== ===== =======
+
+From the table we can see that only *cx_Freeze* and *PyInstaller*
+meet our requirements.
+
+All tools are command-line based, and it could become
+a hard task to include more resources to your application, such as
+images, icons, and meta-information, because you will need to create
+special hooks or separate scripts to handle them.
+Additionally, since this only
+allows you to freeze your current application, you don't have
+any mechanism to update your application.
+
+To cover the update part, there is a tool built around PyInstaller
+called `PyUpdater <https://www.pyupdater.org/>`_ which enables
+a simple mechanism to ship applications updates.
+
+On top of all these features, including also a nice interface
+that allows the user to install the application step by step,
+or even better, provide templates to create new projects to easily
+freeze-them-up is something really beneficial for both developers
+and end-users.
+This is where `fbs <https://build-system.fman.io>`_ enters the
+game, being based on PyInstaller, but including all the nice features
+we previously mentioned.
+
+Here you can find a set of tutorials on how to use the previously
+described tools.
+
+.. note:: Deployment is possible only in Qt for Python 5.12.2
+
+.. toctree::
+ :name: mastertoc
+ :maxdepth: 2
+
+ deployment-pyinstaller.rst
+ deployment-cxfreeze.rst
+ deployment-fbs.rst
diff --git a/sources/pyside2/doc/faq.rst b/sources/pyside2/doc/faq.rst
index e09d98999..aabd017e9 100644
--- a/sources/pyside2/doc/faq.rst
+++ b/sources/pyside2/doc/faq.rst
@@ -29,11 +29,11 @@ Frequently Asked Questions
**Does PySide2 have support for embedded Linux (Raspberry Pi, i.MX6 etc)?**
Not at the moment.
-**There are three wheels (pyside2, shiboken2, and shiboken2_generator)
- what is the different between them?**
+**There are three wheels (pyside2, shiboken2, and shiboken2_generator), what is the different between them?**
Before the official release, everything was in one big wheel, but it made sense to split
the projects in three different wheels:
+
* **pyside2**: contains all the PySide2 modules to use the Qt framework.
Also depends on the shiboken2 module.
* **shiboken2**: contains the shiboken2 module with helper functions for PySide2.
diff --git a/sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst b/sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst
index afec6d84f..accb54aea 100644
--- a/sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst
+++ b/sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst
@@ -11,6 +11,7 @@ click it.
Let's start by importing the necessary PySide2 classes and python
`sys` module:
::
+
import sys
from PySide2.QtWidgets import QApplication, QPushButton
from PySide2.QtCore import Slot
@@ -31,12 +32,14 @@ console:
Now, as mentioned in previous examples you must create the
`QApplication` to run your PySide2 code:
::
+
# Create the Qt Application
app = QApplication(sys.argv)
Let's create the clickable button, which is a `QPushButton` instance.
To label the button, we pass a python string to the constructor:
::
+
# Create a button
button = QPushButton("Click me")
@@ -52,11 +55,13 @@ The `QPushButton` has a predefined signal called **clicked**, which
is triggered every time the button is clicked. We'll connect this
signal to the `say_hello()` function:
::
+
# Connect the button to the function
button.clicked.connect(say_hello)
Finally, we show the button and start the Qt main loop:
::
+
# Show the button
button.show()
# Run the main Qt loop
@@ -64,6 +69,7 @@ Finally, we show the button and start the Qt main loop:
Here is the complete code for this example:
::
+
#!/usr/bin/python
import sys
diff --git a/sources/pyside2/doc/tutorials/basictutorial/dialog.rst b/sources/pyside2/doc/tutorials/basictutorial/dialog.rst
index 1daa6b89d..cdb356b91 100644
--- a/sources/pyside2/doc/tutorials/basictutorial/dialog.rst
+++ b/sources/pyside2/doc/tutorials/basictutorial/dialog.rst
@@ -10,6 +10,7 @@ Let us just start with a simple stub that creates and shows
a dialog. This stub is updated during the course of this
tutorial, but you can use this stub as is if you need to:
::
+
import sys
from PySide2.QtWidgets import QApplication, QDialog, QLineEdit, QPushButton
@@ -49,6 +50,7 @@ enter their name, and a `QPushButton` that prints the contents of
the `QLineEdit`.
So, let's add the following code to the `init()` method of our Form:
::
+
# Create widgets
self.edit = QLineEdit("Write my name here..")
self.button = QPushButton("Show Greetings")
@@ -64,6 +66,7 @@ in your application. In this case, let's use `QVBoxLayout` to lay out
the widgets vertically. Add the following code to the `init()` method,
after creating the widgets:
::
+
# Create layout and add widgets
layout = QVBoxLayout()
layout.addWidget(self.edit)
@@ -82,6 +85,7 @@ Finally, we just have to add a function to our custom **Form**
and *connect* our button to it. Our function will be a part of
the Form, so you have to add it after the `init()` function:
::
+
# Greets the user
def greetings(self):
print ("Hello {}".format(self.edit.text()))
@@ -94,6 +98,7 @@ Now that we have everything, we just need to *connect* the
`QPushButton` to the `Form.greetings()` method. To do so, add the
following line to the `init()` method:
::
+
# Add button signal to greetings slot
self.button.clicked.connect(self.greetings)
@@ -105,6 +110,7 @@ Complete code
Here is the complete code for this tutorial:
::
+
import sys
from PySide2.QtWidgets import (QLineEdit, QPushButton, QApplication,
QVBoxLayout, QDialog)
diff --git a/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst b/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst
index 00731abc3..b00437bcb 100644
--- a/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst
+++ b/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst
@@ -15,6 +15,7 @@ Add a `QPushButton` to the center of the centralwidget.
Your file (mainwindow.ui) should look something like this:
::
+
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
@@ -79,11 +80,13 @@ Another option to interact with a **UI file** is to generate a Python
class from it. This is possible thanks to the `pyside2-uic` tool.
To use this tool, you need to run the following command on a console:
::
+
pyside2-uic mainwindow.ui > ui_mainwindow.py
We redirect all the output of the command to a file called `ui_mainwindow.py`,
which will be imported directly:
::
+
from ui_mainwindow import Ui_MainWindow
Now to use it, we should create a personalized class for our widget
@@ -91,6 +94,7 @@ to **setup** this generated design.
To understand the idea, let's take a look at the whole code:
::
+
import sys
from PySide2.QtWidgets import QApplication, QMainWindow
from PySide2.QtCore import QFile
@@ -115,6 +119,7 @@ examples, and our new basic class contains only two new lines
that are in charge of loading the generated python class from the UI
file:
::
+
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
@@ -127,6 +132,7 @@ Loading it directly
To load the UI file directly, we will need a class from the **QtUiTools**
module:
::
+
from PySide2.QtUiTools import QUiLoader
The `QUiLoader` lets us load the **ui file** dynamically
@@ -141,6 +147,7 @@ and use it right away:
The complete code of this example looks like this:
::
+
# File: main.py
import sys
from PySide2.QtUiTools import QUiLoader
@@ -163,4 +170,5 @@ The complete code of this example looks like this:
Then to execute it we just need to run the following on a
command prompt:
::
+
python main.py
diff --git a/sources/pyside2/doc/tutorials/examples/tabbedbrowser.rst b/sources/pyside2/doc/tutorials/examples/tabbedbrowser.rst
index d291e8399..c34c50647 100644
--- a/sources/pyside2/doc/tutorials/examples/tabbedbrowser.rst
+++ b/sources/pyside2/doc/tutorials/examples/tabbedbrowser.rst
@@ -5,6 +5,7 @@ Web Browser Example
The example demonstrates the power and simplicity offered by |project| to developers.
It uses several |pymodname| submodules to offer a fluid and modern-looking UI that
is apt for a web browser. The application offers the following features:
+
* Tab-based browsing experience using QTabWidget.
* Download manager using a QProgressBar and QWebEngineDownloadItem.
* Bookmark manager using QTreeView.
diff --git a/sources/pyside2/tests/pysidetest/typesystem_pysidetest.xml b/sources/pyside2/tests/pysidetest/typesystem_pysidetest.xml
index bf9c29386..1904f236f 100644
--- a/sources/pyside2/tests/pysidetest/typesystem_pysidetest.xml
+++ b/sources/pyside2/tests/pysidetest/typesystem_pysidetest.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<typesystem package="testbinding">
<load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
<value-type name="IntValue"/>
diff --git a/sources/shiboken2/ApiExtractor/CMakeLists.txt b/sources/shiboken2/ApiExtractor/CMakeLists.txt
index 4c0ac7b30..147fda377 100644
--- a/sources/shiboken2/ApiExtractor/CMakeLists.txt
+++ b/sources/shiboken2/ApiExtractor/CMakeLists.txt
@@ -2,30 +2,8 @@ project(apiextractor)
cmake_minimum_required(VERSION 3.1)
cmake_policy(VERSION 3.1)
-find_package(LibXml2 2.6.32)
-find_package(LibXslt 1.1.19)
-option(DISABLE_DOCSTRINGS "Disable documentation extraction." FALSE)
-
-set (USE_LIBXSLT 0)
-if (NOT DISABLE_DOCSTRINGS)
- if (LIBXSLT_FOUND AND LIBXML2_FOUND)
- add_definitions(-DHAVE_LIBXSLT)
- set (USE_LIBXSLT 1)
- else()
- message(WARNING "libxslt and/or libxml not found, falling back to QtXmlPatterns (QTBUG-66925)")
- endif()
-endif()
-
-if(BUILD_TESTS)
- set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests)
-endif ()
-
-set(QT_USE_QTCORE 1)
-set(QT_USE_QTXML 1)
-add_definitions(-DQT_PLUGIN)
-add_definitions(-DQT_SHARED)
-add_definitions(-DRXX_ALLOCATOR_INIT_0)
+set(CMAKE_AUTOMOC ON)
set(apiextractor_SRC
apiextractor.cpp
@@ -50,45 +28,37 @@ parser/codemodel.cpp
parser/enumvalue.cpp
)
-set(APIEXTRACTOR_EXTRA_INCLUDES ${CLANG_EXTRA_INCLUDES})
-set(APIEXTRACTOR_EXTRA_LIBRARIES ${CLANG_EXTRA_LIBRARIES})
+add_library(apiextractor STATIC ${apiextractor_SRC})
+target_include_directories(apiextractor PRIVATE ${CLANG_EXTRA_INCLUDES}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/parser
+ ${CMAKE_CURRENT_SOURCE_DIR}/parser/rpp)
+target_link_libraries(apiextractor PUBLIC Qt5::Core)
+target_link_libraries(apiextractor PRIVATE ${CLANG_EXTRA_LIBRARIES})
if (NOT DISABLE_DOCSTRINGS)
- set(apiextractor_SRC
- ${apiextractor_SRC}
- docparser.cpp
- doxygenparser.cpp
- qtdocparser.cpp
- )
- set(APIEXTRACTOR_EXTRA_INCLUDES ${APIEXTRACTOR_EXTRA_INCLUDES})
- set(APIEXTRACTOR_EXTRA_LIBRARIES ${APIEXTRACTOR_EXTRA_LIBRARIES})
- if (USE_LIBXSLT)
- list(APPEND APIEXTRACTOR_EXTRA_INCLUDES ${LIBXSLT_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
- list(APPEND APIEXTRACTOR_EXTRA_LIBRARIES ${LIBXSLT_LIBRARIES} ${LIBXML2_LIBRARIES})
+ target_sources(apiextractor PRIVATE docparser.cpp
+ doxygenparser.cpp
+ qtdocparser.cpp)
+ target_link_libraries(apiextractor PUBLIC Qt5::Xml Qt5::XmlPatterns)
+
+ if (LIBXSLT_FOUND AND LIBXML2_FOUND)
+ target_compile_definitions(apiextractor PUBLIC HAVE_LIBXSLT)
+ target_include_directories(apiextractor
+ PRIVATE ${LIBXSLT_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
+ target_link_libraries(apiextractor
+ PRIVATE ${LIBXSLT_LIBRARIES} ${LIBXML2_LIBRARIES})
+ else()
+ message(WARNING
+ "libxslt and/or libxml not found, falling back to QtXmlPatterns (QTBUG-66925)")
endif()
endif()
set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is /lib${LIB_SUFFIX})" FORCE)
-set(CMAKE_AUTOMOC ON)
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/parser
- ${CMAKE_CURRENT_SOURCE_DIR}/parser/rpp
- ${APIEXTRACTOR_EXTRA_INCLUDES}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5Xml_INCLUDE_DIRS}
- )
-
-add_library(apiextractor STATIC ${apiextractor_SRC} ${apiextractor_RCCS_SRC})
-target_link_libraries(apiextractor
- ${Qt5Xml_LIBRARIES}
- ${Qt5XmlPatterns_LIBRARIES}
- ${APIEXTRACTOR_EXTRA_LIBRARIES}
- )
-
if (BUILD_TESTS)
+ set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests)
enable_testing()
add_subdirectory(tests)
endif()
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index e62a2a78a..6e95e79e7 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -111,7 +111,7 @@ static QStringList parseTemplateType(const QString& name) {
return result;
}
-AbstractMetaBuilderPrivate::AbstractMetaBuilderPrivate() : m_currentClass(0),
+AbstractMetaBuilderPrivate::AbstractMetaBuilderPrivate() :
m_logDirectory(QLatin1String(".") + QDir::separator()),
m_skipDeprecated(false)
{
@@ -192,7 +192,7 @@ void AbstractMetaBuilderPrivate::checkFunctionModifications()
QString name = signature.trimmed();
name.truncate(name.indexOf(QLatin1Char('(')));
- AbstractMetaClass *clazz = AbstractMetaClass::findClass(m_metaClasses, centry->qualifiedCppName());
+ AbstractMetaClass *clazz = AbstractMetaClass::findClass(m_metaClasses, centry);
if (!clazz)
continue;
@@ -223,13 +223,14 @@ void AbstractMetaBuilderPrivate::checkFunctionModifications()
}
}
-AbstractMetaClass *AbstractMetaBuilderPrivate::argumentToClass(const ArgumentModelItem &argument)
+AbstractMetaClass *AbstractMetaBuilderPrivate::argumentToClass(const ArgumentModelItem &argument,
+ AbstractMetaClass *currentClass)
{
AbstractMetaClass* returned = 0;
- AbstractMetaType *type = translateType(argument->type());
+ AbstractMetaType *type = translateType(argument->type(), currentClass);
if (type && type->typeEntry() && type->typeEntry()->isComplex()) {
const TypeEntry *entry = type->typeEntry();
- returned = AbstractMetaClass::findClass(m_metaClasses, entry->name());
+ returned = AbstractMetaClass::findClass(m_metaClasses, entry);
}
delete type;
return returned;
@@ -238,11 +239,12 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::argumentToClass(const ArgumentMod
/**
* Checks the argument of a hash function and flags the type if it is a complex type
*/
-void AbstractMetaBuilderPrivate::registerHashFunction(const FunctionModelItem &function_item)
+void AbstractMetaBuilderPrivate::registerHashFunction(const FunctionModelItem &function_item,
+ AbstractMetaClass *currentClass)
{
ArgumentList arguments = function_item->arguments();
if (arguments.size() == 1) {
- if (AbstractMetaClass *cls = argumentToClass(arguments.at(0)))
+ if (AbstractMetaClass *cls = argumentToClass(arguments.at(0), currentClass))
cls->setHasHashFunction(true);
}
}
@@ -251,13 +253,14 @@ void AbstractMetaBuilderPrivate::registerHashFunction(const FunctionModelItem &f
* Check if a class has a debug stream operator that can be used as toString
*/
-void AbstractMetaBuilderPrivate::registerToStringCapability(const FunctionModelItem &function_item)
+void AbstractMetaBuilderPrivate::registerToStringCapability(const FunctionModelItem &function_item,
+ AbstractMetaClass *currentClass)
{
ArgumentList arguments = function_item->arguments();
if (arguments.size() == 2) {
if (arguments.at(0)->type().toString() == QLatin1String("QDebug")) {
const ArgumentModelItem &arg = arguments.at(1);
- if (AbstractMetaClass *cls = argumentToClass(arg)) {
+ if (AbstractMetaClass *cls = argumentToClass(arg, currentClass)) {
if (arg->type().indirections() < 2)
cls->setToStringCapability(true);
}
@@ -265,28 +268,28 @@ void AbstractMetaBuilderPrivate::registerToStringCapability(const FunctionModelI
}
}
-void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelItem &item)
+void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelItem &item,
+ AbstractMetaClass *currentClass)
{
if (item->accessPolicy() != CodeModel::Public)
return;
ArgumentList arguments = item->arguments();
- AbstractMetaClass* baseoperandClass;
bool firstArgumentIsSelf = true;
bool unaryOperator = false;
- baseoperandClass = argumentToClass(arguments.at(0));
+ auto baseoperandClass = argumentToClass(arguments.at(0), currentClass);
if (arguments.size() == 1) {
unaryOperator = true;
} else if (!baseoperandClass
|| !(baseoperandClass->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang)) {
- baseoperandClass = argumentToClass(arguments.at(1));
+ baseoperandClass = argumentToClass(arguments.at(1), currentClass);
firstArgumentIsSelf = false;
} else {
- AbstractMetaType *type = translateType(item->type());
+ AbstractMetaType *type = translateType(item->type(), currentClass);
const TypeEntry *retType = type ? type->typeEntry() : nullptr;
- AbstractMetaClass* otherArgClass = argumentToClass(arguments.at(1));
+ AbstractMetaClass *otherArgClass = argumentToClass(arguments.at(1), currentClass);
if (otherArgClass && retType
&& (retType->isValue() || retType->isObject())
&& retType != baseoperandClass->typeEntry()
@@ -298,9 +301,7 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte
}
if (baseoperandClass) {
- AbstractMetaClass* oldCurrentClass = m_currentClass;
- m_currentClass = baseoperandClass;
- AbstractMetaFunction *metaFunction = traverseFunction(item);
+ AbstractMetaFunction *metaFunction = traverseFunction(item, baseoperandClass);
if (metaFunction) {
// Strip away first argument, since that is the containing object
AbstractMetaArgumentList arguments = metaFunction->arguments();
@@ -333,22 +334,19 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte
} else {
delete metaFunction;
}
-
- m_currentClass = oldCurrentClass;
}
}
-void AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem &item)
+void AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem &item,
+ AbstractMetaClass *currentClass)
{
ArgumentList arguments = item->arguments();
if (arguments.size() == 2 && item->accessPolicy() == CodeModel::Public) {
- AbstractMetaClass* streamClass = argumentToClass(arguments.at(0));
- AbstractMetaClass* streamedClass = argumentToClass(arguments.at(1));
+ AbstractMetaClass *streamClass = argumentToClass(arguments.at(0), currentClass);
+ AbstractMetaClass *streamedClass = argumentToClass(arguments.at(1), currentClass);
if (streamClass && streamedClass && (streamClass->isStream())) {
- AbstractMetaClass *oldCurrentClass = m_currentClass;
- m_currentClass = streamedClass;
- AbstractMetaFunction *streamFunction = traverseFunction(item);
+ AbstractMetaFunction *streamFunction = traverseFunction(item, streamedClass);
if (streamFunction) {
streamFunction->setFunctionType(AbstractMetaFunction::GlobalScopeFunction);
@@ -385,7 +383,6 @@ void AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem
else
funcClass->typeEntry()->addExtraInclude(streamClass->typeEntry()->include());
- m_currentClass = oldCurrentClass;
} else {
delete streamFunction;
}
@@ -394,27 +391,6 @@ void AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem
}
}
-void AbstractMetaBuilderPrivate::fixQObjectForScope(const FileModelItem &dom,
- const TypeDatabase *types,
- const NamespaceModelItem &scope)
-{
- const ClassList &scopeClasses = scope->classes();
- for (const ClassModelItem &item : scopeClasses) {
- QString qualifiedName = item->qualifiedName().join(colonColon());
- TypeEntry* entry = types->findType(qualifiedName);
- if (entry) {
- if (isQObject(dom, qualifiedName) && entry->isComplex())
- static_cast<ComplexTypeEntry *>(entry)->setQObject(true);
- }
- }
-
- const NamespaceList &namespaces = scope->namespaces();
- for (const NamespaceModelItem &n : namespaces) {
- if (scope != n)
- fixQObjectForScope(dom, types, n);
- }
-}
-
void AbstractMetaBuilderPrivate::sortLists()
{
for (AbstractMetaClass *cls : qAsConst(m_metaClasses))
@@ -450,17 +426,14 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
pushScope(dom);
- // fix up QObject's in the type system..
- fixQObjectForScope(dom, types, dom);
-
// Start the generation...
const ClassList &typeValues = dom->classes();
ReportHandler::setProgressReference(typeValues);
for (const ClassModelItem &item : typeValues) {
ReportHandler::progress(QStringLiteral("Generating class model (%1)...")
.arg(typeValues.size()));
- if (AbstractMetaClass *cls = traverseClass(dom, item))
- addAbstractMetaClass(cls);
+ if (AbstractMetaClass *cls = traverseClass(dom, item, nullptr))
+ addAbstractMetaClass(cls, item.data());
}
// We need to know all global enums
@@ -481,9 +454,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
for (const NamespaceModelItem &item : namespaceTypeValues) {
ReportHandler::progress(QStringLiteral("Generating namespace model (%1)...")
.arg(namespaceTypeValues.size()));
- AbstractMetaClass *metaClass = traverseNamespace(dom, item);
- if (metaClass)
- m_metaClasses << metaClass;
+ if (AbstractMetaClass *metaClass = traverseNamespace(dom, item))
+ addAbstractMetaClass(metaClass, item.data());
}
// Go through all typedefs to see if we have defined any
@@ -493,8 +465,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
for (const TypeDefModelItem &typeDef : typeDefs) {
ReportHandler::progress(QStringLiteral("Resolving typedefs (%1)...")
.arg(typeDefs.size()));
- if (AbstractMetaClass *cls = traverseTypeDef(dom, typeDef))
- addAbstractMetaClass(cls);
+ if (AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, nullptr))
+ addAbstractMetaClass(cls, typeDef.data());
}
traverseTypesystemTypedefs();
@@ -515,7 +487,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
if (!funcEntry || !funcEntry->generateCode())
continue;
- AbstractMetaFunction* metaFunc = traverseFunction(func);
+ AbstractMetaFunction* metaFunc = traverseFunction(func, nullptr);
if (!metaFunc)
continue;
@@ -579,7 +551,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
&& !entry->isCustom()
&& !entry->isVariant()
&& (entry->generateCode() & TypeEntry::GenerateTargetLang)
- && !AbstractMetaClass::findClass(m_metaClasses, entry->qualifiedCppName())) {
+ && !AbstractMetaClass::findClass(m_metaClasses, entry)) {
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("type '%1' is specified in typesystem, but not defined. This could potentially lead to compilation errors.")
.arg(entry->qualifiedCppName());
@@ -622,13 +594,13 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
{
const FunctionList &hashFunctions = dom->findFunctions(QLatin1String("qHash"));
for (const FunctionModelItem &item : hashFunctions)
- registerHashFunction(item);
+ registerHashFunction(item, nullptr);
}
{
const FunctionList &streamOps = dom->findFunctions(QLatin1String("operator<<"));
for (const FunctionModelItem &item : streamOps)
- registerToStringCapability(item);
+ registerToStringCapability(item, nullptr);
}
{
@@ -656,14 +628,14 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
binaryOperators.append(dom->findFunctions(QStringLiteral("operator>")));
for (const FunctionModelItem &item : qAsConst(binaryOperators))
- traverseOperatorFunction(item);
+ traverseOperatorFunction(item, nullptr);
}
{
const FunctionList streamOperators = dom->findFunctions(QLatin1String("operator<<"))
+ dom->findFunctions(QLatin1String("operator>>"));
for (const FunctionModelItem &item : streamOperators)
- traverseStreamOperator(item);
+ traverseStreamOperator(item, nullptr);
}
checkFunctionModifications();
@@ -688,21 +660,19 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
sortLists();
- m_currentClass = 0;
-
// Functions added to the module on the type system.
const AddedFunctionList &globalUserFunctions = types->globalUserFunctions();
- for (const AddedFunction &addedFunc : globalUserFunctions) {
+ for (const AddedFunctionPtr &addedFunc : globalUserFunctions) {
AbstractMetaFunction* metaFunc = traverseFunction(addedFunc);
if (Q_UNLIKELY(!metaFunc)) {
qFatal("Unable to traverse added global function \"%s\".",
- qPrintable(addedFunc.name()));
+ qPrintable(addedFunc->name()));
}
metaFunc->setFunctionType(AbstractMetaFunction::NormalFunction);
m_globalFunctions << metaFunc;
}
- std::puts("");
+ m_itemToClass.clear();
}
static bool metaEnumLessThan(const AbstractMetaEnum *e1, const AbstractMetaEnum *e2)
@@ -742,9 +712,11 @@ void AbstractMetaBuilder::setLogDirectory(const QString& logDir)
d->m_logDirectory.append(QDir::separator());
}
-void AbstractMetaBuilderPrivate::addAbstractMetaClass(AbstractMetaClass *cls)
+void AbstractMetaBuilderPrivate::addAbstractMetaClass(AbstractMetaClass *cls,
+ const _CodeModelItem *item)
{
cls->setOriginalAttributes(cls->attributes());
+ m_itemToClass.insert(item, cls);
if (cls->typeEntry()->isContainer()) {
m_templates << cls;
} else if (cls->typeEntry()->isSmartPointer()) {
@@ -763,9 +735,10 @@ void AbstractMetaBuilderPrivate::addAbstractMetaClass(AbstractMetaClass *cls)
AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModelItem &dom,
const NamespaceModelItem &namespaceItem)
{
- QString namespaceName =
- (!m_namespacePrefix.isEmpty() ? m_namespacePrefix + colonColon() : QString())
- + namespaceItem->name();
+ QString namespaceName = currentScope()->qualifiedName().join(colonColon());
+ if (!namespaceName.isEmpty())
+ namespaceName.append(colonColon());
+ namespaceName.append(namespaceItem->name());
NamespaceTypeEntry *type = TypeDatabase::instance()->findNamespaceType(namespaceName);
if (TypeDatabase::instance()->isClassRejected(namespaceName)) {
@@ -784,8 +757,6 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
*metaClass += AbstractMetaAttributes::Public;
- m_currentClass = metaClass;
-
if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
qCDebug(lcShiboken)
<< QStringLiteral("namespace '%1.%2'").arg(metaClass->package(), namespaceItem->name());
@@ -794,15 +765,14 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
traverseEnums(namespaceItem, metaClass, namespaceItem->enumsDeclarations());
pushScope(namespaceItem);
- m_namespacePrefix = currentScope()->qualifiedName().join(colonColon());
const ClassList &classes = namespaceItem->classes();
for (const ClassModelItem &cls : classes) {
- AbstractMetaClass* mjc = traverseClass(dom, cls);
+ AbstractMetaClass* mjc = traverseClass(dom, cls, metaClass);
if (mjc) {
metaClass->addInnerClass(mjc);
mjc->setEnclosingClass(metaClass);
- addAbstractMetaClass(mjc);
+ addAbstractMetaClass(mjc, cls.data());
}
}
@@ -810,11 +780,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
// specific typedefs to be used as classes.
const TypeDefList typeDefs = namespaceItem->typeDefs();
for (const TypeDefModelItem &typeDef : typeDefs) {
- AbstractMetaClass *cls = traverseTypeDef(dom, typeDef);
+ AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, metaClass);
if (cls) {
metaClass->addInnerClass(cls);
cls->setEnclosingClass(metaClass);
- addAbstractMetaClass(cls);
+ addAbstractMetaClass(cls, typeDef.data());
}
}
@@ -824,14 +794,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
if (mjc) {
metaClass->addInnerClass(mjc);
mjc->setEnclosingClass(metaClass);
- addAbstractMetaClass(mjc);
+ addAbstractMetaClass(mjc, ni.data());
}
}
- m_currentClass = 0;
-
popScope();
- m_namespacePrefix = currentScope()->qualifiedName().join(colonColon());
if (!type->include().isValid())
setInclude(type, namespaceItem->fileName());
@@ -872,8 +839,8 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem &
QString enumName = enumItem->name();
QString className;
- if (m_currentClass)
- className = m_currentClass->typeEntry()->qualifiedCppName();
+ if (enclosing)
+ className = enclosing->typeEntry()->qualifiedCppName();
QString rejectReason;
if (TypeDatabase::instance()->isEnumRejected(className, enumName, &rejectReason)) {
@@ -883,8 +850,8 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem &
return 0;
}
- const bool rejectionWarning = !m_currentClass
- || (m_currentClass->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang);
+ const bool rejectionWarning = !enclosing
+ || (enclosing->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang);
if (!typeEntry) {
if (rejectionWarning)
@@ -983,15 +950,16 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem &
}
AbstractMetaClass* AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelItem &dom,
- const TypeDefModelItem &typeDef)
+ const TypeDefModelItem &typeDef,
+ AbstractMetaClass *currentClass)
{
TypeDatabase* types = TypeDatabase::instance();
QString className = stripTemplateArgs(typeDef->name());
QString fullClassName = className;
// we have an inner class
- if (m_currentClass) {
- fullClassName = stripTemplateArgs(m_currentClass->typeEntry()->qualifiedCppName())
+ if (currentClass) {
+ fullClassName = stripTemplateArgs(currentClass->typeEntry()->qualifiedCppName())
+ colonColon() + fullClassName;
}
@@ -1011,9 +979,6 @@ AbstractMetaClass* AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelIt
if (!type)
return 0;
- if (type->isObject())
- static_cast<ObjectTypeEntry *>(type)->setQObject(isQObject(dom, stripTemplateArgs(typeDef->type().qualifiedName().join(colonColon()))));
-
AbstractMetaClass *metaClass = new AbstractMetaClass;
metaClass->setTypeDef(true);
metaClass->setTypeEntry(type);
@@ -1041,19 +1006,20 @@ void AbstractMetaBuilderPrivate::traverseTypesystemTypedefs()
metaClass->setBaseClassNames(QStringList(te->sourceType()));
*metaClass += AbstractMetaAttributes::Public;
fillAddedFunctions(metaClass);
- addAbstractMetaClass(metaClass);
+ addAbstractMetaClass(metaClass, nullptr);
}
}
AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem &dom,
- const ClassModelItem &classItem)
+ const ClassModelItem &classItem,
+ AbstractMetaClass *currentClass)
{
QString className = stripTemplateArgs(classItem->name());
QString fullClassName = className;
// we have inner an class
- if (m_currentClass) {
- fullClassName = stripTemplateArgs(m_currentClass->typeEntry()->qualifiedCppName())
+ if (currentClass) {
+ fullClassName = stripTemplateArgs(currentClass->typeEntry()->qualifiedCppName())
+ colonColon() + fullClassName;
}
@@ -1076,9 +1042,6 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
return 0;
}
- if (type->isObject())
- ((ObjectTypeEntry*)type)->setQObject(isQObject(dom, fullClassName));
-
AbstractMetaClass *metaClass = new AbstractMetaClass;
metaClass->setTypeEntry(type);
@@ -1097,9 +1060,6 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
if (type->stream())
metaClass->setStream(true);
- AbstractMetaClass* oldCurrentClass = m_currentClass;
- m_currentClass = metaClass;
-
if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
const QString message = type->isContainer()
? QStringLiteral("container: '%1'").arg(fullClassName)
@@ -1126,11 +1086,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
{
const ClassList &innerClasses = classItem->classes();
for (const ClassModelItem &ci : innerClasses) {
- AbstractMetaClass *cl = traverseClass(dom, ci);
+ AbstractMetaClass *cl = traverseClass(dom, ci, metaClass);
if (cl) {
cl->setEnclosingClass(metaClass);
metaClass->addInnerClass(cl);
- m_metaClasses << cl;
+ addAbstractMetaClass(cl, ci.data());
}
}
@@ -1140,16 +1100,13 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
// specific typedefs to be used as classes.
const TypeDefList typeDefs = classItem->typeDefs();
for (const TypeDefModelItem &typeDef : typeDefs) {
- AbstractMetaClass *cls = traverseTypeDef(dom, typeDef);
+ AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, metaClass);
if (cls) {
cls->setEnclosingClass(metaClass);
- addAbstractMetaClass(cls);
+ addAbstractMetaClass(cls, typeDef.data());
}
}
-
- m_currentClass = oldCurrentClass;
-
// Set the default include file name
if (!type->include().isValid())
setInclude(type, classItem->fileName());
@@ -1170,48 +1127,22 @@ void AbstractMetaBuilderPrivate::traverseScopeMembers(ScopeModelItem item,
traverseClassMembers(ci);
}
-AbstractMetaClass* AbstractMetaBuilderPrivate::currentTraversedClass(ScopeModelItem item)
-{
- QString className = stripTemplateArgs(item->name());
- QString fullClassName = className;
-
- // This is an inner class
- if (m_currentClass)
- fullClassName = stripTemplateArgs(m_currentClass->typeEntry()->qualifiedCppName()) + colonColon() + fullClassName;
-
- AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, fullClassName);
- if (!metaClass)
- metaClass = AbstractMetaClass::findClass(m_templates, fullClassName);
-
- if (!metaClass)
- metaClass = AbstractMetaClass::findClass(m_smartPointers, fullClassName);
- return metaClass;
-}
-
void AbstractMetaBuilderPrivate::traverseClassMembers(ClassModelItem item)
{
- AbstractMetaClass* metaClass = currentTraversedClass(item);
+ AbstractMetaClass* metaClass = m_itemToClass.value(item.data());
if (!metaClass)
return;
- AbstractMetaClass* oldCurrentClass = m_currentClass;
- m_currentClass = metaClass;
-
// Class members
traverseScopeMembers(item, metaClass);
-
- m_currentClass = oldCurrentClass;
}
void AbstractMetaBuilderPrivate::traverseNamespaceMembers(NamespaceModelItem item)
{
- AbstractMetaClass* metaClass = currentTraversedClass(item);
+ AbstractMetaClass* metaClass = m_itemToClass.value(item.data());
if (!metaClass)
return;
- AbstractMetaClass* oldCurrentClass = m_currentClass;
- m_currentClass = metaClass;
-
// Namespace members
traverseScopeMembers(item, metaClass);
@@ -1219,7 +1150,6 @@ void AbstractMetaBuilderPrivate::traverseNamespaceMembers(NamespaceModelItem ite
for (const NamespaceModelItem &ni : item->namespaces())
traverseNamespaceMembers(ni);
- m_currentClass = oldCurrentClass;
}
static inline QString fieldSignatureWithType(const VariableModelItem &field)
@@ -1234,10 +1164,10 @@ static inline QString qualifiedFieldSignatureWithType(const QString &className,
}
AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(const VariableModelItem &field,
- const AbstractMetaClass *cls)
+ AbstractMetaClass *cls)
{
QString fieldName = field->name();
- QString className = m_currentClass->typeEntry()->qualifiedCppName();
+ QString className = cls->typeEntry()->qualifiedCppName();
// Ignore friend decl.
if (field->isFriend())
@@ -1259,14 +1189,14 @@ AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(const VariableModel
metaField->setEnclosingClass(cls);
TypeInfo fieldType = field->type();
- AbstractMetaType *metaType = translateType(fieldType);
+ AbstractMetaType *metaType = translateType(fieldType, cls);
if (!metaType) {
const QString type = TypeInfo::resolveType(fieldType, currentScope()).qualifiedName().join(colonColon());
- if (m_currentClass->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang) {
+ if (cls->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang) {
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("skipping field '%1::%2' with unmatched type '%3'")
- .arg(m_currentClass->name(), fieldName, type);
+ .arg(cls->name(), fieldName, type);
}
delete metaField;
return 0;
@@ -1369,14 +1299,15 @@ static bool _compareAbstractMetaFunctions(const AbstractMetaFunction* func, cons
}
AbstractMetaFunctionList AbstractMetaBuilderPrivate::classFunctionList(const ScopeModelItem &scopeItem,
- AbstractMetaClass::Attributes *constructorAttributes)
+ AbstractMetaClass::Attributes *constructorAttributes,
+ AbstractMetaClass *currentClass)
{
*constructorAttributes = 0;
AbstractMetaFunctionList result;
const FunctionList &scopeFunctionList = scopeItem->functions();
result.reserve(scopeFunctionList.size());
for (const FunctionModelItem &function : scopeFunctionList) {
- if (AbstractMetaFunction *metaFunction = traverseFunction(function)) {
+ if (AbstractMetaFunction *metaFunction = traverseFunction(function, currentClass)) {
result.append(metaFunction);
} else if (function->functionType() == CodeModel::Constructor) {
auto arguments = function->arguments();
@@ -1416,7 +1347,7 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
{
AbstractMetaAttributes::Attributes constructorAttributes;
const AbstractMetaFunctionList functions =
- classFunctionList(scopeItem, &constructorAttributes);
+ classFunctionList(scopeItem, &constructorAttributes, metaClass);
metaClass->setAttributes(metaClass->attributes() | constructorAttributes);
for (AbstractMetaFunction *metaFunction : functions){
@@ -1477,12 +1408,6 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
.arg(metaFunction->name(), metaClass->name());
}
- if (metaFunction->isSignal() && !metaClass->isQObject()) {
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("signal '%1' in non-QObject class '%2'")
- .arg(metaFunction->name(), metaClass->name());
- }
-
if (metaFunction->isConversionOperator())
fixReturnTypeOfConversionOperator(metaFunction);
@@ -1506,10 +1431,10 @@ void AbstractMetaBuilderPrivate::fillAddedFunctions(AbstractMetaClass *metaClass
{
// Add the functions added by the typesystem
const AddedFunctionList &addedFunctions = metaClass->typeEntry()->addedFunctions();
- for (const AddedFunction &addedFunc : addedFunctions) {
+ for (const AddedFunctionPtr &addedFunc : addedFunctions) {
if (!traverseFunction(addedFunc, metaClass)) {
qFatal("Unable to traverse function \"%s\" added to \"%s\".",
- qPrintable(addedFunc.name()), qPrintable(metaClass->name()));
+ qPrintable(addedFunc->name()), qPrintable(metaClass->name()));
}
}
}
@@ -1663,29 +1588,19 @@ void AbstractMetaBuilderPrivate::traverseEnums(const ScopeModelItem &scopeItem,
}
}
-AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunction& addedFunc)
+AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunctionPtr &addedFunc)
{
return traverseFunction(addedFunc, 0);
}
-AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunction& addedFunc,
+AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunctionPtr &addedFunc,
AbstractMetaClass *metaClass)
{
- AbstractMetaFunction *metaFunction = new AbstractMetaFunction;
- metaFunction->setConstant(addedFunc.isConstant());
- metaFunction->setName(addedFunc.name());
- metaFunction->setOriginalName(addedFunc.name());
- AbstractMetaClass::Attributes visibility =
- addedFunc.access() == AddedFunction::Public
- ? AbstractMetaAttributes::Public : AbstractMetaAttributes::Protected;
- metaFunction->setVisibility(visibility);
- metaFunction->setUserAdded(true);
- AbstractMetaAttributes::Attribute isStatic = addedFunc.isStatic() ? AbstractMetaFunction::Static : AbstractMetaFunction::None;
- metaFunction->setAttributes(metaFunction->attributes() | AbstractMetaAttributes::FinalInTargetLang | isStatic);
- metaFunction->setType(translateType(addedFunc.returnType()));
-
-
- QVector<AddedFunction::TypeInfo> args = addedFunc.arguments();
+ AbstractMetaFunction *metaFunction = new AbstractMetaFunction(addedFunc);
+ metaFunction->setType(translateType(addedFunc->returnType()));
+
+
+ QVector<AddedFunction::TypeInfo> args = addedFunc->arguments();
AbstractMetaArgumentList metaArguments;
for (int i = 0; i < args.count(); ++i) {
@@ -1695,7 +1610,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
if (Q_UNLIKELY(!type)) {
qCWarning(lcShiboken,
"Unable to translate type \"%s\" of argument %d of added function \"%s\".",
- qPrintable(typeInfo.name), i + 1, qPrintable(addedFunc.name()));
+ qPrintable(typeInfo.name), i + 1, qPrintable(addedFunc->name()));
delete metaFunction;
return nullptr;
}
@@ -1734,11 +1649,11 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
//use relace-default-expression for set default value
QString replacedExpression;
- if (m_currentClass)
- replacedExpression = metaFunction->replacedDefaultExpression(m_currentClass, i + 1);
+ if (metaClass)
+ replacedExpression = metaFunction->replacedDefaultExpression(metaClass, i + 1);
if (!replacedExpression.isEmpty()) {
- if (!metaFunction->removedDefaultExpression(m_currentClass, i + 1)) {
+ if (!metaFunction->removedDefaultExpression(metaClass, i + 1)) {
metaArg->setDefaultValueExpression(replacedExpression);
metaArg->setOriginalDefaultValueExpression(replacedExpression);
}
@@ -1747,7 +1662,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
metaFunction->setOriginalAttributes(metaFunction->attributes());
if (!metaArguments.isEmpty())
- fixArgumentNames(metaFunction, metaFunction->modifications(m_currentClass));
+ fixArgumentNames(metaFunction, metaFunction->modifications(metaClass));
if (metaClass) {
const AbstractMetaArgumentList fargs = metaFunction->arguments();
@@ -1864,20 +1779,21 @@ static bool applyArrayArgumentModifications(const FunctionModificationList &func
return true;
}
-AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const FunctionModelItem &functionItem)
+AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const FunctionModelItem &functionItem,
+ AbstractMetaClass *currentClass)
{
if (functionItem->isDeleted() || !functionItem->templateParameters().isEmpty())
return nullptr;
QString functionName = functionItem->name();
QString className;
- if (m_currentClass) {
+ if (currentClass) {
// Clang: Skip qt_metacast(), qt_metacall(), expanded from Q_OBJECT
// and overridden metaObject(), QGADGET helpers
if (functionName == QLatin1String("qt_check_for_QGADGET_macro")
|| functionName.startsWith(QLatin1String("qt_meta"))) {
return nullptr;
}
- className = m_currentClass->typeEntry()->qualifiedCppName();
+ className = currentClass->typeEntry()->qualifiedCppName();
if (functionName == QLatin1String("metaObject") && className != QLatin1String("QObject"))
return nullptr;
}
@@ -1960,7 +1876,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
break;
case AbstractMetaFunction::ConstructorFunction:
metaFunction->setExplicit(functionItem->isExplicit());
- metaFunction->setName(m_currentClass->name());
+ metaFunction->setName(currentClass->name());
break;
default: {
TypeInfo returnType = functionItem->type();
@@ -1973,7 +1889,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
AbstractMetaType *type = nullptr;
if (!returnType.isVoid()) {
- type = translateType(returnType, true, &errorMessage);
+ type = translateType(returnType, currentClass, true, &errorMessage);
if (!type) {
const QString reason = msgUnmatchedReturnType(functionItem, errorMessage);
qCWarning(lcShiboken, "%s",
@@ -2009,12 +1925,12 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
return nullptr;
}
- AbstractMetaType *metaType = translateType(arg->type(), true, &errorMessage);
+ AbstractMetaType *metaType = translateType(arg->type(), currentClass, true, &errorMessage);
if (!metaType) {
// If an invalid argument has a default value, simply remove it
if (arg->defaultValue()) {
- if (!m_currentClass
- || (m_currentClass->typeEntry()->codeGeneration()
+ if (!currentClass
+ || (currentClass->typeEntry()->codeGeneration()
& TypeEntry::GenerateTargetLang)) {
qCWarning(lcShiboken).noquote().nospace()
<< "Stripping argument #" << (i + 1) << " of "
@@ -2046,7 +1962,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
metaFunction->setArguments(metaArguments);
- const FunctionModificationList functionMods = metaFunction->modifications(m_currentClass);
+ const FunctionModificationList functionMods = metaFunction->modifications(currentClass);
for (const FunctionModification &mod : functionMods) {
if (mod.exceptionHandling() != TypeSystem::ExceptionHandling::Unspecified)
@@ -2062,8 +1978,8 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
//use relace-default-expression for set default value
QString replacedExpression;
- if (m_currentClass) {
- replacedExpression = metaFunction->replacedDefaultExpression(m_currentClass, i + 1);
+ if (currentClass) {
+ replacedExpression = metaFunction->replacedDefaultExpression(currentClass, i + 1);
} else {
if (!functionMods.isEmpty()) {
QVector<ArgumentModification> argMods = functionMods.constFirst().argument_mods;
@@ -2075,10 +1991,10 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
bool hasDefaultValue = false;
if (arg->defaultValue() || !replacedExpression.isEmpty()) {
QString expr = arg->defaultValueExpression();
- expr = fixDefaultValue(arg, metaArg->type(), metaFunction, m_currentClass, i);
+ expr = fixDefaultValue(arg, metaArg->type(), metaFunction, currentClass, i);
metaArg->setOriginalDefaultValueExpression(expr);
- if (metaFunction->removedDefaultExpression(m_currentClass, i + 1)) {
+ if (metaFunction->removedDefaultExpression(currentClass, i + 1)) {
expr.clear();
} else if (!replacedExpression.isEmpty()) {
expr = replacedExpression;
@@ -2092,7 +2008,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
&& !metaArg->hasName()
&& !metaFunction->isOperatorOverload()
&& !metaFunction->isSignal()
- && metaFunction->argumentName(i+1, false, m_currentClass).isEmpty()) {
+ && metaFunction->argumentName(i + 1, false, currentClass).isEmpty()) {
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("Argument %1 on function '%2::%3' has default expression but does not have name.")
.arg(i+1).arg(className, metaFunction->minimalSignature());
@@ -2110,9 +2026,9 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
}
// Determine class special functions
- if (m_currentClass && metaFunction->arguments().size() == 1) {
+ if (currentClass && metaFunction->arguments().size() == 1) {
const AbstractMetaType *argType = metaFunction->arguments().constFirst()->type();
- if (argType->typeEntry() == m_currentClass->typeEntry() && argType->indirections() == 0) {
+ if (argType->typeEntry() == currentClass->typeEntry() && argType->indirections() == 0) {
if (metaFunction->name() == QLatin1String("operator=")) {
switch (argType->referenceType()) {
case NoReference:
@@ -2212,10 +2128,11 @@ static const TypeEntry* findTypeEntryUsingContext(const AbstractMetaClass* metaC
}
AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei,
+ AbstractMetaClass *currentClass,
bool resolveType,
QString *errorMessage)
{
- return translateTypeStatic(_typei, m_currentClass, this, resolveType, errorMessage);
+ return translateTypeStatic(_typei, currentClass, this, resolveType, errorMessage);
}
AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei,
@@ -2575,38 +2492,6 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite
return expr;
}
-bool AbstractMetaBuilderPrivate::isQObject(const FileModelItem &dom, const QString &qualifiedName)
-{
- if (qualifiedName == QLatin1String("QObject"))
- return true;
-
- ClassModelItem classItem = dom->findClass(qualifiedName);
-
- if (!classItem) {
- QStringList names = qualifiedName.split(colonColon());
- NamespaceModelItem ns = dom;
- for (int i = 0; i < names.size() - 1 && ns; ++i)
- ns = ns->findNamespace(names.at(i));
- if (ns && names.size() >= 2)
- classItem = ns->findClass(names.at(names.size() - 1));
- }
-
- if (!classItem)
- return false;
-
- if (classItem->extendsClass(QLatin1String("QObject")))
- return true;
-
- const QVector<_ClassModelItem::BaseClass> &baseClasses = classItem->baseClasses();
- for (const _ClassModelItem::BaseClass &baseClass : baseClasses) {
- if (isQObject(dom, baseClass.name))
- return true;
- }
-
- return false;
-}
-
-
bool AbstractMetaBuilderPrivate::isEnum(const FileModelItem &dom, const QStringList& qualified_name)
{
CodeModelItem item = dom->model()->findItem(qualified_name, dom);
@@ -2910,21 +2795,19 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
void AbstractMetaBuilderPrivate::parseQ_Property(AbstractMetaClass *metaClass,
const QStringList &declarations)
{
- for (int i = 0; i < declarations.size(); ++i) {
- const QString &p = declarations.at(i);
-
- QStringList l = p.split(QLatin1Char(' '));
+ const QStringList scopes = currentScope()->qualifiedName();
+ for (int i = 0; i < declarations.size(); ++i) {
+ const auto propertyTokens = declarations.at(i).splitRef(QLatin1Char(' '));
- QStringList qualifiedScopeName = currentScope()->qualifiedName();
- AbstractMetaType* type = 0;
- QString scope;
- for (int j = qualifiedScopeName.size(); j >= 0; --j) {
- scope = j > 0 ? QStringList(qualifiedScopeName.mid(0, j)).join(colonColon()) + colonColon() : QString();
+ AbstractMetaType *type = nullptr;
+ for (int j = scopes.size(); j >= 0; --j) {
+ QStringList qualifiedName = scopes.mid(0, j);
+ qualifiedName.append(propertyTokens.at(0).toString());
TypeInfo info;
- info.setQualifiedName((scope + l.at(0)).split(colonColon()));
+ info.setQualifiedName(qualifiedName);
- type = translateType(info);
+ type = translateType(info, metaClass);
if (type)
break;
}
@@ -2932,23 +2815,23 @@ void AbstractMetaBuilderPrivate::parseQ_Property(AbstractMetaClass *metaClass,
if (!type) {
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("Unable to decide type of property: '%1' in class '%2'")
- .arg(l.at(0), metaClass->name());
+ .arg(propertyTokens.at(0).toString(), metaClass->name());
continue;
}
QPropertySpec* spec = new QPropertySpec(type->typeEntry());
- spec->setName(l.at(1));
+ spec->setName(propertyTokens.at(1).toString());
spec->setIndex(i);
- for (int pos = 2; pos + 1 < l.size(); pos += 2) {
- if (l.at(pos) == QLatin1String("READ"))
- spec->setRead(l.at(pos + 1));
- else if (l.at(pos) == QLatin1String("WRITE"))
- spec->setWrite(l.at(pos + 1));
- else if (l.at(pos) == QLatin1String("DESIGNABLE"))
- spec->setDesignable(l.at(pos + 1));
- else if (l.at(pos) == QLatin1String("RESET"))
- spec->setReset(l.at(pos + 1));
+ for (int pos = 2; pos + 1 < propertyTokens.size(); pos += 2) {
+ if (propertyTokens.at(pos) == QLatin1String("READ"))
+ spec->setRead(propertyTokens.at(pos + 1).toString());
+ else if (propertyTokens.at(pos) == QLatin1String("WRITE"))
+ spec->setWrite(propertyTokens.at(pos + 1).toString());
+ else if (propertyTokens.at(pos) == QLatin1String("DESIGNABLE"))
+ spec->setDesignable(propertyTokens.at(pos + 1).toString());
+ else if (propertyTokens.at(pos) == QLatin1String("RESET"))
+ spec->setReset(propertyTokens.at(pos + 1).toString());
}
metaClass->addPropertySpec(spec);
@@ -3214,16 +3097,60 @@ void AbstractMetaBuilder::setGlobalHeader(const QString& globalHeader)
d->m_globalHeader = QFileInfo(globalHeader);
}
+void AbstractMetaBuilder::setHeaderPaths(const HeaderPaths &hp)
+{
+ for (const auto & h: hp) {
+ if (h.type != HeaderType::Framework && h.type != HeaderType::FrameworkSystem)
+ d->m_headerPaths.append(QFile::decodeName(h.path));
+ }
+}
+
void AbstractMetaBuilder::setSkipDeprecated(bool value)
{
d->m_skipDeprecated = value;
}
+// PYSIDE-975: When receiving an absolute path name from the code model, try
+// to resolve it against the include paths set on shiboken in order to recreate
+// relative paths like #include <foo/bar.h>.
+
+static inline bool isFileSystemSlash(QChar c)
+{
+ return c == QLatin1Char('/') || c == QLatin1Char('\\');
+}
+
+static bool matchHeader(const QString &headerPath, const QString &fileName)
+{
+#if defined(Q_OS_WIN) || defined(Q_OS_DARWIN)
+ static const Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive;
+#else
+ static const Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive;
+#endif
+ const int pathSize = headerPath.size();
+ return fileName.size() > pathSize
+ && isFileSystemSlash(fileName.at(pathSize))
+ && fileName.startsWith(headerPath, caseSensitivity);
+}
+
void AbstractMetaBuilderPrivate::setInclude(TypeEntry *te, const QString &fileName) const
{
- QFileInfo info(fileName);
- if (m_globalHeader.fileName() != info.fileName())
- te->setInclude(Include(Include::IncludePath, info.fileName()));
+ auto it = m_resolveIncludeHash.find(fileName);
+ if (it == m_resolveIncludeHash.end()) {
+ QFileInfo info(fileName);
+ if (m_globalHeader.fileName() == info.fileName())
+ return;
+
+ int bestMatchLength = 0;
+ for (const auto &headerPath : m_headerPaths) {
+ if (headerPath.size() > bestMatchLength && matchHeader(headerPath, fileName))
+ bestMatchLength = headerPath.size();
+ }
+ const QString include = bestMatchLength > 0
+ ? fileName.right(fileName.size() - bestMatchLength - 1)
+ : info.fileName();
+ it = m_resolveIncludeHash.insert(fileName, {Include::IncludePath, include});
+ }
+ te->setInclude(it.value());
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
index ed89060ac..1789ca2aa 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
@@ -30,6 +30,7 @@
#define ABSTRACTMETABUILDER_H
#include "abstractmetalang_typedefs.h"
+#include "header_paths.h"
#include "dependency.h"
#include "clangparser/compilersupport.h"
@@ -85,6 +86,7 @@ public:
* filled.
*/
void setGlobalHeader(const QString& globalHeader);
+ void setHeaderPaths(const HeaderPaths &h);
void setSkipDeprecated(bool value);
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
index d8203a586..3c0039f0e 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
@@ -60,15 +60,17 @@ public:
ScopeModelItem currentScope() const { return m_scopes.constLast(); }
- AbstractMetaClass *argumentToClass(const ArgumentModelItem &);
+ AbstractMetaClass *argumentToClass(const ArgumentModelItem &,
+ AbstractMetaClass *currentClass);
- void addAbstractMetaClass(AbstractMetaClass *cls);
+ void addAbstractMetaClass(AbstractMetaClass *cls, const _CodeModelItem *item);
AbstractMetaClass *traverseTypeDef(const FileModelItem &dom,
- const TypeDefModelItem &typeDef);
+ const TypeDefModelItem &typeDef,
+ AbstractMetaClass *currentClass);
void traverseTypesystemTypedefs();
AbstractMetaClass *traverseClass(const FileModelItem &dom,
- const ClassModelItem &item);
- AbstractMetaClass *currentTraversedClass(ScopeModelItem item);
+ const ClassModelItem &item,
+ AbstractMetaClass *currentClass);
void traverseScopeMembers(ScopeModelItem item, AbstractMetaClass *metaClass);
void traverseClassMembers(ClassModelItem scopeItem);
void traverseNamespaceMembers(NamespaceModelItem scopeItem);
@@ -80,24 +82,30 @@ public:
void traverseEnums(const ScopeModelItem &item, AbstractMetaClass *parent,
const QStringList &enumsDeclarations);
AbstractMetaFunctionList classFunctionList(const ScopeModelItem &scopeItem,
- AbstractMetaClass::Attributes *constructorAttributes);
+ AbstractMetaClass::Attributes *constructorAttributes,
+ AbstractMetaClass *currentClass);
AbstractMetaFunctionList templateClassFunctionList(const ScopeModelItem &scopeItem,
AbstractMetaClass *metaClass,
bool *constructorRejected);
void traverseFunctions(ScopeModelItem item, AbstractMetaClass *parent);
void applyFunctionModifications(AbstractMetaFunction* func);
void traverseFields(const ScopeModelItem &item, AbstractMetaClass *parent);
- void traverseStreamOperator(const FunctionModelItem &functionItem);
- void traverseOperatorFunction(const FunctionModelItem &item);
- AbstractMetaFunction* traverseFunction(const AddedFunction &addedFunc);
- AbstractMetaFunction* traverseFunction(const AddedFunction &addedFunc,
+ void traverseStreamOperator(const FunctionModelItem &functionItem,
+ AbstractMetaClass *currentClass);
+ void traverseOperatorFunction(const FunctionModelItem &item,
+ AbstractMetaClass *currentClass);
+ AbstractMetaFunction* traverseFunction(const AddedFunctionPtr &addedFunc);
+ AbstractMetaFunction* traverseFunction(const AddedFunctionPtr &addedFunc,
AbstractMetaClass *metaClass);
- AbstractMetaFunction *traverseFunction(const FunctionModelItem &function);
+ AbstractMetaFunction *traverseFunction(const FunctionModelItem &function,
+ AbstractMetaClass *currentClass);
AbstractMetaField *traverseField(const VariableModelItem &field,
- const AbstractMetaClass *cls);
+ AbstractMetaClass *cls);
void checkFunctionModifications();
- void registerHashFunction(const FunctionModelItem &functionItem);
- void registerToStringCapability(const FunctionModelItem &functionItem);
+ void registerHashFunction(const FunctionModelItem &functionItem,
+ AbstractMetaClass *currentClass);
+ void registerToStringCapability(const FunctionModelItem &functionItem,
+ AbstractMetaClass *currentClass);
/**
* A conversion operator function should not have its owner class as
@@ -124,6 +132,7 @@ public:
int argumentIndex);
AbstractMetaType *translateType(const AddedFunction::TypeInfo &typeInfo);
AbstractMetaType *translateType(const TypeInfo &type,
+ AbstractMetaClass *currentClass,
bool resolveType = true,
QString *errorMessage = nullptr);
static AbstractMetaType *translateTypeStatic(const TypeInfo &type,
@@ -149,9 +158,6 @@ public:
bool isQObject(const FileModelItem &dom, const QString &qualifiedName);
bool isEnum(const FileModelItem &dom, const QStringList &qualifiedName);
- void fixQObjectForScope(const FileModelItem &dom, const TypeDatabase *types,
- const NamespaceModelItem &item);
-
void sortLists();
AbstractMetaArgumentList reverseList(const AbstractMetaArgumentList &list);
void setInclude(TypeEntry *te, const QString &fileName) const;
@@ -163,6 +169,7 @@ public:
AbstractMetaClassList m_metaClasses;
AbstractMetaClassList m_templates;
AbstractMetaClassList m_smartPointers;
+ QHash<const _CodeModelItem *, AbstractMetaClass *> m_itemToClass;
AbstractMetaFunctionList m_globalFunctions;
AbstractMetaEnumList m_globalEnums;
@@ -175,14 +182,14 @@ public:
QHash<const TypeEntry *, AbstractMetaEnum *> m_enums;
- AbstractMetaClass *m_currentClass;
QList<ScopeModelItem> m_scopes;
- QString m_namespacePrefix;
QSet<AbstractMetaClass *> m_setupInheritanceDone;
QString m_logDirectory;
QFileInfo m_globalHeader;
+ QStringList m_headerPaths;
+ mutable QHash<QString, Include> m_resolveIncludeHash;
bool m_skipDeprecated;
};
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
index 95f8048cd..512efef58 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
@@ -288,8 +288,7 @@ AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() con
if (m_typeEntry->isObject()) {
if (indirections() == 0 && m_referenceType == NoReference)
return ValuePattern;
- return static_cast<const ComplexTypeEntry *>(m_typeEntry)->isQObject()
- ? QObjectPattern : ObjectPattern;
+ return ObjectPattern;
}
if (m_typeEntry->isContainer() && indirections() == 0)
@@ -322,8 +321,7 @@ void AbstractMetaType::decideUsagePattern()
// const-references to pointers can be passed as pointers
setReferenceType(NoReference);
setConstant(false);
- pattern = static_cast<const ComplexTypeEntry *>(m_typeEntry)->isQObject()
- ? QObjectPattern : ObjectPattern;
+ pattern = ObjectPattern;
}
setTypeUsagePattern(pattern);
}
@@ -454,10 +452,32 @@ QDebug operator<<(QDebug d, const AbstractMetaArgument *aa)
* AbstractMetaFunction
*/
+AbstractMetaFunction::AbstractMetaFunction(const AddedFunctionPtr &addedFunc) :
+ AbstractMetaFunction()
+{
+ m_addedFunction = addedFunc;
+ setConstant(addedFunc->isConstant());
+ setName(addedFunc->name());
+ setOriginalName(addedFunc->name());
+ auto atts = attributes() | AbstractMetaAttributes::FinalInTargetLang;
+ switch (addedFunc->access()) {
+ case AddedFunction::InvalidAccess:
+ break;
+ case AddedFunction::Protected:
+ atts |= AbstractMetaAttributes::Protected;
+ break;
+ case AddedFunction::Public:
+ atts |= AbstractMetaAttributes::Public;
+ break;
+ }
+ if (addedFunc->isStatic())
+ atts |= AbstractMetaFunction::Static;
+ setAttributes(atts);
+}
+
AbstractMetaFunction::AbstractMetaFunction()
: m_constant(false),
m_reverse(false),
- m_userAdded(false),
m_explicit(false),
m_pointerOperator(false),
m_isCallOperator(false)
@@ -581,6 +601,7 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const
cpy->setExceptionSpecification(m_exceptionSpecification);
cpy->setAllowThreadModification(m_allowThreadModification);
cpy->setExceptionHandlingModification(m_exceptionHandlingModification);
+ cpy->m_addedFunction = m_addedFunction;
for (AbstractMetaArgument *arg : m_arguments)
cpy->addArgument(arg->copy());
@@ -944,6 +965,8 @@ QString AbstractMetaFunction::debugSignature() const
FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaClass* implementor) const
{
+ if (!m_addedFunction.isNull())
+ return m_addedFunction->modifications;
if (!implementor)
implementor = ownerClass();
@@ -1281,7 +1304,7 @@ void AbstractMetaFunction::formatDebugVerbose(QDebug &d) const
d << " [const]";
if (m_reverse)
d << " [reverse]";
- if (m_userAdded)
+ if (isUserAdded())
d << " [userAdded]";
if (m_explicit)
d << " [explicit]";
@@ -1636,9 +1659,14 @@ bool AbstractMetaClass::isNamespace() const
return m_typeEntry->isNamespace();
}
+static bool qObjectPredicate(const AbstractMetaClass *c)
+{
+ return c->qualifiedCppName() == QLatin1String("QObject");
+}
+
bool AbstractMetaClass::isQObject() const
{
- return m_typeEntry->isQObject();
+ return qObjectPredicate(this) || recurseClassHierarchy(this, qObjectPredicate) != nullptr;
}
QString AbstractMetaClass::qualifiedCppName() const
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h
index 0c652a39a..ef4cef2b4 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -301,7 +301,6 @@ public:
EnumPattern,
ValuePattern,
ObjectPattern,
- QObjectPattern,
ValuePointerPattern,
NativePointerPattern,
NativePointerAsArrayPattern, // "int*" as "int[]"
@@ -376,12 +375,6 @@ public:
return m_pattern == EnumPattern;
}
- // returns true if the type is used as a QObject *
- bool isQObject() const
- {
- return m_pattern == QObjectPattern;
- }
-
// returns true if the type is used as an object, e.g. Xxx *
bool isObject() const
{
@@ -790,6 +783,7 @@ public:
Q_FLAG(CompareResultFlag)
AbstractMetaFunction();
+ explicit AbstractMetaFunction(const AddedFunctionPtr &addedFunc);
~AbstractMetaFunction();
QString name() const
@@ -1010,14 +1004,7 @@ public:
}
/// Returns true if the AbstractMetaFunction was added by the user via the type system description.
- bool isUserAdded() const
- {
- return m_userAdded;
- }
- void setUserAdded(bool userAdded)
- {
- m_userAdded = userAdded;
- }
+ bool isUserAdded() const { return !m_addedFunction.isNull(); }
QString toString() const
{
@@ -1125,9 +1112,9 @@ private:
const AbstractMetaClass *m_declaringClass = nullptr;
QPropertySpec *m_propertySpec = nullptr;
AbstractMetaArgumentList m_arguments;
+ AddedFunctionPtr m_addedFunction;
uint m_constant : 1;
uint m_reverse : 1;
- uint m_userAdded : 1;
uint m_explicit : 1;
uint m_pointerOperator : 1;
uint m_isCallOperator : 1;
diff --git a/sources/shiboken2/ApiExtractor/apiextractor.cpp b/sources/shiboken2/ApiExtractor/apiextractor.cpp
index e301d891f..fbe7664e9 100644
--- a/sources/shiboken2/ApiExtractor/apiextractor.cpp
+++ b/sources/shiboken2/ApiExtractor/apiextractor.cpp
@@ -224,6 +224,7 @@ bool ApiExtractor::run()
m_builder->setLogDirectory(m_logDirectory);
m_builder->setGlobalHeader(m_cppFileName);
m_builder->setSkipDeprecated(m_skipDeprecated);
+ m_builder->setHeaderPaths(m_includePaths);
QByteArrayList arguments;
arguments.reserve(m_includePaths.size() + 1);
for (const HeaderPath &headerPath : qAsConst(m_includePaths))
diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp
index fa4c75743..fdae2359b 100644
--- a/sources/shiboken2/ApiExtractor/messages.cpp
+++ b/sources/shiboken2/ApiExtractor/messages.cpp
@@ -167,6 +167,12 @@ QString msgSkippingFunction(const FunctionModelItem &functionItem,
return result;
}
+QString msgCannotResolveEntity(const QString &name, const QString &reason)
+{
+ return QLatin1String("Cannot resolve entity \"") + name
+ + QLatin1String("\": ") + reason;
+}
+
QString msgCannotSetArrayUsage(const QString &function, int i, const QString &reason)
{
return function + QLatin1String(": Cannot use parameter ")
diff --git a/sources/shiboken2/ApiExtractor/messages.h b/sources/shiboken2/ApiExtractor/messages.h
index 539332aef..30b13fbf8 100644
--- a/sources/shiboken2/ApiExtractor/messages.h
+++ b/sources/shiboken2/ApiExtractor/messages.h
@@ -68,6 +68,8 @@ QString msgUnmatchedReturnType(const FunctionModelItem &functionItem,
QString msgSkippingFunction(const FunctionModelItem &functionItem,
const QString &signature, const QString &why);
+QString msgCannotResolveEntity(const QString &name, const QString &reason);
+
QString msgCannotSetArrayUsage(const QString &function, int i, const QString &reason);
QString msgUnableToTranslateType(const QString &t, const QString &why);
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
index 8bc9b24ac..9a845b04a 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
@@ -83,37 +83,35 @@ FileModelItem CodeModel::findFile(const QString &name) const
return findModelItem(m_files, name);
}
-CodeModelItem CodeModel::findItem(const QStringList &qualifiedName, CodeModelItem scope) const
-{
- for (int i = 0; i < qualifiedName.size(); ++i) {
- // ### Extend to look for members etc too.
- const QString &name = qualifiedName.at(i);
-
- if (NamespaceModelItem ns = qSharedPointerDynamicCast<_NamespaceModelItem>(scope)) {
- if (NamespaceModelItem tmp_ns = ns->findNamespace(name)) {
- scope = tmp_ns;
- continue;
- }
- }
-
- if (ScopeModelItem ss = qSharedPointerDynamicCast<_ScopeModelItem>(scope)) {
- if (ClassModelItem cs = ss->findClass(name)) {
- scope = cs;
- } else if (EnumModelItem es = ss->findEnum(name)) {
- if (i == qualifiedName.size() - 1)
- return es;
- } else if (TypeDefModelItem tp = ss->findTypeDef(name)) {
- if (i == qualifiedName.size() - 1)
- return tp;
- } else {
- // If we don't find the name in the scope chain we
- // need to return an empty item to indicate failure...
- return CodeModelItem();
+static CodeModelItem findRecursion(const ScopeModelItem &scope,
+ const QStringList &qualifiedName, int segment = 0)
+{
+ const QString &nameSegment = qualifiedName.at(segment);
+ if (segment == qualifiedName.size() - 1) { // Leaf item
+ if (ClassModelItem cs = scope->findClass(nameSegment))
+ return cs;
+ if (EnumModelItem es = scope->findEnum(nameSegment))
+ return es;
+ if (TypeDefModelItem tp = scope->findTypeDef(nameSegment))
+ return tp;
+ return CodeModelItem();
+ }
+ if (auto nestedClass = scope->findClass(nameSegment))
+ return findRecursion(nestedClass, qualifiedName, segment + 1);
+ if (auto namespaceItem = qSharedPointerDynamicCast<_NamespaceModelItem>(scope)) {
+ for (const auto &nestedNamespace : namespaceItem->namespaces()) {
+ if (nestedNamespace->name() == nameSegment) {
+ if (auto item = findRecursion(nestedNamespace, qualifiedName, segment + 1))
+ return item;
}
}
}
+ return CodeModelItem();
+}
- return scope;
+CodeModelItem CodeModel::findItem(const QStringList &qualifiedName, const ScopeModelItem &scope) const
+{
+ return findRecursion(scope, qualifiedName);
}
#ifndef QT_NO_DEBUG_STREAM
@@ -160,7 +158,7 @@ bool TypeInfo::isVoid() const
&& m_qualifiedName.constFirst() == QLatin1String("void");
}
-TypeInfo TypeInfo::resolveType(TypeInfo const &__type, CodeModelItem __scope)
+TypeInfo TypeInfo::resolveType(TypeInfo const &__type, const ScopeModelItem &__scope)
{
CodeModel *__model = __scope->model();
Q_ASSERT(__model != 0);
@@ -168,7 +166,7 @@ TypeInfo TypeInfo::resolveType(TypeInfo const &__type, CodeModelItem __scope)
return TypeInfo::resolveType(__model->findItem(__type.qualifiedName(), __scope), __type, __scope);
}
-TypeInfo TypeInfo::resolveType(CodeModelItem __item, TypeInfo const &__type, CodeModelItem __scope)
+TypeInfo TypeInfo::resolveType(CodeModelItem __item, TypeInfo const &__type, const ScopeModelItem &__scope)
{
// Copy the type and replace with the proper qualified name. This
// only makes sence to do if we're actually getting a resolved
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.h b/sources/shiboken2/ApiExtractor/parser/codemodel.h
index 0296a8cb2..64415e07b 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.h
@@ -82,7 +82,7 @@ public:
void addFile(FileModelItem item);
FileModelItem findFile(const QString &name) const;
- CodeModelItem findItem(const QStringList &qualifiedName, CodeModelItem scope) const;
+ CodeModelItem findItem(const QStringList &qualifiedName, const ScopeModelItem &scope) const;
private:
FileList m_files;
@@ -202,7 +202,7 @@ public:
QString toString() const;
static TypeInfo combine(const TypeInfo &__lhs, const TypeInfo &__rhs);
- static TypeInfo resolveType(TypeInfo const &__type, CodeModelItem __scope);
+ static TypeInfo resolveType(TypeInfo const &__type, const ScopeModelItem &__scope);
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const;
@@ -219,7 +219,7 @@ public:
private:
friend class TypeInfoTemplateArgumentHandler;
- static TypeInfo resolveType(CodeModelItem item, TypeInfo const &__type, CodeModelItem __scope);
+ static TypeInfo resolveType(CodeModelItem item, TypeInfo const &__type, const ScopeModelItem &__scope);
QStringList m_qualifiedName;
QStringList m_arrayElements;
diff --git a/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt b/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
index e100ef493..a36cc17de 100644
--- a/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
+++ b/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
@@ -1,9 +1,3 @@
-find_package(Qt5Core)
-find_package(Qt5Gui)
-find_package(Qt5Test)
-find_package(Qt5Xml)
-find_package(Qt5XmlPatterns)
-
set(CMAKE_AUTORCC ON)
macro(declare_test testname)
@@ -15,19 +9,13 @@ macro(declare_test testname)
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${testname}.qrc")
list(APPEND SOURCES "${testname}.qrc")
endif ()
+
add_executable(${testname} ${SOURCES})
- include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}
- ${apiextractor_SOURCE_DIR}
- ${Qt5Test_INCLUDE_DIRS}
- )
- link_directories(${APIEXTRACTOR_EXTRA_LINK_DIRECTORIES})
- target_link_libraries(${testname}
- ${Qt5XmlPatterns_LIBRARIES}
- ${Qt5Test_LIBRARIES}
- ${Qt5Core_LIBRARIES}
- ${Qt5Gui_LIBRARIES}
- apiextractor)
+ target_include_directories(${testname} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${apiextractor_SOURCE_DIR}
+ )
+ target_link_libraries(${testname} PRIVATE apiextractor Qt5::Test)
add_test(${testname} ${testname})
if (INSTALL_TESTS)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${testname}
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp
index fc67ebba5..63434b3a5 100644
--- a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp
@@ -85,7 +85,6 @@ void TestAbstractMetaType::testConstCharPtrType()
QVERIFY(!rtype->isObject());
QVERIFY(!rtype->isPrimitive()); // const char* differs from char, so it's not considered a primitive type by apiextractor
QVERIFY(rtype->isNativePointer());
- QVERIFY(!rtype->isQObject());
QCOMPARE(rtype->referenceType(), NoReference);
QVERIFY(!rtype->isValue());
QVERIFY(!rtype->isValuePointer());
@@ -159,7 +158,6 @@ void TestAbstractMetaType::testCharType()
QVERIFY(!rtype->isObject());
QVERIFY(rtype->isPrimitive());
QVERIFY(!rtype->isNativePointer());
- QVERIFY(!rtype->isQObject());
QCOMPARE(rtype->referenceType(), NoReference);
QVERIFY(!rtype->isValue());
QVERIFY(!rtype->isValuePointer());
diff --git a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
index db49942c9..8c443527e 100644
--- a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
@@ -71,26 +71,32 @@ void TestAddFunction::testParsingFuncNameAndConstness()
void TestAddFunction::testAddFunction()
{
- const char cppCode[] = "struct B {}; struct A { void a(int); };\n";
- const char xmlCode[] = "\
- <typesystem package='Foo'>\n\
- <primitive-type name='int'/>\n\
- <primitive-type name='float'/>\n\
- <value-type name='B'/>\n\
- <value-type name='A'>\n\
- <add-function signature='b(int, float = 4.6, const B&amp;)' return-type='int' access='protected'>\n\
- </add-function>\n\
- </value-type>\n\
- </typesystem>\n";
+ const char cppCode[] = R"CPP(
+struct B {};
+struct A {
+ void a(int);
+};)CPP";
+ const char xmlCode[] = R"XML(
+<typesystem package='Foo'>
+ <primitive-type name='int'/>
+ <primitive-type name='float'/>
+ <value-type name='B'/>
+ <value-type name='A'>
+ <add-function signature='b(int, float = 4.6, const B&amp;)' return-type='int' access='protected'/>
+ <add-function signature='operator()(int)' return-type='int' access='public'/>
+ </value-type>
+</typesystem>)XML";
+
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
QVERIFY(!builder.isNull());
TypeDatabase* typeDb = TypeDatabase::instance();
AbstractMetaClassList classes = builder->classes();
const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
QVERIFY(classA);
- QCOMPARE(classA->functions().count(), 4); // default ctor, default copy ctor, func a() and the added function
+ QCOMPARE(classA->functions().count(), 5); // default ctor, default copy ctor, func a() and the added functions
- AbstractMetaFunction* addedFunc = classA->functions().last();
+ auto addedFunc = classA->findFunction(QLatin1String("b"));
+ QVERIFY(addedFunc);
QCOMPARE(addedFunc->visibility(), AbstractMetaFunction::Protected);
QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction);
QVERIFY(addedFunc->isUserAdded());
@@ -109,6 +115,9 @@ void TestAddFunction::testAddFunction()
QCOMPARE(args[0]->type()->typeEntry(), returnType->typeEntry());
QCOMPARE(args[1]->defaultValueExpression(), QLatin1String("4.6"));
QCOMPARE(args[2]->type()->typeEntry(), typeDb->findType(QLatin1String("B")));
+
+ auto addedCallOperator = classA->findFunction(QLatin1String("operator()"));
+ QVERIFY(addedCallOperator);
}
void TestAddFunction::testAddFunctionConstructor()
@@ -265,7 +274,7 @@ void TestAddFunction::testAddFunctionAtModuleLevel()
QCOMPARE(addedFuncs.size(), 1);
- FunctionModificationList mods = typeDb->functionModifications(QLatin1String("func(int,int)"));
+ const FunctionModificationList mods = addedFuncs.constFirst()->modifications;
QCOMPARE(mods.size(), 1);
QVERIFY(mods.first().isCodeInjection());
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp
index 4ce2790f5..a8c69d376 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp
@@ -430,8 +430,8 @@ void TypeDatabase::addGlobalUserFunctions(const AddedFunctionList &functions)
AddedFunctionList TypeDatabase::findGlobalUserFunctions(const QString& name) const
{
AddedFunctionList addedFunctions;
- for (const AddedFunction &func : m_globalUserFunctions) {
- if (func.name() == name)
+ for (const AddedFunctionPtr &func : m_globalUserFunctions) {
+ if (func->name() == name)
addedFunctions.append(func);
}
return addedFunctions;
@@ -802,7 +802,6 @@ void ComplexTypeEntry::formatDebug(QDebug &d) const
{
TypeEntry::formatDebug(d);
FORMAT_NONEMPTY_STRING("targetLangName", m_targetLangName)
- FORMAT_BOOL("QObject", m_qobject)
FORMAT_BOOL("polymorphicBase", m_polymorphicBase)
FORMAT_BOOL("genericClass", m_genericClass)
FORMAT_BOOL("deleteInMainThread", m_deleteInMainThread)
diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp
index ad97e40ee..318a52e2e 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystem.cpp
@@ -40,6 +40,7 @@
#include <QtCore/QStringAlgorithms>
#include <QtCore/QXmlStreamAttributes>
#include <QtCore/QXmlStreamReader>
+#include <QtCore/QXmlStreamEntityResolver>
#include <algorithm>
@@ -105,6 +106,8 @@ static inline QString yesAttributeValue() { return QStringLiteral("yes"); }
static inline QString trueAttributeValue() { return QStringLiteral("true"); }
static inline QString falseAttributeValue() { return QStringLiteral("false"); }
+static inline QString callOperator() { return QStringLiteral("operator()"); }
+
static QVector<CustomConversion *> customConversionsForReview;
// Set a regular expression for rejection from text. By legacy, those are fixed
@@ -437,12 +440,75 @@ static QString msgUnusedAttributes(const QStringRef &tag, const QXmlStreamAttrib
return result;
}
+// QXmlStreamEntityResolver::resolveEntity(publicId, systemId) is not
+// implemented; resolve via undeclared entities instead.
+class TypeSystemEntityResolver : public QXmlStreamEntityResolver
+{
+public:
+ explicit TypeSystemEntityResolver(const QString &currentPath) :
+ m_currentPath(currentPath) {}
+
+ QString resolveUndeclaredEntity(const QString &name) override;
+
+private:
+ QString readFile(const QString &entityName, QString *errorMessage) const;
+
+ const QString m_currentPath;
+ QHash<QString, QString> m_cache;
+};
+
+QString TypeSystemEntityResolver::readFile(const QString &entityName, QString *errorMessage) const
+{
+ QString fileName = entityName;
+ if (!fileName.contains(QLatin1Char('.')))
+ fileName += QLatin1String(".xml");
+ QString path = TypeDatabase::instance()->modifiedTypesystemFilepath(fileName, m_currentPath);
+ if (!QFileInfo::exists(path)) // PySide2-specific hack
+ fileName.prepend(QLatin1String("typesystem_"));
+ path = TypeDatabase::instance()->modifiedTypesystemFilepath(fileName, m_currentPath);
+ if (!QFileInfo::exists(path)) {
+ *errorMessage = QLatin1String("Unable to resolve: ") + entityName;
+ return QString();
+ }
+ QFile file(path);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ *errorMessage = msgCannotOpenForReading(file);
+ return QString();
+ }
+ QString result = QString::fromUtf8(file.readAll()).trimmed();
+ // Remove license header comments on which QXmlStreamReader chokes
+ if (result.startsWith(QLatin1String("<!--"))) {
+ const int commentEnd = result.indexOf(QLatin1String("-->"));
+ if (commentEnd != -1) {
+ result.remove(0, commentEnd + 3);
+ result = result.trimmed();
+ }
+ }
+ return result;
+}
+
+QString TypeSystemEntityResolver::resolveUndeclaredEntity(const QString &name)
+{
+ auto it = m_cache.find(name);
+ if (it == m_cache.end()) {
+ QString errorMessage;
+ it = m_cache.insert(name, readFile(name, &errorMessage));
+ if (it.value().isEmpty()) { // The parser will fail and display the line number.
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgCannotResolveEntity(name, errorMessage)));
+ }
+ }
+ return it.value();
+}
+
Handler::Handler(TypeDatabase *database, bool generate) :
m_database(database),
m_generate(generate ? TypeEntry::GenerateAll : TypeEntry::GenerateForSubclass)
{
}
+Handler::~Handler() = default;
+
static QString readerFileName(const QXmlStreamReader &reader)
{
const QFile *file = qobject_cast<const QFile *>(reader.device());
@@ -582,6 +648,8 @@ bool Handler::parse(QXmlStreamReader &reader)
const QString fileName = readerFileName(reader);
if (!fileName.isEmpty())
m_currentPath = QFileInfo(fileName).absolutePath();
+ m_entityResolver.reset(new TypeSystemEntityResolver(m_currentPath));
+ reader.setEntityResolver(m_entityResolver.data());
while (!reader.atEnd()) {
switch (reader.readNext()) {
@@ -674,6 +742,17 @@ bool Handler::endElement(const QStringRef &localName)
}
}
break;
+ case StackElement::AddFunction: {
+ // Leaving add-function: Assign all modifications to the added function
+ StackElementContext *top = m_contextStack.top();
+ const int modIndex = top->addedFunctionModificationIndex;
+ top->addedFunctionModificationIndex = -1;
+ Q_ASSERT(modIndex >= 0);
+ Q_ASSERT(!top->addedFunctions.isEmpty());
+ while (modIndex < top->functionMods.size())
+ top->addedFunctions.last()->modifications.append(top->functionMods.takeAt(modIndex));
+ }
+ break;
case StackElement::NativeToTarget:
case StackElement::AddConversion: {
CustomConversion* customConversion = static_cast<TypeEntry*>(m_current->entry)->customConversion();
@@ -2009,8 +2088,8 @@ bool Handler::parseAddFunction(const QXmlStreamReader &,
return false;
}
- AddedFunction func(signature, returnType);
- func.setStatic(staticFunction);
+ AddedFunctionPtr func(new AddedFunction(signature, returnType));
+ func->setStatic(staticFunction);
if (!signature.contains(QLatin1Char('(')))
signature += QLatin1String("()");
m_currentSignature = signature;
@@ -2021,10 +2100,12 @@ bool Handler::parseAddFunction(const QXmlStreamReader &,
m_error = QString::fromLatin1("Bad access type '%1'").arg(access);
return false;
}
- func.setAccess(a);
+ func->setAccess(a);
}
m_contextStack.top()->addedFunctions << func;
+ m_contextStack.top()->addedFunctionModificationIndex =
+ m_contextStack.top()->functionMods.size();
FunctionModification mod;
if (!mod.setSignature(m_currentSignature, &m_error))
@@ -3231,7 +3312,10 @@ AddedFunction::AddedFunction(QString signature, const QString &returnType) :
Q_ASSERT(!returnType.isEmpty());
m_returnType = parseType(returnType);
signature = signature.trimmed();
- int endPos = signature.indexOf(QLatin1Char('('));
+ // Skip past "operator()(...)"
+ const int parenStartPos = signature.startsWith(callOperator())
+ ? callOperator().size() : 0;
+ int endPos = signature.indexOf(QLatin1Char('('), parenStartPos);
if (endPos < 0) {
m_isConst = false;
m_name = signature;
@@ -3413,7 +3497,6 @@ ComplexTypeEntry::ComplexTypeEntry(const QString &name, TypeEntry::Type t,
const QVersionNumber &vr) :
TypeEntry(name, t, vr),
m_qualifiedCppName(name),
- m_qobject(false),
m_polymorphicBase(false),
m_genericClass(false),
m_deleteInMainThread(false)
@@ -3483,6 +3566,20 @@ static const QSet<QString> &primitiveCppTypes()
return result;
}
+void TypeEntry::setInclude(const Include &inc)
+{
+ // This is a workaround for preventing double inclusion of the QSharedPointer implementation
+ // header, which does not use header guards. In the previous parser this was not a problem
+ // because the Q_QDOC define was set, and the implementation header was never included.
+ if (inc.name().endsWith(QLatin1String("qsharedpointer_impl.h"))) {
+ QString path = inc.name();
+ path.remove(QLatin1String("_impl"));
+ m_include = Include(inc.type(), path);
+ } else {
+ m_include = inc;
+ }
+}
+
bool TypeEntry::isCppPrimitive() const
{
if (!isPrimitive())
diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h
index 96d0bb5fd..f089bb6e0 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.h
+++ b/sources/shiboken2/ApiExtractor/typesystem.h
@@ -476,6 +476,8 @@ struct AddedFunction
return m_isStatic;
}
+ FunctionModificationList modifications;
+
private:
QString m_name;
QVector<TypeInfo> m_arguments;
@@ -835,16 +837,7 @@ public:
{
return m_include;
}
- void setInclude(const Include &inc)
- {
- // This is a workaround for preventing double inclusion of the QSharedPointer implementation
- // header, which does not use header guards. In the previous parser this was not a problem
- // because the Q_QDOC define was set, and the implementation header was never included.
- if (inc.name() == QLatin1String("qsharedpointer_impl.h"))
- m_include = Include(inc.type(), QLatin1String("qsharedpointer.h"));
- else
- m_include = inc;
- }
+ void setInclude(const Include &inc);
// Replace conversionRule arg to CodeSnip in future version
/// Set the type convertion rule
@@ -1278,7 +1271,7 @@ public:
{
m_addedFunctions = addedFunctions;
}
- void addNewFunction(const AddedFunction &addedFunction)
+ void addNewFunction(const AddedFunctionPtr &addedFunction)
{
m_addedFunctions << addedFunction;
}
@@ -1293,15 +1286,6 @@ public:
return m_fieldMods;
}
- bool isQObject() const
- {
- return m_qobject;
- }
- void setQObject(bool qobject)
- {
- m_qobject = qobject;
- }
-
QString defaultSuperclass() const
{
return m_defaultSuperclass;
@@ -1419,7 +1403,6 @@ private:
QString m_qualifiedCppName;
QString m_targetLangName;
- uint m_qobject : 1;
uint m_polymorphicBase : 1;
uint m_genericClass : 1;
uint m_deleteInMainThread : 1;
diff --git a/sources/shiboken2/ApiExtractor/typesystem_p.h b/sources/shiboken2/ApiExtractor/typesystem_p.h
index a119b2a97..f6b0717f4 100644
--- a/sources/shiboken2/ApiExtractor/typesystem_p.h
+++ b/sources/shiboken2/ApiExtractor/typesystem_p.h
@@ -29,11 +29,13 @@
#define TYPESYSTEM_P_H
#include <QStack>
+#include <QtCore/QScopedPointer>
#include "typesystem.h"
QT_FORWARD_DECLARE_CLASS(QXmlStreamAttributes)
QT_FORWARD_DECLARE_CLASS(QXmlStreamReader)
+class TypeSystemEntityResolver;
class TypeDatabase;
class StackElement
{
@@ -132,12 +134,16 @@ struct StackElementContext
FunctionModificationList functionMods;
FieldModificationList fieldMods;
DocModificationList docModifications;
+ int addedFunctionModificationIndex = -1;
};
class Handler
{
public:
+ Q_DISABLE_COPY(Handler)
+
Handler(TypeDatabase* database, bool generate);
+ ~Handler();
bool parse(QXmlStreamReader &reader);
@@ -255,6 +261,7 @@ private:
QString m_currentSignature;
QString m_currentPath;
+ QScopedPointer<TypeSystemEntityResolver> m_entityResolver;
};
#endif
diff --git a/sources/shiboken2/ApiExtractor/typesystem_typedefs.h b/sources/shiboken2/ApiExtractor/typesystem_typedefs.h
index dc6e5cbcc..5cea587ed 100644
--- a/sources/shiboken2/ApiExtractor/typesystem_typedefs.h
+++ b/sources/shiboken2/ApiExtractor/typesystem_typedefs.h
@@ -31,6 +31,7 @@
#include <QtCore/QHash>
#include <QtCore/QList>
+#include <QtCore/QSharedPointer>
#include <QtCore/QVector>
class CodeSnip;
@@ -40,7 +41,8 @@ struct AddedFunction;
struct FieldModification;
struct FunctionModification;
-typedef QVector<AddedFunction> AddedFunctionList;
+using AddedFunctionPtr = QSharedPointer<AddedFunction>;
+using AddedFunctionList = QVector<AddedFunctionPtr>;
typedef QVector<CodeSnip> CodeSnipList;
typedef QVector<DocModification> DocModificationList;
typedef QVector<FieldModification> FieldModificationList;
diff --git a/sources/shiboken2/CMakeLists.txt b/sources/shiboken2/CMakeLists.txt
index 1e52c4297..12429c657 100644
--- a/sources/shiboken2/CMakeLists.txt
+++ b/sources/shiboken2/CMakeLists.txt
@@ -11,10 +11,24 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/data/")
include(helpers)
include(shiboken_helpers)
-find_package(Qt5 5.12 REQUIRED COMPONENTS Core Xml XmlPatterns)
-
option(BUILD_TESTS "Build tests." TRUE)
option(USE_PYTHON_VERSION "Use specific python version to build shiboken2." "")
+option(DISABLE_DOCSTRINGS "Disable documentation extraction." FALSE)
+
+find_package(Qt5 5.12 REQUIRED COMPONENTS Core)
+find_package(Qt5Xml 5.12)
+find_package(Qt5XmlPatterns 5.12)
+find_package(LibXml2 2.6.32)
+find_package(LibXslt 1.1.19)
+if(BUILD_TESTS)
+ find_package(Qt5Test 5.12 REQUIRED)
+endif()
+
+if(NOT Qt5XmlPatterns_FOUND OR NOT Qt5Xml_FOUND)
+ set(DISABLE_DOCSTRINGS TRUE)
+ message(WARNING
+ "Documentation will not be built due to missing dependency (no Qt5XmlPatterns found).")
+endif()
# Don't display "up-to-date / install" messages when installing, to reduce visual clutter.
if (QUIET_BUILD)
diff --git a/sources/shiboken2/doc/typesystem_specifying_types.rst b/sources/shiboken2/doc/typesystem_specifying_types.rst
index f4016bc2c..ac1121461 100644
--- a/sources/shiboken2/doc/typesystem_specifying_types.rst
+++ b/sources/shiboken2/doc/typesystem_specifying_types.rst
@@ -3,6 +3,30 @@ Specifying Types
.. _typesystem:
+Including Snippets
+^^^^^^^^^^^^^^^^^^
+
+There might be repetitive XML code, for example function modifications that
+need to be done on classes that are not related by type inheritance.
+It is possible to split out such snippets and include them via an entity reference.
+
+.. code-block:: xml
+
+ <typesystem>
+ <object-type name="A">
+ &common_function_modifications;
+ </object-type>
+ <object-type name="B">
+ &common_function_modifications;
+ </object-type>
+ </typesystem>
+
+The entity name is interpreted as file name (with suffix **xml**) appended and resolved
+in the type system paths passed as command line argument.
+
+Note that this is not a standard externally parsed entity due to the limitations
+of the underlying parser.
+
typesystem
^^^^^^^^^^
diff --git a/sources/shiboken2/generator/CMakeLists.txt b/sources/shiboken2/generator/CMakeLists.txt
index 943e8d19b..745c366f5 100644
--- a/sources/shiboken2/generator/CMakeLists.txt
+++ b/sources/shiboken2/generator/CMakeLists.txt
@@ -1,8 +1,5 @@
project(shibokengenerator)
-find_package(Qt5Xml)
-find_package(Qt5XmlPatterns)
-
set(shiboken2_SRC
generator.cpp
shiboken2/cppgenerator.cpp
@@ -12,29 +9,23 @@ shiboken2/shibokengenerator.cpp
main.cpp
)
-if (NOT DISABLE_DOCSTRINGS)
- set(shiboken2_SRC ${shiboken2_SRC} qtdoc/qtdocgenerator.cpp)
- add_definitions(-DDOCSTRINGS_ENABLED)
-endif()
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/shiboken2
+add_executable(shiboken2 ${shiboken2_SRC})
+add_executable(Shiboken2::shiboken2 ALIAS shiboken2)
+add_dependencies(shiboken2 apiextractor)
+set_target_properties(shiboken2 PROPERTIES OUTPUT_NAME shiboken2${shiboken2_SUFFIX})
+target_include_directories(shiboken2 PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/shiboken2
${CMAKE_CURRENT_SOURCE_DIR}/qtdoc
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${apiextractor_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${Qt5XmlPatterns_INCLUDE_DIRS}
)
-
-add_executable(shiboken2 ${shiboken2_SRC})
-add_executable(Shiboken2::shiboken2 ALIAS shiboken2)
-add_dependencies(shiboken2 apiextractor)
-set_target_properties(shiboken2 PROPERTIES OUTPUT_NAME shiboken2${shiboken2_SUFFIX})
-target_link_libraries(shiboken2
- apiextractor
- ${Qt5Core_LIBRARIES}
- ${Qt5XmlPatterns_LIBRARIES}
- )
+target_link_libraries(shiboken2 apiextractor Qt5::Core)
+if (NOT DISABLE_DOCSTRINGS)
+ target_sources(shiboken2 PRIVATE qtdoc/qtdocgenerator.cpp)
+ target_compile_definitions(shiboken2 PUBLIC DOCSTRINGS_ENABLED)
+ target_link_libraries(shiboken2 Qt5::XmlPatterns)
+endif()
configure_file(shibokenconfig.h.in "${CMAKE_CURRENT_BINARY_DIR}/shibokenconfig.h" @ONLY)
diff --git a/sources/shiboken2/generator/generator.cpp b/sources/shiboken2/generator/generator.cpp
index 91e940f51..87758e533 100644
--- a/sources/shiboken2/generator/generator.cpp
+++ b/sources/shiboken2/generator/generator.cpp
@@ -421,7 +421,7 @@ bool Generator::generate()
for (const AbstractMetaType *type : qAsConst(m_d->instantiatedSmartPointers)) {
AbstractMetaClass *smartPointerClass =
- AbstractMetaClass::findClass(m_d->apiextractor->smartPointers(), type->name());
+ AbstractMetaClass::findClass(m_d->apiextractor->smartPointers(), type->typeEntry());
GeneratorContext context(smartPointerClass, type, true);
if (!generateFileForContext(context))
return false;
@@ -538,7 +538,7 @@ bool Generator::isObjectType(const TypeEntry* type)
}
bool Generator::isObjectType(const ComplexTypeEntry* type)
{
- return type->isObject() || type->isQObject();
+ return type->isObject();
}
bool Generator::isObjectType(const AbstractMetaClass* metaClass)
{
diff --git a/sources/shiboken2/generator/main.cpp b/sources/shiboken2/generator/main.cpp
index 094990b64..1817f6b03 100644
--- a/sources/shiboken2/generator/main.cpp
+++ b/sources/shiboken2/generator/main.cpp
@@ -373,8 +373,10 @@ static void parseIncludePathOption(const QString &option, HeaderType headerType,
const QStringList includePathListList =
it.value().split(pathSplitter, QString::SkipEmptyParts);
args.erase(it);
- for (const QString &s : includePathListList)
- extractor.addIncludePath(HeaderPath{QFile::encodeName(s), headerType});
+ for (const QString &s : includePathListList) {
+ auto path = QFile::encodeName(QDir::cleanPath(s));
+ extractor.addIncludePath(HeaderPath{path, headerType});
+ }
}
}
diff --git a/sources/shiboken2/generator/qtdoc/CMakeLists.txt b/sources/shiboken2/generator/qtdoc/CMakeLists.txt
deleted file mode 100644
index 1361ba8f1..000000000
--- a/sources/shiboken2/generator/qtdoc/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-project(qtdoc_generator)
-
-set(qtdoc_generator_SRC
-qtdocgenerator.cpp
-)
-
-include_directories(${generators_SOURCE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- ${APIEXTRACTOR_INCLUDE_DIR})
-add_executable(docgenerator main.cpp)
-set_target_properties(docgenerator PROPERTIES OUTPUT_NAME docgenerator${generator_SUFFIX})
-
-target_link_libraries(docgenerator ${Qt5Core_LIBRARES})
-
-add_library(qtdoc_generator SHARED ${qtdoc_generator_SRC})
-target_link_libraries(qtdoc_generator ${APIEXTRACTOR_LIBRARY} ${Qt5Core_LIBRARES} genrunner)
-set_property(TARGET qtdoc_generator PROPERTY PREFIX "")
-
-install(TARGETS qtdoc_generator DESTINATION ${generator_plugin_DIR})
-install(TARGETS docgenerator DESTINATION bin)
-
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
index 05729f4b5..6abfde7c9 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
@@ -1872,7 +1872,7 @@ QString QtDocGenerator::parseArgDocStyle(const AbstractMetaClass* /* cppClass */
defValue.replace(QLatin1String("::"), QLatin1String("."));
if (defValue == QLatin1String("nullptr"))
defValue = none();
- else if (defValue == QLatin1String("0") && (arg->type()->isQObject() || arg->type()->isObject()))
+ else if (defValue == QLatin1String("0") && arg->type()->isObject())
defValue = none();
}
ret += QLatin1Char('=') + defValue;
diff --git a/sources/shiboken2/generator/shiboken2/CMakeLists.txt b/sources/shiboken2/generator/shiboken2/CMakeLists.txt
deleted file mode 100644
index 5c1b612dd..000000000
--- a/sources/shiboken2/generator/shiboken2/CMakeLists.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-project(shibokengenerator)
-
-set(shiboken_SRC
-../generator.cpp
-cppgenerator.cpp
-headergenerator.cpp
-overloaddata.cpp
-shibokengenerator.cpp
-main.cpp
-)
-
-include_directories(${generators_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}
- ${APIEXTRACTOR_INCLUDE_DIR}
- ${Qt5Core_INCLUDE_DIRS}
- )
-
-add_executable(shiboken2 ${shiboken_SRC})
-set_target_properties(shiboken2 PROPERTIES OUTPUT_NAME shiboken2${shiboken_SUFFIX})
-target_link_libraries(shiboken2
- ${APIEXTRACTOR_LIBRARY}
- ${Qt5Core_LIBRARIES}
- )
-
-configure_file(shibokenconfig.h.in "${CMAKE_CURRENT_BINARY_DIR}/shibokenconfig.h" @ONLY)
-
-install(TARGETS shiboken2 DESTINATION bin)
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 2fedf9ae1..29220c739 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -664,7 +664,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
s << NULL_PTR;
s << "}," << endl;
}
- s << INDENT << '{' << NULL_PTR << "} // Sentinel" << endl;
+ s << INDENT << '{' << NULL_PTR << "} // Sentinel" << endl;
s << "};" << endl << endl;
}
@@ -907,7 +907,6 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
QTextStream ac(&argConv);
const PrimitiveTypeEntry* argType = (const PrimitiveTypeEntry*) arg->type()->typeEntry();
bool convert = argType->isObject()
- || arg->type()->isQObject()
|| argType->isValue()
|| arg->type()->isValuePointer()
|| arg->type()->isNativePointer()
@@ -3076,7 +3075,7 @@ QString CppGenerator::argumentNameFromIndex(const AbstractMetaFunction* func, in
AbstractMetaType *returnType = getTypeWithoutContainer(funcType);
if (returnType) {
pyArgName = QLatin1String(PYTHON_RETURN_VAR);
- *wrappedClass = AbstractMetaClass::findClass(classes(), returnType->typeEntry()->name());
+ *wrappedClass = AbstractMetaClass::findClass(classes(), returnType->typeEntry());
} else {
QString message = QLatin1String("Invalid Argument index (0, return value) on function modification: ")
+ (funcType ? funcType->name() : QLatin1String("void")) + QLatin1Char(' ');
@@ -3090,7 +3089,7 @@ QString CppGenerator::argumentNameFromIndex(const AbstractMetaFunction* func, in
AbstractMetaType* argType = getTypeWithoutContainer(func->arguments().at(realIndex)->type());
if (argType) {
- *wrappedClass = AbstractMetaClass::findClass(classes(), argType->typeEntry()->name());
+ *wrappedClass = AbstractMetaClass::findClass(classes(), argType->typeEntry());
if (argIndex == 1
&& !func->isConstructor()
&& OverloadData::isSingleArgument(getFunctionGroups(func->implementingClass())[func->name()]))
@@ -4925,11 +4924,11 @@ void CppGenerator::writeClassRegister(QTextStream &s,
// PYSIDE-510: Create a signatures string for the introspection feature.
s << "// The signatures string for the functions." << endl;
s << "// Multiple signatures have their index \"n:\" in front." << endl;
- s << "const char " << initFunctionName << "_SignaturesString[] = \"\"" << endl;
+ s << "static const char *" << initFunctionName << "_SignatureStrings[] = {" << endl;
QString line;
while (signatureStream.readLineInto(&line))
- s << INDENT << '"' << line << "\\n\"" << endl;
- s << ';' << endl << endl;
+ s << INDENT << '"' << line << "\"," << endl;
+ s << INDENT << NULL_PTR << "}; // Sentinel" << endl << endl;
s << "void init_" << initFunctionName;
s << "(PyObject* " << enclosingObjectVariable << ")" << endl;
s << '{' << endl;
@@ -4982,8 +4981,8 @@ void CppGenerator::writeClassRegister(QTextStream &s,
// 4:typeSpec
s << INDENT << '&' << chopType(pyTypeName) << "_spec," << endl;
- // 5:signaturesString
- s << INDENT << initFunctionName << "_SignaturesString," << endl;
+ // 5:signatureStrings
+ s << INDENT << initFunctionName << "_SignatureStrings," << endl;
// 6:cppObjDtor
s << INDENT;
@@ -5657,7 +5656,17 @@ bool CppGenerator::finishGeneration()
s << " /* m_clear */ nullptr," << endl;
s << " /* m_free */ nullptr" << endl;
s << "};" << endl << endl;
- s << "#endif" << endl;
+ s << "#endif" << endl << endl;
+
+ // PYSIDE-510: Create a signatures string for the introspection feature.
+ s << "// The signatures string for the global functions." << endl;
+ s << "// Multiple signatures have their index \"n:\" in front." << endl;
+ s << "static const char *" << moduleName() << "_SignatureStrings[] = {" << endl;
+ QString line;
+ while (signatureStream.readLineInto(&line))
+ s << INDENT << '"' << line << "\"," << endl;
+ s << INDENT << NULL_PTR << "}; // Sentinel" << endl << endl;
+
s << "SBK_MODULE_INIT_FUNCTION_BEGIN(" << moduleName() << ")" << endl;
ErrorCode errorCode(QLatin1String("SBK_MODULE_INIT_ERROR"));
@@ -5788,17 +5797,9 @@ bool CppGenerator::finishGeneration()
s << INDENT << "PySide::registerCleanupFunction(cleanTypesAttributes);" << endl << endl;
}
- // PYSIDE-510: Create a signatures string for the introspection feature.
- s << "// The signatures string for the global functions." << endl;
- s << "// Multiple signatures have their index \"n:\" in front." << endl;
- s << "const char " << moduleName() << "_SignaturesString[] = \"\"" << endl;
- QString line;
- while (signatureStream.readLineInto(&line))
- s << INDENT << '"' << line << "\\n\"" << endl;
- s << ';' << endl;
// finish the rest of __signature__ initialization.
s << INDENT << "FinishSignatureInitialization(module, " << moduleName()
- << "_SignaturesString);" << endl;
+ << "_SignatureStrings);" << endl;
if (usePySideExtensions()) {
// initialize the qApp module.
diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.cpp b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
index 9f0ac51e5..becd66879 100644
--- a/sources/shiboken2/generator/shiboken2/overloaddata.cpp
+++ b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
@@ -322,7 +322,7 @@ void OverloadData::sortNextOverloads()
}
// Process inheritance relationships
- if (targetType->isValue() || targetType->isObject() || targetType->isQObject()) {
+ if (targetType->isValue() || targetType->isObject()) {
const AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_generator->classes(), targetType->typeEntry());
const AbstractMetaClassList &ancestors = m_generator->getAllAncestors(metaClass);
for (const AbstractMetaClass *ancestor : ancestors) {
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index b5069db14..002ab8cfb 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -373,7 +373,7 @@ QString ShibokenGenerator::fullPythonClassName(const AbstractMetaClass *metaClas
return fullClassName;
}
-QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunction *func) //WS
+QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunction *func)
{
QString funcName;
if (func->isOperatorOverload())
@@ -729,8 +729,7 @@ QString ShibokenGenerator::getFormatUnitString(const AbstractMetaFunction* func,
if (!func->typeReplaced(arg->argumentIndex() + 1).isEmpty()) {
result += QLatin1Char(objType);
- } else if (arg->type()->isQObject()
- || arg->type()->isObject()
+ } else if (arg->type()->isObject()
|| arg->type()->isValue()
|| arg->type()->isValuePointer()
|| arg->type()->isNativePointer()
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
index d2c4b3292..80b172778 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
@@ -216,7 +216,7 @@ protected:
QString wrapperName(const AbstractMetaType *metaType) const;
QString fullPythonClassName(const AbstractMetaClass *metaClass);
- QString fullPythonFunctionName(const AbstractMetaFunction *func); //WS
+ QString fullPythonFunctionName(const AbstractMetaFunction *func);
static QString protectedEnumSurrogateName(const AbstractMetaEnum* metaEnum);
static QString protectedFieldGetterName(const AbstractMetaField* field);
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp
index a008fece8..3a043d849 100644
--- a/sources/shiboken2/libshiboken/basewrapper.cpp
+++ b/sources/shiboken2/libshiboken/basewrapper.cpp
@@ -744,18 +744,14 @@ introduceWrapperType(PyObject *enclosingObject,
const char *typeName,
const char *originalName,
PyType_Spec *typeSpec,
- const char *signaturesString,
+ const char *signatureStrings[],
ObjectDestructor cppObjDtor,
SbkObjectType *baseType,
PyObject *baseTypes,
unsigned wrapperFlags)
{
- if (baseType) {
- typeSpec->slots[0].pfunc = reinterpret_cast<void *>(baseType);
- }
- else {
- typeSpec->slots[0].pfunc = reinterpret_cast<void *>(SbkObject_TypeF());
- }
+ typeSpec->slots[0].pfunc = reinterpret_cast<void *>(baseType ? baseType : SbkObject_TypeF());
+
PyObject *heaptype = PyType_FromSpecWithBases(typeSpec, baseTypes);
Py_TYPE(heaptype) = SbkObjectType_TypeF();
Py_INCREF(Py_TYPE(heaptype));
@@ -769,7 +765,7 @@ introduceWrapperType(PyObject *enclosingObject,
}
}
// PYSIDE-510: Here is the single change to support signatures.
- if (SbkSpecial_Type_Ready(enclosingObject, reinterpret_cast<PyTypeObject *>(type), signaturesString) < 0)
+ if (SbkSpecial_Type_Ready(enclosingObject, reinterpret_cast<PyTypeObject *>(type), signatureStrings) < 0)
return nullptr;
initPrivateData(type);
@@ -779,20 +775,14 @@ introduceWrapperType(PyObject *enclosingObject,
setOriginalName(type, originalName);
setDestructorFunction(type, cppObjDtor);
+ PyObject *ob_type = reinterpret_cast<PyObject *>(type);
- if (wrapperFlags & InnerClass) {
- if (PyDict_SetItemString(enclosingObject, typeName, reinterpret_cast<PyObject *>(type)) == 0)
- return type;
- else
- return nullptr;
- }
+ if (wrapperFlags & InnerClass)
+ return PyDict_SetItemString(enclosingObject, typeName, ob_type) == 0 ? type : nullptr;
- //PyModule_AddObject steals type's reference.
- Py_INCREF(reinterpret_cast<PyObject *>(type));
- if (PyModule_AddObject(enclosingObject, typeName, reinterpret_cast<PyObject *>(type)) == 0) {
- return type;
- }
- return nullptr;
+ // PyModule_AddObject steals type's reference.
+ Py_INCREF(ob_type);
+ return PyModule_AddObject(enclosingObject, typeName, ob_type) == 0 ? type : nullptr;
}
void setSubTypeInitHook(SbkObjectType* type, SubTypeInitHook func)
diff --git a/sources/shiboken2/libshiboken/basewrapper.h b/sources/shiboken2/libshiboken/basewrapper.h
index e1cc64ba9..d12b7222b 100644
--- a/sources/shiboken2/libshiboken/basewrapper.h
+++ b/sources/shiboken2/libshiboken/basewrapper.h
@@ -219,7 +219,7 @@ LIBSHIBOKEN_API SbkObjectType *introduceWrapperType(PyObject *enclosingObject,
const char *typeName,
const char *originalName,
PyType_Spec *typeSpec,
- const char *signaturesString,
+ const char *signatureStrings[],
ObjectDestructor cppObjDtor,
SbkObjectType *baseType,
PyObject *baseTypes,
diff --git a/sources/shiboken2/libshiboken/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h
index d883677ce..ffbc570a8 100644
--- a/sources/shiboken2/libshiboken/pep384impl.h
+++ b/sources/shiboken2/libshiboken/pep384impl.h
@@ -316,6 +316,7 @@ LIBSHIBOKEN_API void PyBuffer_Release(Pep_buffer *view);
#else
#define Pep_buffer Py_buffer
+#define PepType_AS_BUFFER(type) ((type)->tp_as_buffer)
#endif /* Py_LIMITED_API */
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index dea4c9b09..3defca7d2 100644
--- a/sources/shiboken2/libshiboken/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature.cpp
@@ -46,7 +46,6 @@ extern "C"
/*
* The documentation is located in file signature_doc.rst
*/
-
#include "signature.h"
#include <structmember.h>
@@ -62,6 +61,7 @@ extern "C"
#define PYTHON_NEEDS_ITERATOR_FLAG (!PYTHON_IS_PYTHON3)
#define PYTHON_EXPOSES_METHODDESCR (PYTHON_IS_PYTHON3)
#define PYTHON_NO_TYPE_IN_FUNCTIONS (!PYTHON_IS_PYTHON3 || Py_LIMITED_API)
+#define PYTHON_HAS_INT_AND_LONG (!PYTHON_IS_PYTHON3)
// These constants are still in use:
#define PYTHON_USES_D_COMMON (PY_VERSION_HEX >= 0x03020000)
@@ -72,15 +72,15 @@ typedef struct safe_globals_struc {
PyObject *arg_dict;
PyObject *map_dict;
// init part 2: run module
- PyObject *sigparse_func;
- PyObject *createsig_func;
+ PyObject *pyside_type_init_func;
+ PyObject *create_signature_func;
PyObject *seterror_argument_func;
PyObject *make_helptext_func;
} safe_globals_struc, *safe_globals;
static safe_globals pyside_globals = 0;
-static PyObject *GetClassKey(PyObject *ob);
+static PyObject *GetTypeKey(PyObject *ob);
static PyObject *GetSignature_Function(PyObject *, const char *);
static PyObject *GetSignature_TypeMod(PyObject *, const char *);
@@ -101,8 +101,8 @@ CreateSignature(PyObject *props, PyObject *key)
* This is so much simpler than using all the attributes explicitly
* to support '_signature_is_functionlike()'.
*/
- return PyObject_CallFunction(pyside_globals->createsig_func,
- (char *)"(OO)", props, key);
+ return PyObject_CallFunction(pyside_globals->create_signature_func,
+ const_cast<char *>("(OO)"), props, key);
}
static PyObject *
@@ -139,10 +139,10 @@ _get_class_of_cf(PyObject *ob_cf)
}
}
- PyObject *typemod = (PyType_Check(selftype) || PyModule_Check(selftype))
- ? selftype : (PyObject *)Py_TYPE(selftype);
- Py_INCREF(typemod);
- return typemod;
+ PyObject *obtype_mod = (PyType_Check(selftype) || PyModule_Check(selftype))
+ ? selftype : reinterpret_cast<PyObject *>(Py_TYPE(selftype));
+ Py_INCREF(obtype_mod);
+ return obtype_mod;
}
static PyObject *
@@ -198,24 +198,24 @@ static PyObject *
compute_name_key(PyObject *ob)
{
if (PyType_Check(ob))
- return GetClassKey(ob);
+ return GetTypeKey(ob);
Shiboken::AutoDecRef func_name(get_funcname(ob));
- Shiboken::AutoDecRef type_key(GetClassKey(GetClassOfFunc(ob)));
+ Shiboken::AutoDecRef type_key(GetTypeKey(GetClassOfFunc(ob)));
return Py_BuildValue("(OO)", type_key.object(), func_name.object());
}
static int
build_name_key_to_func(PyObject *obtype)
{
- PyTypeObject *type = (PyTypeObject *)obtype;
+ PyTypeObject *type = reinterpret_cast<PyTypeObject *>(obtype);
PyMethodDef *meth = type->tp_methods;
if (meth == 0)
return 0;
- Shiboken::AutoDecRef type_key(GetClassKey(obtype));
- for (; meth->ml_name != NULL; meth++) {
- Shiboken::AutoDecRef func(PyCFunction_NewEx(meth, obtype, NULL));
+ Shiboken::AutoDecRef type_key(GetTypeKey(obtype));
+ for (; meth->ml_name != nullptr; meth++) {
+ Shiboken::AutoDecRef func(PyCFunction_NewEx(meth, obtype, nullptr));
Shiboken::AutoDecRef func_name(get_funcname(func));
Shiboken::AutoDecRef name_key(Py_BuildValue("(OO)", type_key.object(), func_name.object()));
if (func.isNull() || name_key.isNull()
@@ -240,7 +240,7 @@ name_key_to_func(PyObject *ob)
PyObject *ret = PyDict_GetItem(pyside_globals->map_dict, name_key);
if (ret == nullptr) {
// do a lazy initialization
- Shiboken::AutoDecRef type_key(GetClassKey(GetClassOfFunc(ob)));
+ Shiboken::AutoDecRef type_key(GetTypeKey(GetClassOfFunc(ob)));
PyObject *type = PyDict_GetItem(pyside_globals->map_dict,
type_key);
if (type == nullptr)
@@ -274,10 +274,10 @@ pyside_wd_get___signature__(PyObject *ob, const char *modifier)
}
static PyObject *
-pyside_tp_get___signature__(PyObject *typemod, const char *modifier)
+pyside_tp_get___signature__(PyObject *obtype_mod, const char *modifier)
{
init_module_2();
- return GetSignature_TypeMod(typemod, modifier);
+ return GetSignature_TypeMod(obtype_mod, modifier);
}
// forward
@@ -285,13 +285,13 @@ static PyObject *
GetSignature_Cached(PyObject *props, const char *sig_kind, const char *modifier);
static PyObject *
-GetClassKey(PyObject *ob)
+GetTypeKey(PyObject *ob)
{
assert(PyType_Check(ob) || PyModule_Check(ob));
/*
- * We obtain a unique key using the module name and the class name.
+ * We obtain a unique key using the module name and the type name.
*
- * The class name is a bit funny when modules are nested.
+ * The type name is a bit funny when modules are nested.
* Example:
*
* "sample.Photon.ValueIdentity" is a class.
@@ -326,32 +326,32 @@ TypeKey_to_PropsDict(PyObject *type_key, PyObject *obtype)
empty_dict = PyDict_New();
dict = empty_dict;
}
- if (PyTuple_Check(dict))
- dict = PySide_BuildSignatureProps(obtype);
+ if (!PyDict_Check(dict))
+ dict = PySide_BuildSignatureProps(type_key);
return dict;
}
static PyObject *
-GetSignature_Function(PyObject *ob_func, const char *modifier)
+GetSignature_Function(PyObject *obfunc, const char *modifier)
{
// make sure that we look into PyCFunction, only...
- if (Py_TYPE(ob_func) == PepFunction_TypePtr)
+ if (Py_TYPE(obfunc) == PepFunction_TypePtr)
Py_RETURN_NONE;
- Shiboken::AutoDecRef typemod(GetClassOfFunc(ob_func));
- Shiboken::AutoDecRef type_key(GetClassKey(typemod));
+ Shiboken::AutoDecRef obtype_mod(GetClassOfFunc(obfunc));
+ Shiboken::AutoDecRef type_key(GetTypeKey(obtype_mod));
if (type_key.isNull())
Py_RETURN_NONE;
- PyObject *dict = TypeKey_to_PropsDict(type_key, typemod);
+ PyObject *dict = TypeKey_to_PropsDict(type_key, obtype_mod);
if (dict == nullptr)
return nullptr;
- Shiboken::AutoDecRef func_name(PyObject_GetAttrString(ob_func, "__name__"));
+ Shiboken::AutoDecRef func_name(PyObject_GetAttrString(obfunc, "__name__"));
PyObject *props = !func_name.isNull() ? PyDict_GetItem(dict, func_name) : nullptr;
if (props == nullptr)
Py_RETURN_NONE;
- int flags = PyCFunction_GET_FLAGS(ob_func);
+ int flags = PyCFunction_GET_FLAGS(obfunc);
const char *sig_kind;
- if (PyModule_Check(typemod))
+ if (PyModule_Check(obtype_mod))
sig_kind = "function";
else if (flags & METH_CLASS)
sig_kind = "classmethod";
@@ -367,7 +367,7 @@ GetSignature_Wrapper(PyObject *ob, const char *modifier)
{
Shiboken::AutoDecRef func_name(PyObject_GetAttrString(ob, "__name__"));
Shiboken::AutoDecRef objclass(PyObject_GetAttrString(ob, "__objclass__"));
- Shiboken::AutoDecRef class_key(GetClassKey(objclass));
+ Shiboken::AutoDecRef class_key(GetTypeKey(objclass));
if (func_name.isNull() || objclass.isNull() || class_key.isNull())
return nullptr;
@@ -384,7 +384,7 @@ static PyObject *
GetSignature_TypeMod(PyObject *ob, const char *modifier)
{
Shiboken::AutoDecRef ob_name(PyObject_GetAttrString(ob, "__name__"));
- Shiboken::AutoDecRef ob_key(GetClassKey(ob));
+ Shiboken::AutoDecRef ob_key(GetTypeKey(ob));
PyObject *dict = TypeKey_to_PropsDict(ob_key, ob);
if (dict == nullptr)
@@ -430,9 +430,9 @@ static safe_globals_struc *
init_phase_1(void)
{
{
- safe_globals_struc *p = (safe_globals_struc *)
- malloc(sizeof(safe_globals_struc));
- if (p == NULL)
+ safe_globals_struc *p = reinterpret_cast<safe_globals_struc *>
+ (malloc(sizeof(safe_globals_struc)));
+ if (p == nullptr)
goto error;
/*
* Initializing module signature_bootstrap.
@@ -479,7 +479,6 @@ init_phase_1(void)
PyObject *mdict = PyModule_GetDict(p->helper_module);
if (PyDict_SetItemString(mdict, "__builtins__", PyEval_GetBuiltins()) < 0)
goto error;
-
/*
* Unpack an embedded ZIP file with more signature modules.
* They will be loaded later with the zipimporter.
@@ -488,11 +487,13 @@ init_phase_1(void)
const char **block_ptr = (const char **)PySide_CompressedSignaturePackage;
int npieces = 0;
PyObject *piece, *zipped_string_sequence = PyList_New(0);
+ if (zipped_string_sequence == nullptr)
+ return nullptr;
for (; **block_ptr != 0; ++block_ptr) {
npieces++;
// we avoid the string/unicode dilemma by not using PyString_XXX:
piece = Py_BuildValue("s", *block_ptr);
- if (piece == NULL || PyList_Append(zipped_string_sequence, piece) < 0)
+ if (piece == nullptr || PyList_Append(zipped_string_sequence, piece) < 0)
goto error;
}
if (PyDict_SetItemString(mdict, "zipstring_sequence", zipped_string_sequence) < 0)
@@ -501,12 +502,12 @@ init_phase_1(void)
// build a dict for diverse mappings
p->map_dict = PyDict_New();
- if (p->map_dict == NULL)
+ if (p->map_dict == nullptr)
goto error;
// build a dict for the prepared arguments
p->arg_dict = PyDict_New();
- if (p->arg_dict == NULL
+ if (p->arg_dict == nullptr
|| PyObject_SetAttrString(p->helper_module, "pyside_arg_dict", p->arg_dict) < 0)
goto error;
return p;
@@ -514,7 +515,7 @@ init_phase_1(void)
error:
PyErr_Print();
PyErr_SetString(PyExc_SystemError, "could not initialize part 1");
- return NULL;
+ return nullptr;
}
static int
@@ -524,7 +525,7 @@ init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
PyMethodDef *ml;
// The single function to be called, but maybe more to come.
- for (ml = methods; ml->ml_name != NULL; ml++) {
+ for (ml = methods; ml->ml_name != nullptr; ml++) {
PyObject *v = PyCFunction_NewEx(ml, nullptr, nullptr);
if (v == nullptr
|| PyObject_SetAttrString(p->helper_module, ml->ml_name, v) != 0)
@@ -532,24 +533,24 @@ init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
Py_DECREF(v);
}
PyObject *bootstrap_func = PyObject_GetAttrString(p->helper_module, "bootstrap");
- if (bootstrap_func == NULL)
+ if (bootstrap_func == nullptr)
goto error;
// The return value of the bootstrap function is the loader module.
- PyObject *loader = PyObject_CallFunction(bootstrap_func, (char *)"()");
+ PyObject *loader = PyObject_CallFunction(bootstrap_func, const_cast<char *>("()"));
if (loader == nullptr)
goto error;
// now the loader should be initialized
- p->sigparse_func = PyObject_GetAttrString(loader, "pyside_type_init");
- if (p->sigparse_func == NULL)
+ p->pyside_type_init_func = PyObject_GetAttrString(loader, "pyside_type_init");
+ if (p->pyside_type_init_func == nullptr)
goto error;
- p->createsig_func = PyObject_GetAttrString(loader, "create_signature");
- if (p->createsig_func == NULL)
+ p->create_signature_func = PyObject_GetAttrString(loader, "create_signature");
+ if (p->create_signature_func == nullptr)
goto error;
p->seterror_argument_func = PyObject_GetAttrString(loader, "seterror_argument");
- if (p->seterror_argument_func == NULL)
+ if (p->seterror_argument_func == nullptr)
goto error;
p->make_helptext_func = PyObject_GetAttrString(loader, "make_helptext");
- if (p->make_helptext_func == NULL)
+ if (p->make_helptext_func == nullptr)
goto error;
return 0;
}
@@ -568,7 +569,7 @@ _fixup_getset(PyTypeObject *type, const char *name, PyGetSetDef *new_gsp)
*/
PyGetSetDef *gsp = type->tp_getset;
if (gsp != nullptr) {
- for (; gsp->name != NULL; gsp++) {
+ for (; gsp->name != nullptr; gsp++) {
if (strcmp(gsp->name, name) == 0) {
new_gsp->set = gsp->set;
new_gsp->doc = gsp->doc;
@@ -592,7 +593,7 @@ add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **old_descr)
assert(PyType_Check(type));
PyType_Ready(type);
PyObject *dict = type->tp_dict;
- for (; gsp->name != NULL; gsp++) {
+ for (; gsp->name != nullptr; gsp++) {
PyObject *have_descr = PyDict_GetItemString(dict, gsp->name);
if (have_descr != nullptr) {
assert(strcmp(gsp->name, "__doc__") == 0);
@@ -730,7 +731,7 @@ get_signature(PyObject *self, PyObject *args)
init_module_1();
if (!PyArg_ParseTuple(args, "O|s", &ob, &modifier))
- return NULL;
+ return nullptr;
if (Py_TYPE(ob) == PepFunction_TypePtr)
Py_RETURN_NONE;
@@ -784,15 +785,17 @@ PySide_PatchTypes(void)
static int init_done = 0;
if (!init_done) {
- Shiboken::AutoDecRef md(PyObject_GetAttrString((PyObject *)&PyString_Type, "split")); // method-descriptor
- Shiboken::AutoDecRef wd(PyObject_GetAttrString((PyObject *)Py_TYPE(Py_True), "__add__")); // wrapper-descriptor
- if (md.isNull() || wd.isNull()
- || PyType_Ready(Py_TYPE(md)) < 0
+ Shiboken::AutoDecRef meth_descr(PyObject_GetAttrString(
+ reinterpret_cast<PyObject *>(&PyString_Type), "split"));
+ Shiboken::AutoDecRef wrap_descr(PyObject_GetAttrString(
+ reinterpret_cast<PyObject *>(Py_TYPE(Py_True)), "__add__"));
+ if (meth_descr.isNull() || wrap_descr.isNull()
+ || PyType_Ready(Py_TYPE(meth_descr)) < 0
|| add_more_getsets(PepMethodDescr_TypePtr, new_PyMethodDescr_getsets, &old_md_doc_descr) < 0
|| add_more_getsets(&PyCFunction_Type, new_PyCFunction_getsets, &old_cf_doc_descr) < 0
|| add_more_getsets(PepStaticMethod_TypePtr, new_PyStaticMethod_getsets, &old_sm_doc_descr) < 0
|| add_more_getsets(&PyType_Type, new_PyType_getsets, &old_tp_doc_descr) < 0
- || add_more_getsets(Py_TYPE(wd), new_PyWrapperDescr_getsets, &old_wd_doc_descr) < 0
+ || add_more_getsets(Py_TYPE(wrap_descr), new_PyWrapperDescr_getsets, &old_wd_doc_descr) < 0
)
return -1;
#ifndef _WIN32
@@ -819,52 +822,32 @@ init_module_1(void)
}
static int
-PySide_BuildSignatureArgs(PyObject *module, PyObject *type,
- const char *signatures)
+PySide_BuildSignatureArgs(PyObject *obtype_mod, const char *signatures[])
{
- PyObject *type_key, *arg_tup;
-
init_module_1();
- arg_tup = Py_BuildValue("(Os)", type, signatures);
- if (arg_tup == NULL)
- return -1;
- /*
- * We either get a module name or the dict of an EnclosingObject.
- * We can ignore the EnclosingObject since we get full name info
- * from the type.
- */
- if (!PyModule_Check(module))
- assert(PyDict_Check(module));
+ Shiboken::AutoDecRef type_key(GetTypeKey(obtype_mod));
/*
- * Normally, we would now just call the Python function with the
- * arguments and then continue processing.
- * But it is much better to delay the second part until it is
- * really needed. Why?
- *
- * - by doing it late, we save initialization time when no signatures
- * are requested,
- * - by calling the python function late, we can freely import PySide
- * without recursion problems.
+ * PYSIDE-996: Avoid string overflow in MSVC, which has a limit of
+ * 2**15 unicode characters (64 K memory).
+ * Instead of one huge string, we take a ssize_t that is the
+ * address of a string array. It will not be turned into a real
+ * string list until really used by Python. This is quite optimal.
*/
- type_key = GetClassKey(type);
- if (type_key == nullptr)
- return -1;
- if (PyDict_SetItem(pyside_globals->arg_dict, type_key, arg_tup) < 0)
+ Shiboken::AutoDecRef numkey(Py_BuildValue("n", signatures));
+ if (type_key.isNull() || numkey.isNull()
+ || PyDict_SetItem(pyside_globals->arg_dict, type_key, numkey) < 0)
return -1;
/*
- * We record also a mapping from type key to type. This helps to lazily
- * initialize the Py_LIMITED_API in name_key_to_func().
+ * We record also a mapping from type key to type/module. This helps to
+ * lazily initialize the Py_LIMITED_API in name_key_to_func().
*/
-
- if (PyDict_SetItem(pyside_globals->map_dict, type_key, type) < 0)
- return -1;
- return 0;
+ return PyDict_SetItem(pyside_globals->map_dict, type_key, obtype_mod) == 0 ? 0 : -1;
}
static PyMethodDef signature_methods[] = {
{"get_signature", (PyCFunction)get_signature, METH_VARARGS,
"get the __signature__, but pass an optional string parameter"},
- {NULL, NULL}
+ {nullptr, nullptr}
};
static void
@@ -881,7 +864,26 @@ init_module_2(void)
}
static PyObject *
-PySide_BuildSignatureProps(PyObject *classmod)
+_address_to_stringlist(PyObject *numkey)
+{
+ ssize_t address = PyNumber_AsSsize_t(numkey, PyExc_ValueError);
+ if (address == -1 && PyErr_Occurred())
+ return nullptr;
+ char **sig_strings = reinterpret_cast<char **>(address);
+ PyObject *res_list = PyList_New(0);
+ if (res_list == nullptr)
+ return nullptr;
+ for (; *sig_strings != nullptr; ++sig_strings) {
+ char *sig_str = *sig_strings;
+ Shiboken::AutoDecRef pystr(Py_BuildValue("s", sig_str));
+ if (pystr.isNull() || PyList_Append(res_list, pystr) < 0)
+ return nullptr;
+ }
+ return res_list;
+}
+
+static PyObject *
+PySide_BuildSignatureProps(PyObject *type_key)
{
/*
* Here is the second part of the function.
@@ -890,13 +892,16 @@ PySide_BuildSignatureProps(PyObject *classmod)
* them by the function result.
*/
init_module_2();
- Shiboken::AutoDecRef type_key(GetClassKey(classmod));
- if (type_key.isNull())
+ if (type_key == nullptr)
+ return nullptr;
+ PyObject *numkey = PyDict_GetItem(pyside_globals->arg_dict, type_key);
+ Shiboken::AutoDecRef strings(_address_to_stringlist(numkey));
+ if (strings.isNull())
return nullptr;
- PyObject *arg_tup = PyDict_GetItem(pyside_globals->arg_dict, type_key);
- if (arg_tup == nullptr)
+ Shiboken::AutoDecRef arg_tup(Py_BuildValue("(OO)", type_key, strings.object()));
+ if (arg_tup.isNull())
return nullptr;
- PyObject *dict = PyObject_CallObject(pyside_globals->sigparse_func, arg_tup);
+ PyObject *dict = PyObject_CallObject(pyside_globals->pyside_type_init_func, arg_tup);
if (dict == nullptr) {
if (PyErr_Occurred())
return nullptr;
@@ -905,44 +910,27 @@ PySide_BuildSignatureProps(PyObject *classmod)
empty_dict = PyDict_New();
return empty_dict;
}
-
// We replace the arguments by the result dict.
if (PyDict_SetItem(pyside_globals->arg_dict, type_key, dict) < 0)
return nullptr;
return dict;
}
-int
-SbkSpecial_Type_Ready(PyObject *module, PyTypeObject *type,
- const char *signatures)
-{
- int ret;
- if (PyType_Ready(type) < 0)
- return -1;
- ret = PySide_BuildSignatureArgs(module, (PyObject *)type, signatures);
- if (ret < 0) {
- PyErr_Print();
- PyErr_SetNone(PyExc_ImportError);
- }
- return ret;
-}
-
static int _finish_nested_classes(PyObject *dict);
static int _build_func_to_type(PyObject *obtype);
static int
-PySide_FinishSignatures(PyObject *module, const char *signatures)
+PySide_FinishSignatures(PyObject *module, const char *signatures[])
{
/*
* Initialization of module functions and resolving of static methods.
*/
-
const char *name = PyModule_GetName(module);
- if (name == NULL)
+ if (name == nullptr)
return -1;
// we abuse the call for types, since they both have a __name__ attribute.
- if (PySide_BuildSignatureArgs(module, module, signatures) < 0)
+ if (PySide_BuildSignatureArgs(module, signatures) < 0)
return -1;
/*
@@ -972,7 +960,7 @@ _finish_nested_classes(PyObject *obdict)
PyTypeObject *subtype;
Py_ssize_t pos = 0;
- if (obdict == NULL)
+ if (obdict == nullptr)
return -1;
while (PyDict_Next(obdict, &pos, &key, &value)) {
if (PyType_Check(value)) {
@@ -1011,7 +999,7 @@ _build_func_to_type(PyObject *obtype)
if (meth == 0)
return 0;
- for (; meth->ml_name != NULL; meth++) {
+ for (; meth->ml_name != nullptr; meth++) {
/*
* It is possible that a method is overwritten by another
* attribute with the same name. This case was obviously provoked
@@ -1027,7 +1015,7 @@ _build_func_to_type(PyObject *obtype)
PyObject *descr = PyDict_GetItemString(dict, meth->ml_name);
const char *look_attr = meth->ml_flags & METH_STATIC ? "__func__" : "__name__";
int check_name = meth->ml_flags & METH_STATIC ? 0 : 1;
- if (descr == NULL)
+ if (descr == nullptr)
return -1;
// We first check all methods if one is hidden by something else.
@@ -1036,7 +1024,8 @@ _build_func_to_type(PyObject *obtype)
if (look.isNull()
|| (check_name && PyObject_RichCompareBool(look, given, Py_EQ) != 1)) {
PyErr_Clear();
- Shiboken::AutoDecRef cfunc(PyCFunction_NewEx(meth, (PyObject*)type, NULL));
+ Shiboken::AutoDecRef cfunc(PyCFunction_NewEx(meth,
+ reinterpret_cast<PyObject*>(type), nullptr));
if (cfunc.isNull())
return -1;
if (meth->ml_flags & METH_STATIC)
@@ -1069,8 +1058,23 @@ _build_func_to_type(PyObject *obtype)
return 0;
}
+int
+SbkSpecial_Type_Ready(PyObject *module, PyTypeObject *type,
+ const char *signatures[])
+{
+ if (PyType_Ready(type) < 0)
+ return -1;
+ PyObject *ob_type = reinterpret_cast<PyObject *>(type);
+ int ret = PySide_BuildSignatureArgs(ob_type, signatures);
+ if (ret < 0) {
+ PyErr_Print();
+ PyErr_SetNone(PyExc_ImportError);
+ }
+ return ret;
+}
+
void
-FinishSignatureInitialization(PyObject *module, const char *signatures)
+FinishSignatureInitialization(PyObject *module, const char *signatures[])
{
/*
* This function is called at the very end of a module initialization.
diff --git a/sources/shiboken2/libshiboken/signature.h b/sources/shiboken2/libshiboken/signature.h
index c850698a6..6b477c52e 100644
--- a/sources/shiboken2/libshiboken/signature.h
+++ b/sources/shiboken2/libshiboken/signature.h
@@ -45,8 +45,8 @@
extern "C"
{
-LIBSHIBOKEN_API int SbkSpecial_Type_Ready(PyObject *, PyTypeObject *, const char *); //WS
-LIBSHIBOKEN_API void FinishSignatureInitialization(PyObject *, const char *);
+LIBSHIBOKEN_API int SbkSpecial_Type_Ready(PyObject *, PyTypeObject *, const char *[]);
+LIBSHIBOKEN_API void FinishSignatureInitialization(PyObject *, const char *[]);
LIBSHIBOKEN_API void SetError_Argument(PyObject *, const char *);
} // extern "C"
diff --git a/sources/shiboken2/shibokenmodule/CMakeLists.txt b/sources/shiboken2/shibokenmodule/CMakeLists.txt
index 61c38c5d7..09731240f 100644
--- a/sources/shiboken2/shibokenmodule/CMakeLists.txt
+++ b/sources/shiboken2/shibokenmodule/CMakeLists.txt
@@ -3,14 +3,9 @@ project(shibokenmodule)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/shibokenmodule.txt.in"
"${CMAKE_CURRENT_BINARY_DIR}/shibokenmodule.txt" @ONLY)
+set(sample_SRC ${CMAKE_CURRENT_BINARY_DIR}/shiboken2/shiboken2_module_wrapper.cpp)
-set(sample_SRC
-${CMAKE_CURRENT_BINARY_DIR}/shiboken2/shiboken2_module_wrapper.cpp
-)
-
-set(shibokenmodule_TYPESYSTEM
-${CMAKE_CURRENT_SOURCE_DIR}/typesystem_shiboken.xml
-)
+set(shibokenmodule_TYPESYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_shiboken.xml)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
@@ -24,19 +19,16 @@ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Running generator for 'shiboken2'..."
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}
- ${libshiboken_SOURCE_DIR}
- ${libshiboken_BINARY_DIR})
add_library(shibokenmodule MODULE ${sample_SRC})
+target_include_directories(shibokenmodule PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR})
set_property(TARGET shibokenmodule PROPERTY PREFIX "")
set_property(TARGET shibokenmodule PROPERTY OUTPUT_NAME "shiboken2${PYTHON_EXTENSION_SUFFIX}")
if(WIN32)
set_property(TARGET shibokenmodule PROPERTY SUFFIX ".pyd")
endif()
-target_link_libraries(shibokenmodule
- libshiboken)
+target_link_libraries(shibokenmodule PUBLIC libshiboken)
add_dependencies(shibokenmodule shiboken2)
create_generator_target(shibokenmodule)
diff --git a/sources/shiboken2/shibokenmodule/__init__.py.in b/sources/shiboken2/shibokenmodule/__init__.py.in
index 066fd3584..ed6ce5623 100644
--- a/sources/shiboken2/shibokenmodule/__init__.py.in
+++ b/sources/shiboken2/shibokenmodule/__init__.py.in
@@ -3,7 +3,26 @@ __version_info__ = (@shiboken_MAJOR_VERSION@, @shiboken_MINOR_VERSION@, @shiboke
# PYSIDE-932: Python 2 cannot import 'zipfile' for embedding while being imported, itself.
# We simply pre-load all imports for the signature extension.
-import sys, zipfile, base64, marshal, io, contextlib
+# Also, PyInstaller seems not always to be reliable in finding modules.
+# We explicitly import everything that is needed:
+import sys
+import os
+import zipfile
+import base64
+import marshal
+import io
+import contextlib
+import textwrap
+import traceback
+import types
+import struct
+import re
+import tempfile
+import keyword
+import functools
+if sys.version_info[0] == 3:
+ # PyInstaller seems to sometimes fail:
+ import typing
from .shiboken2 import *
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
index a564aedb9..6c76483a0 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
@@ -119,7 +119,6 @@ from shibokensupport import signature
signature.get_signature = signature_bootstrap.get_signature
del signature_bootstrap
-
def _get_modname(mod):
return mod.__spec__.name if getattr(mod, "__spec__", None) else mod.__name__
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
index 9a8ee4c4e..306103304 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
@@ -418,6 +418,9 @@ def init_QtCore():
"PySide2.QtCore.quint32": int,
"PySide2.QtCore.quint64": int,
"PySide2.QtCore.quint8": int,
+ "PySide2.QtCore.short": int,
+ "PySide2.QtCore.unsigned short": int,
+ "PySide2.QtCore.signed char": Char,
"PySide2.QtCore.uchar": Char,
"PySide2.QtCore.unsigned char": Char, # 5.9
"PySide2.QtCore.long": int,
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
index 09e78f1b0..72ca35757 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
@@ -224,7 +224,6 @@ def _resolve_type(thing, line):
return _resolve_value(thing, None, line)
def calculate_props(line):
- line = line.strip()
res = _parse_line(line)
arglist = res["arglist"]
annotations = {}
@@ -257,8 +256,7 @@ def calculate_props(line):
props["multi"] = res["multi"]
return props
-def fixup_multilines(sig_str):
- lines = list(line.strip() for line in sig_str.strip().splitlines())
+def fixup_multilines(lines):
res = []
multi_lines = []
for line in lines:
@@ -282,15 +280,11 @@ def fixup_multilines(sig_str):
res.append(line)
return res
-def pyside_type_init(typemod, sig_str):
+def pyside_type_init(type_key, sig_strings):
dprint()
- if type(typemod) is types.ModuleType:
- dprint("Initialization of module '{}'".format(typemod.__name__))
- else:
- dprint("Initialization of type '{}.{}'".format(typemod.__module__,
- typemod.__name__))
+ dprint("Initialization of type key '{}'".format(type_key))
update_mapping()
- lines = fixup_multilines(sig_str)
+ lines = fixup_multilines(sig_strings)
ret = {}
multi_props = []
for line in lines:
diff --git a/sources/shiboken2/tests/CMakeLists.txt b/sources/shiboken2/tests/CMakeLists.txt
index c06c56f6d..085a4344c 100644
--- a/sources/shiboken2/tests/CMakeLists.txt
+++ b/sources/shiboken2/tests/CMakeLists.txt
@@ -1,6 +1,3 @@
-find_package(Qt5 REQUIRED COMPONENTS Core)
-include_directories(${Qt5Core_INCLUDE_DIRS})
-
add_subdirectory(libminimal)
if(NOT DEFINED MINIMAL_TESTS)
add_subdirectory(libsample)
diff --git a/sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt b/sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt
index af18cb3c8..7c6d60fe2 100644
--- a/sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt
+++ b/sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt
@@ -1,5 +1,6 @@
add_executable(dumpcodemodel main.cpp)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${apiextractor_SOURCE_DIR} ${Qt5Core_INCLUDE_DIRS})
+target_include_directories(dumpcodemodel
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${apiextractor_SOURCE_DIR})
-target_link_libraries(dumpcodemodel apiextractor ${Qt5Core_LIBRARIES})
+target_link_libraries(dumpcodemodel PUBLIC apiextractor Qt5::Core)
diff --git a/sources/shiboken2/tests/libminimal/CMakeLists.txt b/sources/shiboken2/tests/libminimal/CMakeLists.txt
index a25892571..f906bdb84 100644
--- a/sources/shiboken2/tests/libminimal/CMakeLists.txt
+++ b/sources/shiboken2/tests/libminimal/CMakeLists.txt
@@ -6,8 +6,8 @@ listuser.cpp
typedef.cpp
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-add_definitions("-DLIBMINIMAL_BUILD")
add_library(libminimal SHARED ${libminimal_SRC})
+target_include_directories(libminimal PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_compile_definitions(libminimal PRIVATE LIBMINIMAL_BUILD)
set_property(TARGET libminimal PROPERTY PREFIX "")
diff --git a/sources/shiboken2/tests/libother/CMakeLists.txt b/sources/shiboken2/tests/libother/CMakeLists.txt
index 9b3cf5552..6aba91e13 100644
--- a/sources/shiboken2/tests/libother/CMakeLists.txt
+++ b/sources/shiboken2/tests/libother/CMakeLists.txt
@@ -7,12 +7,10 @@ otherobjecttype.cpp
othermultiplederived.cpp
)
-add_definitions("-DLIBOTHER_BUILD")
add_library(libother SHARED ${libother_SRC})
+target_include_directories(libother PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_compile_definitions(libother PRIVATE LIBOTHER_BUILD)
+target_link_libraries(libother PUBLIC libsample)
set_property(TARGET libother PROPERTY PREFIX "")
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${libsample_SOURCE_DIR}
- ${libsample_SOURCE_DIR}/..)
-target_link_libraries(libother libsample)
diff --git a/sources/shiboken2/tests/libsample/CMakeLists.txt b/sources/shiboken2/tests/libsample/CMakeLists.txt
index ae3d40312..170829fbc 100644
--- a/sources/shiboken2/tests/libsample/CMakeLists.txt
+++ b/sources/shiboken2/tests/libsample/CMakeLists.txt
@@ -51,8 +51,8 @@ expression.cpp
filter.cpp
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-add_definitions("-DLIBSAMPLE_BUILD")
add_library(libsample SHARED ${libsample_SRC})
+target_include_directories(libsample PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_compile_definitions(libsample PRIVATE LIBSAMPLE_BUILD)
set_property(TARGET libsample PROPERTY PREFIX "")
diff --git a/sources/shiboken2/tests/libsmart/CMakeLists.txt b/sources/shiboken2/tests/libsmart/CMakeLists.txt
index 66c27cdae..152c57f25 100644
--- a/sources/shiboken2/tests/libsmart/CMakeLists.txt
+++ b/sources/shiboken2/tests/libsmart/CMakeLists.txt
@@ -4,8 +4,8 @@ set(libsmart_SRC
smart.cpp
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-add_definitions("-DLIBSMART_BUILD")
add_library(libsmart SHARED ${libsmart_SRC})
+target_include_directories(libsmart PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_compile_definitions(libsmart PRIVATE LIBSMART_BUILD)
set_property(TARGET libsmart PROPERTY PREFIX "")
diff --git a/sources/shiboken2/tests/minimalbinding/CMakeLists.txt b/sources/shiboken2/tests/minimalbinding/CMakeLists.txt
index 7301e1882..ffeb086a0 100644
--- a/sources/shiboken2/tests/minimalbinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/minimalbinding/CMakeLists.txt
@@ -24,18 +24,13 @@ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Running generator for 'minimal' test binding..."
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}
- ${libminimal_SOURCE_DIR}
- ${libshiboken_SOURCE_DIR}
- ${libshiboken_BINARY_DIR})
add_library(minimal MODULE ${minimal_SRC})
+target_include_directories(minimal PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries(minimal PUBLIC libminimal libshiboken)
set_property(TARGET minimal PROPERTY PREFIX "")
set_property(TARGET minimal PROPERTY OUTPUT_NAME "minimal${PYTHON_EXTENSION_SUFFIX}")
if(WIN32)
set_property(TARGET minimal PROPERTY SUFFIX ".pyd")
endif()
-target_link_libraries(minimal
- libminimal
- libshiboken)
+
create_generator_target(minimal)
diff --git a/sources/shiboken2/tests/minimalbinding/typesystem_minimal.xml b/sources/shiboken2/tests/minimalbinding/typesystem_minimal.xml
index 968b27c53..03b88a970 100644
--- a/sources/shiboken2/tests/minimalbinding/typesystem_minimal.xml
+++ b/sources/shiboken2/tests/minimalbinding/typesystem_minimal.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<typesystem package="minimal">
<primitive-type name="bool"/>
<primitive-type name="int"/>
diff --git a/sources/shiboken2/tests/otherbinding/CMakeLists.txt b/sources/shiboken2/tests/otherbinding/CMakeLists.txt
index 44855e297..bc5c4bdad 100644
--- a/sources/shiboken2/tests/otherbinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/otherbinding/CMakeLists.txt
@@ -26,26 +26,17 @@ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Running generator for 'other' test binding..."
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}
- ${libother_SOURCE_DIR}
- ${libsample_SOURCE_DIR}
- ${libsample_SOURCE_DIR}/..
- ${sample_BINARY_DIR}
- ${sample_BINARY_DIR}/sample
- ${libshiboken_SOURCE_DIR}
- ${libshiboken_BINARY_DIR})
add_library(other MODULE ${other_SRC})
+target_include_directories(other PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ ${sample_BINARY_DIR}/sample)
+target_link_libraries(other PUBLIC libother libsample libshiboken)
set_property(TARGET other PROPERTY PREFIX "")
set_property(TARGET other PROPERTY OUTPUT_NAME "other${PYTHON_EXTENSION_SUFFIX}")
if(WIN32)
set_property(TARGET other PROPERTY SUFFIX ".pyd")
endif()
-target_link_libraries(other
- libother
- libsample
- libshiboken)
+
add_dependencies(other sample)
create_generator_target(other)
diff --git a/sources/shiboken2/tests/otherbinding/typesystem_other.xml b/sources/shiboken2/tests/otherbinding/typesystem_other.xml
index 63ccdd518..2932dafb3 100644
--- a/sources/shiboken2/tests/otherbinding/typesystem_other.xml
+++ b/sources/shiboken2/tests/otherbinding/typesystem_other.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<typesystem package="other">
<load-typesystem name="typesystem_sample.xml" generate="no" />
diff --git a/sources/shiboken2/tests/samplebinding/CMakeLists.txt b/sources/shiboken2/tests/samplebinding/CMakeLists.txt
index 9ecbd98e6..61090d30e 100644
--- a/sources/shiboken2/tests/samplebinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/samplebinding/CMakeLists.txt
@@ -137,19 +137,14 @@ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Running generator for 'sample' test binding..."
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}
- ${libsample_SOURCE_DIR}
- ${libshiboken_SOURCE_DIR}
- ${libshiboken_BINARY_DIR})
add_library(sample MODULE ${sample_SRC})
+target_include_directories(sample PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries(sample PUBLIC libsample libshiboken)
set_property(TARGET sample PROPERTY PREFIX "")
set_property(TARGET sample PROPERTY OUTPUT_NAME "sample${PYTHON_EXTENSION_SUFFIX}")
if(WIN32)
set_property(TARGET sample PROPERTY SUFFIX ".pyd")
endif()
-target_link_libraries(sample
- libsample
- libshiboken)
+
create_generator_target(sample)
diff --git a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
index 78ceaab43..19b4948a1 100644
--- a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<typesystem package="sample">
<suppress-warning text="Duplicate type entry: 'sample'" />
<suppress-warning text="Duplicate type entry: 'SampleNamespace'" />
diff --git a/sources/shiboken2/tests/smartbinding/CMakeLists.txt b/sources/shiboken2/tests/smartbinding/CMakeLists.txt
index ed6bcef0a..88a7bc059 100644
--- a/sources/shiboken2/tests/smartbinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/smartbinding/CMakeLists.txt
@@ -27,19 +27,14 @@ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Running generator for 'smart' test binding..."
)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}
- ${libsmart_SOURCE_DIR}
- ${libshiboken_SOURCE_DIR}
- ${libshiboken_BINARY_DIR})
add_library(smart MODULE ${smart_SRC})
+target_include_directories(smart PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries(smart PUBLIC libsmart libshiboken)
set_property(TARGET smart PROPERTY PREFIX "")
set_property(TARGET smart PROPERTY OUTPUT_NAME "smart${PYTHON_EXTENSION_SUFFIX}")
if(WIN32)
set_property(TARGET smart PROPERTY SUFFIX ".pyd")
endif()
-target_link_libraries(smart
- libsmart
- libshiboken)
+
create_generator_target(smart)
diff --git a/sources/shiboken2/tests/smartbinding/typesystem_smart.xml b/sources/shiboken2/tests/smartbinding/typesystem_smart.xml
index aea1c2f73..0bb485957 100644
--- a/sources/shiboken2/tests/smartbinding/typesystem_smart.xml
+++ b/sources/shiboken2/tests/smartbinding/typesystem_smart.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<typesystem package="smart">
<primitive-type name="int" />
<primitive-type name="char" />
diff --git a/testing/wheel_tester.py b/testing/wheel_tester.py
index 60fd7a38a..a6ee2d463 100644
--- a/testing/wheel_tester.py
+++ b/testing/wheel_tester.py
@@ -1,6 +1,6 @@
#############################################################################
##
-## Copyright (C) 2018 The Qt Company Ltd.
+## Copyright (C) 2019 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of Qt for Python.
@@ -71,6 +71,7 @@ from build_scripts.utils import find_glob_in_path
from build_scripts.utils import run_process
from build_scripts.utils import rmtree
import distutils.log as log
+import platform
log.set_verbosity(1)
@@ -203,6 +204,25 @@ def generate_build_qmake():
log.info("")
+def compile_using_pyinstaller():
+ src_path = os.path.join("..", "hello.py")
+ spec_path = os.path.join("..", "hello_app.spec")
+ exit_code = run_process([sys.executable, "-m", "PyInstaller", spec_path])
+ # to create the spec file, this setting was used:
+ #"--name=hello_app", "--console", "--log-level=DEBUG", src_path])
+ # By using a spec file, we avoid all the probing that might disturb certain
+ # platforms and also save some analysis time.
+ if exit_code:
+ # raise RuntimeError("Failure while compiling script using PyInstaller.")
+ print("PYINST: Failure while compiling script using PyInstaller.")
+ print("PYINST: sys.version = {}".format(sys.version.splitlines()[0]))
+ print("PYINST: platform.platform() = {}".format(platform.platform()))
+ print("PYINST: See the error message above.")
+ return False
+ log.info("")
+ return True
+
+
def run_make():
args = []
if is_unix():
@@ -232,6 +252,14 @@ def run_make_install():
log.info("")
+def run_compiled_script(binary_path):
+ args = [binary_path]
+ exit_code = run_process(args)
+ if exit_code:
+ raise RuntimeError("Failure while executing compiled script: {}".format(binary_path))
+ log.info("")
+
+
def execute_script(script_path):
args = [sys.executable, script_path]
exit_code = run_process(args)
@@ -257,6 +285,20 @@ def prepare_build_folder(src_path, build_folder_name):
def try_build_examples():
examples_dir = get_examples_dir()
+ # This script should better go to the last place, here.
+ # But because it is most likely to break, we put it here for now.
+ log.info("Attempting to build hello.py using PyInstaller.")
+ # PyInstaller is loaded by coin_build_instructions.py, but not when
+ # testing directly this script.
+ src_path = os.path.join(examples_dir, "installer_test")
+ prepare_build_folder(src_path, "pyinstaller")
+
+ # Currently, there are bugs in the COIN setup.
+ # That is currently not the subject of this test:
+ if compile_using_pyinstaller():
+ run_compiled_script(os.path.join(src_path,
+ "pyinstaller", "dist", "hello_app", "hello_app"))
+
log.info("Attempting to build and run samplebinding using cmake.")
src_path = os.path.join(examples_dir, "samplebinding")
prepare_build_folder(src_path, "cmake")