From d5651c03ba398a97ff96e30759b3679c81feab56 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sat, 16 Apr 2022 15:51:41 +1200 Subject: Manual fixups for ImportErrors lost in rewrite Fixups for commit Qt import rewrite commit "Re-write PyQt references to always include the module" Imports not at the top of the file were mostly moved up there. Where they were inside a try/except block they were replaced with `pass` (why!). In a previous version of this commit it was based on a branch were we were doing things like: if module and module.attribute is not None: do_thing() elif hasattr(module, 'attribute'): do_thing() else: cant_do_thing() But on this branch we are doing it like: try: import module.attribute do_thing() except ImportError: cant_do_thing() They may have been some stuff that came over from the earlier version of this commit (1378c09aa5de) that hasn't been migrated over. I'll get back to it when I know what direction we are going with the qt wrapper. Because different approaches require different handling of this (for example if you just do import QtCore in the wrapper and then refer to stuff as QtCore.attribute in the code you won't get any ImportErrors) This has not currently been well tested. We might have to move some of the conditional checks into qt.py. I identified these pieces of code by looking for `^+ * pass$` in the diff of the big rewrite commit. --- qutebrowser/completion/models/histcategory.py | 4 ++-- qutebrowser/keyinput/keyutils.py | 19 ++++++++++--------- qutebrowser/misc/backendproblem.py | 5 ++--- qutebrowser/misc/earlyinit.py | 12 +++++++----- qutebrowser/utils/qtutils.py | 5 ++--- qutebrowser/utils/version.py | 25 ++++++++++++------------- tests/end2end/conftest.py | 6 +++--- tests/helpers/testutils.py | 7 ++----- tests/unit/browser/test_history.py | 5 ----- tests/unit/browser/test_notification.py | 2 +- tests/unit/completion/test_models.py | 4 ---- tests/unit/config/test_configfiles.py | 6 ++---- tests/unit/utils/test_version.py | 3 ++- 13 files changed, 45 insertions(+), 58 deletions(-) diff --git a/qutebrowser/completion/models/histcategory.py b/qutebrowser/completion/models/histcategory.py index 43befcbfc..f9d29247c 100644 --- a/qutebrowser/completion/models/histcategory.py +++ b/qutebrowser/completion/models/histcategory.py @@ -21,7 +21,7 @@ from typing import Optional -from qutebrowser.qt import widgets, sql +from qutebrowser.qt import widgets, sql as qtsql from qutebrowser.misc import sql from qutebrowser.utils import debug, message, log @@ -29,7 +29,7 @@ from qutebrowser.config import config from qutebrowser.completion.models import util -class HistoryCategory(sql.QSqlQueryModel): +class HistoryCategory(qtsql.QSqlQueryModel): """A completion category that queries the SQL history store.""" diff --git a/qutebrowser/keyinput/keyutils.py b/qutebrowser/keyinput/keyutils.py index 70898ceb2..8d4de6035 100644 --- a/qutebrowser/keyinput/keyutils.py +++ b/qutebrowser/keyinput/keyutils.py @@ -34,12 +34,13 @@ handle what we actually think we do. import itertools import dataclasses from typing import Iterator, List, Mapping, Optional, Union, overload -try: - from qutebrowser.qt import gui, core -except ImportError: - QKeyCombination = None # Qt 6 only from qutebrowser.utils import utils, qtutils, debug +from qutebrowser.qt import gui, core + +QKeyCombination = None # Qt 6 only +if hasattr(core, 'QKeyCombination'): + QKeyCombination = core.QKeyCombination class InvalidKeyError(Exception): @@ -377,7 +378,7 @@ class KeyInfo: return cls(key, modifiers) @classmethod - def from_qt(cls, combination: Union[int, core.QKeyCombination]) -> 'KeyInfo': + def from_qt(cls, combination: Union[int, QKeyCombination]) -> 'KeyInfo': """Construct a KeyInfo from a Qt5-style int or Qt6-style QKeyCombination.""" if isinstance(combination, int): key = core.Qt.Key( @@ -387,7 +388,7 @@ class KeyInfo: return cls(key, modifiers) else: # QKeyCombination is now guaranteed to be available here - assert isinstance(combination, core.QKeyCombination) + assert isinstance(combination, QKeyCombination) try: key = combination.key() except ValueError as e: @@ -458,9 +459,9 @@ class KeyInfo: """Get a QKeyEvent from this KeyInfo.""" return gui.QKeyEvent(typ, self.key, self.modifiers, self.text()) - def to_qt(self) -> Union[int, core.QKeyCombination]: + def to_qt(self) -> Union[int, QKeyCombination]: """Get something suitable for a QKeySequence.""" - if core.QKeyCombination is None: + if QKeyCombination is None: # Qt 5 return int(self.key) | int(self.modifiers) @@ -473,7 +474,7 @@ class KeyInfo: # https://www.riverbankcomputing.com/pipermail/pyqt/2022-April/044607.html raise InvalidKeyError(e) - return core.QKeyCombination(self.modifiers, key) + return QKeyCombination(self.modifiers, key) def with_stripped_modifiers(self, modifiers: core.Qt.KeyboardModifier) -> "KeyInfo": return KeyInfo(key=self.key, modifiers=self.modifiers & ~modifiers) diff --git a/qutebrowser/misc/backendproblem.py b/qutebrowser/misc/backendproblem.py index 40b15a9f5..c29cd970f 100644 --- a/qutebrowser/misc/backendproblem.py +++ b/qutebrowser/misc/backendproblem.py @@ -202,11 +202,10 @@ class _BackendProblemChecker: def _try_import_backends(self) -> _BackendImports: """Check whether backends can be imported and return BackendImports.""" - # pylint: disable=unused-import results = _BackendImports() try: - pass + from qutebrowser.qt import webkit, webkitwidgets except (ImportError, ValueError) as e: results.webkit_error = str(e) assert results.webkit_error @@ -215,7 +214,7 @@ class _BackendProblemChecker: results.webkit_error = "Unsupported legacy QtWebKit found" try: - pass + from qutebrowser.qt import webenginecore, webenginewidgets except (ImportError, ValueError) as e: results.webengine_error = str(e) assert results.webengine_error diff --git a/qutebrowser/misc/earlyinit.py b/qutebrowser/misc/earlyinit.py index 74c830dd9..9550f147f 100644 --- a/qutebrowser/misc/earlyinit.py +++ b/qutebrowser/misc/earlyinit.py @@ -78,7 +78,7 @@ def _die(message, exception=None): message: The message to display. exception: The exception object if we're handling an exception. """ - from qutebrowser.qt import widgets, network, core + from qutebrowser.qt import widgets, core if (('--debug' in sys.argv or '--no-err-windows' in sys.argv) and exception is not None): print(file=sys.stderr) @@ -163,6 +163,7 @@ def check_pyqt(): def qt_version(qversion=None, qt_version_str=None): """Get a Qt version string based on the runtime/compiled versions.""" + from qutebrowser.qt import core if qversion is None: qversion = core.qVersion() if qt_version_str is None: @@ -176,6 +177,7 @@ def qt_version(qversion=None, qt_version_str=None): def check_qt_version(): """Check if the Qt version is recent enough.""" + from qutebrowser.qt import core try: qt_ver = core.QLibraryInfo.version().normalized() recent_qt_runtime = qt_ver >= core.QVersionNumber(5, 15) # type: ignore[operator] @@ -197,9 +199,8 @@ def check_qt_version(): def check_ssl_support(): """Check if SSL support is available.""" - try: - pass - except ImportError: + from qutebrowser.qt import network + if not hasattr(network, 'QSslSocket'): _die("Fatal error: Your Qt is built without SSL support.") @@ -250,6 +251,7 @@ def configure_pyqt(): Doing this means we can't use the interactive shell anymore (which we don't anyways), but we can use pdb instead. """ + from qutebrowser.qt import core core.pyqtRemoveInputHook() from qutebrowser.qt import sip @@ -290,7 +292,7 @@ def webengine_early_import(): error messages in backendproblem.py are accurate. """ try: - pass + from qutebrowser.qt import webenginewidgets # pylint: disable=unused-import except ImportError: pass diff --git a/qutebrowser/utils/qtutils.py b/qutebrowser/utils/qtutils.py index 8d0e1bd62..2facbfaab 100644 --- a/qutebrowser/utils/qtutils.py +++ b/qutebrowser/utils/qtutils.py @@ -35,9 +35,8 @@ import operator import contextlib from typing import (Any, AnyStr, TYPE_CHECKING, BinaryIO, IO, Iterator, Optional, Union, Tuple, cast) -from qutebrowser.qt import webkit, webenginewidgets, gui try: - pass + from qutebrowser.qt.webkit import qWebKitVersion except ImportError: # pragma: no cover qWebKitVersion = None # type: ignore[assignment] # noqa: N816 if TYPE_CHECKING: @@ -46,7 +45,7 @@ if TYPE_CHECKING: from qutebrowser.misc import objects from qutebrowser.utils import usertypes, utils -from qutebrowser.qt import core +from qutebrowser.qt import core, gui MAXVALS = { diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index efd7fc68d..42215633e 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -36,15 +36,15 @@ import dataclasses from typing import (Mapping, Optional, Sequence, Tuple, ClassVar, Dict, cast, TYPE_CHECKING) -from qutebrowser.qt import opengl, widgets, webkit, webenginecore, network, gui, core, machinery +from qutebrowser.qt import opengl, widgets, network, gui, core, machinery try: - pass + from qutebrowser.qt.webkit import qWebKitVersion except ImportError: # pragma: no cover - qWebKitVersion = None # type: ignore[assignment] # noqa: N816 + qWebKitVersion = lambda: None # type: ignore[assignment] # noqa: N816 try: - pass -except ImportError: # pragma: no cover + from qutebrowser.qt.webenginecore import PYQT_WEBENGINE_VERSION_STR +except ImportError: # QtWebKit PYQT_WEBENGINE_VERSION_STR = None # type: ignore[assignment] @@ -774,11 +774,10 @@ def qtwebengine_versions(*, avoid_init: bool = False) -> WebEngineVersions: if override is not None: return WebEngineVersions.from_pyqt(override, source='override') - try: - pass - except ImportError: - pass # Needs QtWebEngine 6.2+ with PyQtWebEngine 6.3.1+ - else: + if hasattr(webenginecore, 'qWebEngineChromiumVersion') and hasattr( + webenginecore, 'qWebEngineVersion' + ): + # Needs QtWebEngine 6.2+ with PyQtWebEngine 6.3.1+ return WebEngineVersions.from_api( qtwe_version=webenginecore.qWebEngineVersion(), chromium_version=webenginecore.qWebEngineChromiumVersion(), @@ -801,14 +800,14 @@ def qtwebengine_versions(*, avoid_init: bool = False) -> WebEngineVersions: return WebEngineVersions.from_webengine( pyqt_webengine_qt_version, source='importlib') - assert webenginecore.PYQT_WEBENGINE_VERSION_STR is not None - return WebEngineVersions.from_pyqt(webenginecore.PYQT_WEBENGINE_VERSION_STR) + assert PYQT_WEBENGINE_VERSION_STR is not None + return WebEngineVersions.from_pyqt(PYQT_WEBENGINE_VERSION_STR) def _backend() -> str: """Get the backend line with relevant information.""" if objects.backend == usertypes.Backend.QtWebKit: - return 'new QtWebKit (WebKit {})'.format(webkit.qWebKitVersion()) + return 'new QtWebKit (WebKit {})'.format(qWebKitVersion()) elif objects.backend == usertypes.Backend.QtWebEngine: return str(qtwebengine_versions( avoid_init='avoid-chromium-init' in objects.debug_flags)) diff --git a/tests/end2end/conftest.py b/tests/end2end/conftest.py index 634c23480..8a4d56822 100644 --- a/tests/end2end/conftest.py +++ b/tests/end2end/conftest.py @@ -38,7 +38,7 @@ from end2end.fixtures.quteprocess import (quteproc_process, quteproc, from end2end.fixtures.testprocess import pytest_runtest_makereport # pylint: enable=unused-import from qutebrowser.utils import qtutils, utils -from qutebrowser.qt import webenginecore, core +from qutebrowser.qt import core def pytest_configure(config): @@ -119,12 +119,12 @@ def _get_version_tag(tag): ) elif package == 'pyqtwebengine': try: - pass + from qutebrowser.qt.webenginecore import PYQT_WEBENGINE_VERSION except ImportError: # QtWebKit running_version = core.PYQT_VERSION else: - running_version = webenginecore.PYQT_WEBENGINE_VERSION + running_version = PYQT_WEBENGINE_VERSION return pytest.mark.skipif( not _check_version( op_str=match.group('operator'), diff --git a/tests/helpers/testutils.py b/tests/helpers/testutils.py index fa98474e5..d9e7d9a92 100644 --- a/tests/helpers/testutils.py +++ b/tests/helpers/testutils.py @@ -32,7 +32,7 @@ import importlib.machinery import pytest -from qutebrowser.qt import gui +from qutebrowser.qt import gui, webenginecore from qutebrowser.utils import log, utils, version @@ -268,10 +268,7 @@ def disable_seccomp_bpf_sandbox(): This is needed for some QtWebEngine setups, with older Qt versions but newer kernels. """ - try: - pass - except ImportError: - # no QtWebEngine available + if not webenginecore: return False versions = version.qtwebengine_versions(avoid_init=True) diff --git a/tests/unit/browser/test_history.py b/tests/unit/browser/test_history.py index afa1acc62..4865c778c 100644 --- a/tests/unit/browser/test_history.py +++ b/tests/unit/browser/test_history.py @@ -320,11 +320,6 @@ class TestInit: history.init(data_tmpdir / f'test_init_{backend}', qapp) assert history.web_history.parent() is qapp - try: - pass - except ImportError: - QWebHistoryInterface = None - if backend == usertypes.Backend.QtWebKit: default_interface = webkit.QWebHistoryInterface.defaultInterface() assert default_interface._history is history.web_history diff --git a/tests/unit/browser/test_notification.py b/tests/unit/browser/test_notification.py index 6d0966cb9..2ae64a134 100644 --- a/tests/unit/browser/test_notification.py +++ b/tests/unit/browser/test_notification.py @@ -25,7 +25,7 @@ import inspect from typing import List, Dict, Any, Optional, TYPE_CHECKING import pytest -from qutebrowser.qt import webenginecore, gui +from qutebrowser.qt import gui pytest.importorskip("qutebrowser.qt.webenginecore") if TYPE_CHECKING: from qutebrowser.qt import QWebEngineNotification diff --git a/tests/unit/completion/test_models.py b/tests/unit/completion/test_models.py index 1a326c1df..79871487c 100644 --- a/tests/unit/completion/test_models.py +++ b/tests/unit/completion/test_models.py @@ -31,10 +31,6 @@ from unittest import mock import hypothesis import hypothesis.strategies as hst import pytest -try: - pass -except ImportError: - pass from qutebrowser.misc import objects, guiprocess from qutebrowser.completion import completer diff --git a/tests/unit/config/test_configfiles.py b/tests/unit/config/test_configfiles.py index c44614d90..9ba02c639 100644 --- a/tests/unit/config/test_configfiles.py +++ b/tests/unit/config/test_configfiles.py @@ -25,7 +25,7 @@ import textwrap import logging import pytest -from qutebrowser.qt import core +from qutebrowser.qt import core, webenginecore from qutebrowser.config import (config, configfiles, configexc, configdata, configtypes) @@ -186,9 +186,7 @@ def state_writer(data_tmpdir): @pytest.fixture def qtwe_version_patcher(monkeypatch): - try: - pass - except ImportError: + if not webenginecore: pytest.skip("QtWebEngine not available") def patch(ver, chromium_version=None): diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py index 1ab8c127c..b44a26359 100644 --- a/tests/unit/utils/test_version.py +++ b/tests/unit/utils/test_version.py @@ -1007,7 +1007,8 @@ class TestWebEngineVersions: pytest.skip("dev version of PyQt") try: - pass + from qutebrowser.qt.webenginecore import ( + PYQT_WEBENGINE_VERSION_STR, PYQT_WEBENGINE_VERSION) except ImportError as e: # QtWebKit pytest.skip(str(e)) -- cgit v1.2.3-54-g00ecf