aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2019-03-19 17:00:08 +0100
committerChristian Tismer <tismer@stackless.com>2019-04-08 13:55:43 +0000
commit728e94e37d44229d8f31dee4761eaf66f89bf01e (patch)
tree98b7c7a89bdb1e23b2f4863b6d80fdcc4061ae2c
parentafd4ee23124541c23fe58639f138ed7689cac562 (diff)
Automatically Test Small Example With PyInstaller
A simple hello.py script was modified for running in PyInstaller and stopping to execute after 2 seconds. The reason is to test that PyInstaller works correctly together with the embedded mode of the signature extension on all platforms. The script did first not work on Windows. This is now solved, after an import in pyside2_config.py is fixed. Currently, there are several configuration errors in COIN. Errors are therefore skipped in the PyInstaller build. The test tests only if the generated script works. Change-Id: I7a1b1e738d523b83cc3fe5beafa7e2579f9c7f48 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r--build_scripts/utils.py2
-rw-r--r--coin_test_instructions.py4
-rw-r--r--examples/examples.pyproject1
-rw-r--r--examples/installer_test/hello.py103
-rw-r--r--examples/utils/pyside2_config.py4
-rw-r--r--sources/shiboken2/shibokenmodule/__init__.py.in21
-rw-r--r--testing/wheel_tester.py41
7 files changed, 169 insertions, 7 deletions
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..f31c35e59 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.
@@ -68,7 +68,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",
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/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/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/testing/wheel_tester.py b/testing/wheel_tester.py
index 60fd7a38a..810ef0f56 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,22 @@ def generate_build_qmake():
log.info("")
+def compile_using_pyinstaller():
+ src_path = os.path.join("..", "hello.py")
+ exit_code = run_process([sys.executable, "-m", "PyInstaller",
+ "--name=hello_app", "--console", "--log-level=DEBUG",
+ src_path])
+ 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 +249,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 +282,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")