From 47a9c8e17caf8124172e1a2f9a7c536f375ae04f Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 28 Feb 2017 21:01:47 +0100 Subject: [PATCH] Also check compiled Qt version in version checks --- qutebrowser/config/configdata.py | 5 ++-- qutebrowser/misc/earlyinit.py | 11 +++++---- qutebrowser/utils/qtutils.py | 12 ++++++---- qutebrowser/utils/version.py | 15 +++++++----- tests/unit/utils/test_qtutils.py | 28 +++++++++++++++-------- tests/unit/utils/test_version.py | 39 ++++++++++++++++++++------------ 6 files changed, 69 insertions(+), 41 deletions(-) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 7673414b3..71a97a03d 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -200,8 +200,9 @@ def data(readonly=False): ('print-element-backgrounds', SettingValue(typ.Bool(), 'true', - backends=(None if qtutils.version_check('5.8') - else [usertypes.Backend.QtWebKit])), + backends=( + None if qtutils.version_check('5.8', strict=True) + else [usertypes.Backend.QtWebKit])), "Whether the background color and images are also drawn when the " "page is printed.\n" "This setting only works with Qt 5.8 or newer when using the " diff --git a/qutebrowser/misc/earlyinit.py b/qutebrowser/misc/earlyinit.py index 4e6406591..015efc1e4 100644 --- a/qutebrowser/misc/earlyinit.py +++ b/qutebrowser/misc/earlyinit.py @@ -263,18 +263,19 @@ def get_backend(args): def check_qt_version(backend): """Check if the Qt version is recent enough.""" from PyQt5.QtCore import qVersion, PYQT_VERSION, PYQT_VERSION_STR - from qutebrowser.utils import qtutils - if (qtutils.version_check('5.2.0', operator.lt) or + from qutebrowser.utils import qtutils, version + if (qtutils.version_check('5.2.0', operator.lt, strict=True) or PYQT_VERSION < 0x050200): text = ("Fatal error: Qt and PyQt >= 5.2.0 are required, but Qt {} / " - "PyQt {} is installed.".format(qVersion(), PYQT_VERSION_STR)) + "PyQt {} is installed.".format(version.qt_version(), + PYQT_VERSION_STR)) _die(text) elif (backend == 'webengine' and ( - qtutils.version_check('5.7.1', operator.lt) or + qtutils.version_check('5.7.1', operator.lt, strict=True) or PYQT_VERSION < 0x050700)): text = ("Fatal error: Qt >= 5.7.1 and PyQt >= 5.7 are required for " "QtWebEngine support, but Qt {} / PyQt {} is installed." - .format(qVersion(), PYQT_VERSION_STR)) + .format(version.qt_version(), PYQT_VERSION_STR)) _die(text) diff --git a/qutebrowser/utils/qtutils.py b/qutebrowser/utils/qtutils.py index 7266736f6..10c28a7ab 100644 --- a/qutebrowser/utils/qtutils.py +++ b/qutebrowser/utils/qtutils.py @@ -34,7 +34,7 @@ import operator import contextlib from PyQt5.QtCore import (qVersion, QEventLoop, QDataStream, QByteArray, - QIODevice, QSaveFile) + QIODevice, QSaveFile, QT_VERSION_STR) from PyQt5.QtWidgets import QApplication from qutebrowser.utils import log @@ -80,15 +80,19 @@ class QtOSError(OSError): self.qt_errno = None -def version_check(version, op=operator.ge): +def version_check(version, op=operator.ge, strict=False): """Check if the Qt runtime version is the version supplied or newer. Args: version: The version to check against. op: The operator to use for the check. + strict: If given, also check the compiled Qt version. """ - return op(pkg_resources.parse_version(qVersion()), - pkg_resources.parse_version(version)) + parsed = pkg_resources.parse_version(version) + result = op(pkg_resources.parse_version(qVersion()), parsed) + if result and strict: + result = op(pkg_resources.parse_version(QT_VERSION_STR), parsed) + return result def is_qtwebkit_ng(version): diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index 784c68cff..1aaf6c7c1 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -225,6 +225,14 @@ def _pdfjs_version(): return '{} ({})'.format(pdfjs_version, file_path) +def qt_version(): + """Get a Qt version string based on the runtime/compiled versions.""" + if qVersion() != QT_VERSION_STR: + return '{} (compiled {})'.format(qVersion(), QT_VERSION_STR) + else: + return qVersion() + + def version(): """Return a string with various version informations.""" lines = ["qutebrowser v{}".format(qutebrowser.__version__)] @@ -239,16 +247,11 @@ def version(): backend = 'QtWebKit-NG' lines.append("Backend: {}".format(backend)) - if qVersion() != QT_VERSION_STR: - qt_version = 'Qt: {} (compiled {})'.format(qVersion(), QT_VERSION_STR) - else: - qt_version = 'Qt: {}'.format(qVersion()) - lines += [ '', '{}: {}'.format(platform.python_implementation(), platform.python_version()), - qt_version, + 'Qt: {}'.format(qt_version()), 'PyQt: {}'.format(PYQT_VERSION_STR), '', ] diff --git a/tests/unit/utils/test_qtutils.py b/tests/unit/utils/test_qtutils.py index 4c991c707..2a40ca69b 100644 --- a/tests/unit/utils/test_qtutils.py +++ b/tests/unit/utils/test_qtutils.py @@ -42,26 +42,36 @@ from qutebrowser.utils import qtutils import overflow_test_cases -@pytest.mark.parametrize('qversion, version, op, expected', [ - ('5.4.0', '5.4.0', operator.ge, True), - ('5.4.0', '5.4.0', operator.eq, True), - ('5.4.0', '5.4', operator.eq, True), - ('5.4.1', '5.4', operator.ge, True), - ('5.3.2', '5.4', operator.ge, False), - ('5.3.0', '5.3.2', operator.ge, False), +@pytest.mark.parametrize('qversion, compiled, version, op, expected', [ + ('5.4.0', None, '5.4.0', operator.ge, True), + ('5.4.0', None, '5.4.0', operator.eq, True), + ('5.4.0', None, '5.4', operator.eq, True), + ('5.4.1', None, '5.4', operator.ge, True), + ('5.3.2', None, '5.4', operator.ge, False), + ('5.3.0', None, '5.3.2', operator.ge, False), + # strict=True + ('5.4.0', '5.3.0', '5.4.0', operator.ge, False), + ('5.4.0', '5.4.0', '5.4.0', operator.ge, True), ]) -def test_version_check(monkeypatch, qversion, version, op, expected): +def test_version_check(monkeypatch, qversion, compiled, version, op, expected): """Test for version_check(). Args: monkeypatch: The pytest monkeypatch fixture. qversion: The version to set as fake qVersion(). + compiled: The value for QT_VERSION_STR (set strict=True) version: The version to compare with. op: The operator to use when comparing. expected: The expected result. """ monkeypatch.setattr('qutebrowser.utils.qtutils.qVersion', lambda: qversion) - assert qtutils.version_check(version, op) == expected + if compiled is not None: + monkeypatch.setattr('qutebrowser.utils.qtutils.QT_VERSION_STR', compiled) + strict = True + else: + strict = False + + assert qtutils.version_check(version, op, strict=strict) == expected @pytest.mark.parametrize('version, ng', [ diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py index 7b821bba6..09b1b22df 100644 --- a/tests/unit/utils/test_version.py +++ b/tests/unit/utils/test_version.py @@ -638,18 +638,29 @@ class FakeQSslSocket: return self._version -@pytest.mark.parametrize(['git_commit', 'frozen', 'style', - 'equal_qt', 'with_webkit'], [ - (True, False, True, True, True), # normal - (False, False, True, True, True), # no git commit - (True, True, True, True, True), # frozen - (True, True, False, True, True), # no style - (True, False, True, False, True), # different Qt - (True, False, True, True, False), # no webkit - (True, False, True, True, 'ng'), # QtWebKit-NG +@pytest.mark.parametrize('same', [True, False]) +def test_qt_version(monkeypatch, same): + if same: + qt_version_str = '5.4.0' + expected = '5.4.0' + else: + qt_version_str = '5.3.0' + expected = '5.4.0 (compiled 5.3.0)' + monkeypatch.setattr(version, 'qVersion', lambda: '5.4.0') + monkeypatch.setattr(version, 'QT_VERSION_STR', qt_version_str) + assert version.qt_version() == expected + + +@pytest.mark.parametrize(['git_commit', 'frozen', 'style', 'with_webkit'], [ + (True, False, True, True), # normal + (False, False, True, True), # no git commit + (True, True, True, True), # frozen + (True, True, False, True), # no style + (True, False, True, False), # no webkit + (True, False, True, 'ng'), # QtWebKit-NG ]) -def test_version_output(git_commit, frozen, style, equal_qt, with_webkit, - stubs, monkeypatch): +def test_version_output(git_commit, frozen, style, with_webkit, stubs, + monkeypatch): """Test version.version().""" import_path = os.path.abspath('/IMPORTPATH') patches = { @@ -660,8 +671,7 @@ def test_version_output(git_commit, frozen, style, equal_qt, with_webkit, 'platform.python_version': lambda: 'PYTHON VERSION', 'PYQT_VERSION_STR': 'PYQT VERSION', 'QT_VERSION_STR': 'QT VERSION', - 'qVersion': (lambda: - 'QT VERSION' if equal_qt else 'QT RUNTIME VERSION'), + 'qVersion': lambda: 'QT VERSION', '_module_versions': lambda: ['MODULE VERSION 1', 'MODULE VERSION 2'], '_pdfjs_version': lambda: 'PDFJS VERSION', 'qWebKitVersion': (lambda: 'WEBKIT VERSION') if with_webkit else None, @@ -715,8 +725,7 @@ def test_version_output(git_commit, frozen, style, equal_qt, with_webkit, substitutions = { 'git_commit': '\nGit commit: GIT COMMIT' if git_commit else '', 'style': '\nStyle: STYLE' if style else '', - 'qt': ('QT VERSION' if equal_qt else - 'QT RUNTIME VERSION (compiled QT VERSION)'), + 'qt': 'QT VERSION', 'frozen': str(frozen), 'import_path': import_path, 'webkit': 'WEBKIT VERSION' if with_webkit else 'no',