From ef9301da92b902d379dea053f8a685a3654e64c1 Mon Sep 17 00:00:00 2001 From: qutebrowser bot Date: Mon, 13 Nov 2023 04:24:22 +0000 Subject: Update dependencies --- misc/requirements/requirements-dev.txt | 6 +++--- misc/requirements/requirements-flake8.txt | 4 ++-- misc/requirements/requirements-mypy.txt | 8 ++++---- misc/requirements/requirements-pyinstaller.txt | 2 +- misc/requirements/requirements-pylint.txt | 6 +++--- misc/requirements/requirements-pyqt-6.txt | 8 ++++---- misc/requirements/requirements-pyqt.txt | 8 ++++---- misc/requirements/requirements-pyroma.txt | 4 ++-- misc/requirements/requirements-sphinx.txt | 2 +- misc/requirements/requirements-tests.txt | 16 ++++++++-------- misc/requirements/requirements-tox.txt | 4 ++-- misc/requirements/requirements-yamllint.txt | 2 +- requirements.txt | 2 +- 13 files changed, 36 insertions(+), 36 deletions(-) diff --git a/misc/requirements/requirements-dev.txt b/misc/requirements/requirements-dev.txt index 3d6a7760a..fae3a3762 100644 --- a/misc/requirements/requirements-dev.txt +++ b/misc/requirements/requirements-dev.txt @@ -4,17 +4,17 @@ build==1.0.3 bump2version==1.0.1 certifi==2023.7.22 cffi==1.16.0 -charset-normalizer==3.3.1 +charset-normalizer==3.3.2 cryptography==41.0.5 docutils==0.20.1 github3.py==4.0.1 hunter==3.6.1 idna==3.4 importlib-metadata==6.8.0 -importlib-resources==6.1.0 +importlib-resources==6.1.1 jaraco.classes==3.3.0 jeepney==0.8.0 -keyring==24.2.0 +keyring==24.3.0 manhole==1.8.0 markdown-it-py==3.0.0 mdurl==0.1.2 diff --git a/misc/requirements/requirements-flake8.txt b/misc/requirements/requirements-flake8.txt index 95a9cb382..6995f7ac5 100644 --- a/misc/requirements/requirements-flake8.txt +++ b/misc/requirements/requirements-flake8.txt @@ -3,10 +3,10 @@ attrs==23.1.0 flake8==6.1.0 flake8-bugbear==23.9.16 -flake8-builtins==2.1.0 +flake8-builtins==2.2.0 flake8-comprehensions==3.14.0 flake8-debugger==4.1.2 -flake8-deprecated==2.1.0 +flake8-deprecated==2.2.1 flake8-docstrings==1.7.0 flake8-future-import==0.4.7 flake8-plugin-utils==1.3.3 diff --git a/misc/requirements/requirements-mypy.txt b/misc/requirements/requirements-mypy.txt index 8b5b68b56..497ac9b92 100644 --- a/misc/requirements/requirements-mypy.txt +++ b/misc/requirements/requirements-mypy.txt @@ -2,11 +2,11 @@ chardet==5.2.0 diff_cover==8.0.0 -importlib-resources==6.1.0 +importlib-resources==6.1.1 Jinja2==3.1.2 lxml==4.9.3 MarkupSafe==2.1.3 -mypy==1.6.1 +mypy==1.7.0 mypy-extensions==1.0.0 pluggy==1.3.0 Pygments==2.16.1 @@ -14,8 +14,8 @@ PyQt5-stubs==5.15.6.0 tomli==2.0.1 types-colorama==0.4.15.12 types-docutils==0.20.0.3 -types-Pygments==2.16.0.0 +types-Pygments==2.16.0.1 types-PyYAML==6.0.12.12 -types-setuptools==68.2.0.0 +types-setuptools==68.2.0.1 typing_extensions==4.8.0 zipp==3.17.0 diff --git a/misc/requirements/requirements-pyinstaller.txt b/misc/requirements/requirements-pyinstaller.txt index d62b99df5..d1a2c18c9 100644 --- a/misc/requirements/requirements-pyinstaller.txt +++ b/misc/requirements/requirements-pyinstaller.txt @@ -3,6 +3,6 @@ altgraph==0.17.4 importlib-metadata==6.8.0 packaging==23.2 -pyinstaller==6.1.0 +pyinstaller==6.2.0 pyinstaller-hooks-contrib==2023.10 zipp==3.17.0 diff --git a/misc/requirements/requirements-pylint.txt b/misc/requirements/requirements-pylint.txt index 6cdd658f8..38c227103 100644 --- a/misc/requirements/requirements-pylint.txt +++ b/misc/requirements/requirements-pylint.txt @@ -3,7 +3,7 @@ astroid==3.0.1 certifi==2023.7.22 cffi==1.16.0 -charset-normalizer==3.3.1 +charset-normalizer==3.3.2 cryptography==41.0.5 dill==0.3.7 github3.py==4.0.1 @@ -11,7 +11,7 @@ idna==3.4 isort==5.12.0 mccabe==0.7.0 pefile==2023.2.7 -platformdirs==3.11.0 +platformdirs==4.0.0 pycparser==2.21 PyJWT==2.8.0 pylint==3.0.2 @@ -20,7 +20,7 @@ python-dateutil==2.8.2 requests==2.31.0 six==1.16.0 tomli==2.0.1 -tomlkit==0.12.1 +tomlkit==0.12.2 typing_extensions==4.8.0 uritemplate==4.1.1 # urllib3==2.0.7 diff --git a/misc/requirements/requirements-pyqt-6.txt b/misc/requirements/requirements-pyqt-6.txt index 5dca9ab74..0a9c72e25 100644 --- a/misc/requirements/requirements-pyqt-6.txt +++ b/misc/requirements/requirements-pyqt-6.txt @@ -1,7 +1,7 @@ # This file is automatically generated by scripts/dev/recompile_requirements.py -PyQt6==6.5.3 -PyQt6-Qt6==6.5.3 +PyQt6==6.6.0 +PyQt6-Qt6==6.6.0 PyQt6-sip==13.6.0 -PyQt6-WebEngine==6.5.0 -PyQt6-WebEngine-Qt6==6.5.3 +PyQt6-WebEngine==6.6.0 +PyQt6-WebEngine-Qt6==6.6.0 diff --git a/misc/requirements/requirements-pyqt.txt b/misc/requirements/requirements-pyqt.txt index 5dca9ab74..0a9c72e25 100644 --- a/misc/requirements/requirements-pyqt.txt +++ b/misc/requirements/requirements-pyqt.txt @@ -1,7 +1,7 @@ # This file is automatically generated by scripts/dev/recompile_requirements.py -PyQt6==6.5.3 -PyQt6-Qt6==6.5.3 +PyQt6==6.6.0 +PyQt6-Qt6==6.6.0 PyQt6-sip==13.6.0 -PyQt6-WebEngine==6.5.0 -PyQt6-WebEngine-Qt6==6.5.3 +PyQt6-WebEngine==6.6.0 +PyQt6-WebEngine-Qt6==6.6.0 diff --git a/misc/requirements/requirements-pyroma.txt b/misc/requirements/requirements-pyroma.txt index c171b400e..576c5574f 100644 --- a/misc/requirements/requirements-pyroma.txt +++ b/misc/requirements/requirements-pyroma.txt @@ -2,7 +2,7 @@ build==1.0.3 certifi==2023.7.22 -charset-normalizer==3.3.1 +charset-normalizer==3.3.2 docutils==0.20.1 idna==3.4 importlib-metadata==6.8.0 @@ -12,6 +12,6 @@ pyproject_hooks==1.0.0 pyroma==4.2 requests==2.31.0 tomli==2.0.1 -trove-classifiers==2023.10.18 +trove-classifiers==2023.11.9 urllib3==2.0.7 zipp==3.17.0 diff --git a/misc/requirements/requirements-sphinx.txt b/misc/requirements/requirements-sphinx.txt index 77d982519..3d5011d12 100644 --- a/misc/requirements/requirements-sphinx.txt +++ b/misc/requirements/requirements-sphinx.txt @@ -3,7 +3,7 @@ alabaster==0.7.13 Babel==2.13.1 certifi==2023.7.22 -charset-normalizer==3.3.1 +charset-normalizer==3.3.2 docutils==0.20.1 idna==3.4 imagesize==1.4.1 diff --git a/misc/requirements/requirements-tests.txt b/misc/requirements/requirements-tests.txt index 49028afa4..168acac36 100644 --- a/misc/requirements/requirements-tests.txt +++ b/misc/requirements/requirements-tests.txt @@ -2,25 +2,25 @@ attrs==23.1.0 beautifulsoup4==4.12.2 -blinker==1.6.3 +blinker==1.7.0 certifi==2023.7.22 -charset-normalizer==3.3.1 +charset-normalizer==3.3.2 cheroot==10.0.0 click==8.1.7 coverage==7.3.2 exceptiongroup==1.1.3 execnet==2.0.2 -filelock==3.13.0 +filelock==3.13.1 Flask==3.0.0 hunter==3.6.1 -hypothesis==6.88.1 +hypothesis==6.88.3 idna==3.4 importlib-metadata==6.8.0 iniconfig==2.0.0 itsdangerous==2.1.2 -jaraco.functools==3.9.0 +jaraco.functools==4.0.0 # Jinja2==3.1.2 -Mako==1.2.4 +Mako==1.3.0 manhole==1.8.0 # MarkupSafe==2.1.3 more-itertools==10.1.0 @@ -39,7 +39,7 @@ pytest-mock==3.12.0 pytest-qt==4.2.0 pytest-repeat==0.9.3 pytest-rerunfailures==12.0 -pytest-xdist==3.3.1 +pytest-xdist==3.4.0 pytest-xvfb==3.0.0 PyVirtualDisplay==3.0 requests==2.31.0 @@ -47,7 +47,7 @@ requests-file==1.5.1 six==1.16.0 sortedcontainers==2.4.0 soupsieve==2.5 -tldextract==5.0.1 +tldextract==5.1.0 toml==0.10.2 tomli==2.0.1 typing_extensions==4.8.0 diff --git a/misc/requirements/requirements-tox.txt b/misc/requirements/requirements-tox.txt index b9a2c0508..0b1b5277d 100644 --- a/misc/requirements/requirements-tox.txt +++ b/misc/requirements/requirements-tox.txt @@ -4,7 +4,7 @@ cachetools==5.3.2 chardet==5.2.0 colorama==0.4.6 distlib==0.3.7 -filelock==3.13.0 +filelock==3.13.1 packaging==23.2 pip==23.3.1 platformdirs==3.11.0 @@ -14,4 +14,4 @@ setuptools==68.2.2 tomli==2.0.1 tox==4.11.3 virtualenv==20.24.6 -wheel==0.41.2 +wheel==0.41.3 diff --git a/misc/requirements/requirements-yamllint.txt b/misc/requirements/requirements-yamllint.txt index fd9ea256f..32589d26f 100644 --- a/misc/requirements/requirements-yamllint.txt +++ b/misc/requirements/requirements-yamllint.txt @@ -2,4 +2,4 @@ pathspec==0.11.2 PyYAML==6.0.1 -yamllint==1.32.0 +yamllint==1.33.0 diff --git a/requirements.txt b/requirements.txt index dc07bf531..9b8b4a905 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ adblock==0.6.0 colorama==0.4.6 -importlib-resources==6.1.0 ; python_version=="3.8.*" +importlib-resources==6.1.1 ; python_version=="3.8.*" Jinja2==3.1.2 MarkupSafe==2.1.3 Pygments==2.16.1 -- cgit v1.2.3-54-g00ecf From 9ebd28a10815176af5d4aada29a843dedd70a8a6 Mon Sep 17 00:00:00 2001 From: qutebrowser bot Date: Mon, 6 Nov 2023 04:24:33 +0000 Subject: Update dependencies --- misc/requirements/requirements-dev.txt | 2 +- misc/requirements/requirements-flake8.txt | 4 ++-- misc/requirements/requirements-pylint.txt | 4 ++-- misc/requirements/requirements-pyqt-6.txt | 8 ++++---- misc/requirements/requirements-pyqt.txt | 8 ++++---- misc/requirements/requirements-pyroma.txt | 2 +- misc/requirements/requirements-sphinx.txt | 2 +- misc/requirements/requirements-tests.txt | 10 +++++----- misc/requirements/requirements-tox.txt | 4 ++-- 9 files changed, 22 insertions(+), 22 deletions(-) diff --git a/misc/requirements/requirements-dev.txt b/misc/requirements/requirements-dev.txt index 3d6a7760a..0cb0e2acd 100644 --- a/misc/requirements/requirements-dev.txt +++ b/misc/requirements/requirements-dev.txt @@ -4,7 +4,7 @@ build==1.0.3 bump2version==1.0.1 certifi==2023.7.22 cffi==1.16.0 -charset-normalizer==3.3.1 +charset-normalizer==3.3.2 cryptography==41.0.5 docutils==0.20.1 github3.py==4.0.1 diff --git a/misc/requirements/requirements-flake8.txt b/misc/requirements/requirements-flake8.txt index 95a9cb382..6995f7ac5 100644 --- a/misc/requirements/requirements-flake8.txt +++ b/misc/requirements/requirements-flake8.txt @@ -3,10 +3,10 @@ attrs==23.1.0 flake8==6.1.0 flake8-bugbear==23.9.16 -flake8-builtins==2.1.0 +flake8-builtins==2.2.0 flake8-comprehensions==3.14.0 flake8-debugger==4.1.2 -flake8-deprecated==2.1.0 +flake8-deprecated==2.2.1 flake8-docstrings==1.7.0 flake8-future-import==0.4.7 flake8-plugin-utils==1.3.3 diff --git a/misc/requirements/requirements-pylint.txt b/misc/requirements/requirements-pylint.txt index 6cdd658f8..80e67d9d4 100644 --- a/misc/requirements/requirements-pylint.txt +++ b/misc/requirements/requirements-pylint.txt @@ -3,7 +3,7 @@ astroid==3.0.1 certifi==2023.7.22 cffi==1.16.0 -charset-normalizer==3.3.1 +charset-normalizer==3.3.2 cryptography==41.0.5 dill==0.3.7 github3.py==4.0.1 @@ -20,7 +20,7 @@ python-dateutil==2.8.2 requests==2.31.0 six==1.16.0 tomli==2.0.1 -tomlkit==0.12.1 +tomlkit==0.12.2 typing_extensions==4.8.0 uritemplate==4.1.1 # urllib3==2.0.7 diff --git a/misc/requirements/requirements-pyqt-6.txt b/misc/requirements/requirements-pyqt-6.txt index 5dca9ab74..0a9c72e25 100644 --- a/misc/requirements/requirements-pyqt-6.txt +++ b/misc/requirements/requirements-pyqt-6.txt @@ -1,7 +1,7 @@ # This file is automatically generated by scripts/dev/recompile_requirements.py -PyQt6==6.5.3 -PyQt6-Qt6==6.5.3 +PyQt6==6.6.0 +PyQt6-Qt6==6.6.0 PyQt6-sip==13.6.0 -PyQt6-WebEngine==6.5.0 -PyQt6-WebEngine-Qt6==6.5.3 +PyQt6-WebEngine==6.6.0 +PyQt6-WebEngine-Qt6==6.6.0 diff --git a/misc/requirements/requirements-pyqt.txt b/misc/requirements/requirements-pyqt.txt index 5dca9ab74..0a9c72e25 100644 --- a/misc/requirements/requirements-pyqt.txt +++ b/misc/requirements/requirements-pyqt.txt @@ -1,7 +1,7 @@ # This file is automatically generated by scripts/dev/recompile_requirements.py -PyQt6==6.5.3 -PyQt6-Qt6==6.5.3 +PyQt6==6.6.0 +PyQt6-Qt6==6.6.0 PyQt6-sip==13.6.0 -PyQt6-WebEngine==6.5.0 -PyQt6-WebEngine-Qt6==6.5.3 +PyQt6-WebEngine==6.6.0 +PyQt6-WebEngine-Qt6==6.6.0 diff --git a/misc/requirements/requirements-pyroma.txt b/misc/requirements/requirements-pyroma.txt index c171b400e..1291f5e9d 100644 --- a/misc/requirements/requirements-pyroma.txt +++ b/misc/requirements/requirements-pyroma.txt @@ -2,7 +2,7 @@ build==1.0.3 certifi==2023.7.22 -charset-normalizer==3.3.1 +charset-normalizer==3.3.2 docutils==0.20.1 idna==3.4 importlib-metadata==6.8.0 diff --git a/misc/requirements/requirements-sphinx.txt b/misc/requirements/requirements-sphinx.txt index 77d982519..3d5011d12 100644 --- a/misc/requirements/requirements-sphinx.txt +++ b/misc/requirements/requirements-sphinx.txt @@ -3,7 +3,7 @@ alabaster==0.7.13 Babel==2.13.1 certifi==2023.7.22 -charset-normalizer==3.3.1 +charset-normalizer==3.3.2 docutils==0.20.1 idna==3.4 imagesize==1.4.1 diff --git a/misc/requirements/requirements-tests.txt b/misc/requirements/requirements-tests.txt index 49028afa4..9b93e3974 100644 --- a/misc/requirements/requirements-tests.txt +++ b/misc/requirements/requirements-tests.txt @@ -2,23 +2,23 @@ attrs==23.1.0 beautifulsoup4==4.12.2 -blinker==1.6.3 +blinker==1.7.0 certifi==2023.7.22 -charset-normalizer==3.3.1 +charset-normalizer==3.3.2 cheroot==10.0.0 click==8.1.7 coverage==7.3.2 exceptiongroup==1.1.3 execnet==2.0.2 -filelock==3.13.0 +filelock==3.13.1 Flask==3.0.0 hunter==3.6.1 -hypothesis==6.88.1 +hypothesis==6.88.3 idna==3.4 importlib-metadata==6.8.0 iniconfig==2.0.0 itsdangerous==2.1.2 -jaraco.functools==3.9.0 +jaraco.functools==4.0.0 # Jinja2==3.1.2 Mako==1.2.4 manhole==1.8.0 diff --git a/misc/requirements/requirements-tox.txt b/misc/requirements/requirements-tox.txt index b9a2c0508..0b1b5277d 100644 --- a/misc/requirements/requirements-tox.txt +++ b/misc/requirements/requirements-tox.txt @@ -4,7 +4,7 @@ cachetools==5.3.2 chardet==5.2.0 colorama==0.4.6 distlib==0.3.7 -filelock==3.13.0 +filelock==3.13.1 packaging==23.2 pip==23.3.1 platformdirs==3.11.0 @@ -14,4 +14,4 @@ setuptools==68.2.2 tomli==2.0.1 tox==4.11.3 virtualenv==20.24.6 -wheel==0.41.2 +wheel==0.41.3 -- cgit v1.2.3-54-g00ecf From cedef129f98a01ec7bd0443ca38c8730d3a4491a Mon Sep 17 00:00:00 2001 From: toofar Date: Sun, 12 Nov 2023 11:15:20 +1300 Subject: Change browsertab WidgetType to be our tab implementations Changing the type to be our overridden implementation of the view means we can push more common code down into the view class and make use of overridden methods more consistently. In this case I'm adding some type checking to some of the getters on the view. `_set_widget()` should be being called from the concrete child tab implementations. So the widget should always be our overridden version of the Qt tab implementations. Also change `_set_widget()` to use the common typevar. Also change the _widget type in WebEngineTab to match what it is actually being set to and to match all the _widgets in the other concrete classes in that file. ref: https://github.com/qutebrowser/qutebrowser/pull/7990 --- qutebrowser/browser/browsertab.py | 13 +++++++------ qutebrowser/browser/webengine/webenginetab.py | 5 ++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index 1312275dc..4d14c9cd7 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: GPL-3.0-or-later -"""Base class for a wrapper over QWebView/QWebEngineView.""" +"""Base class for a wrapper over WebView/WebEngineView.""" import enum import pathlib @@ -22,10 +22,9 @@ from qutebrowser.qt.network import QNetworkAccessManager if TYPE_CHECKING: from qutebrowser.qt.webkit import QWebHistory, QWebHistoryItem - from qutebrowser.qt.webkitwidgets import QWebPage, QWebView + from qutebrowser.qt.webkitwidgets import QWebPage from qutebrowser.qt.webenginecore import ( QWebEngineHistory, QWebEngineHistoryItem, QWebEnginePage) - from qutebrowser.qt.webenginewidgets import QWebEngineView from qutebrowser.keyinput import modeman from qutebrowser.config import config, websettings @@ -38,10 +37,12 @@ from qutebrowser.qt import sip if TYPE_CHECKING: from qutebrowser.browser import webelem from qutebrowser.browser.inspector import AbstractWebInspector + from qutebrowser.browser.webengine.webview import WebEngineView + from qutebrowser.browser.webkit.webview import WebView tab_id_gen = itertools.count(0) -_WidgetType = Union["QWebView", "QWebEngineView"] +_WidgetType = Union["WebView", "WebEngineView"] def create(win_id: int, @@ -964,7 +965,7 @@ class AbstractTabPrivate: class AbstractTab(QWidget): - """An adapter for QWebView/QWebEngineView representing a single tab.""" + """An adapter for WebView/WebEngineView representing a single tab.""" #: Signal emitted when a website requests to close this tab. window_close_requested = pyqtSignal() @@ -1058,7 +1059,7 @@ class AbstractTab(QWidget): self.before_load_started.connect(self._on_before_load_started) - def _set_widget(self, widget: Union["QWebView", "QWebEngineView"]) -> None: + def _set_widget(self, widget: _WidgetType) -> None: # pylint: disable=protected-access self._widget = widget # FIXME:v4 ignore needed for QtWebKit diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index 9f1d04b63..1c712db5e 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: GPL-3.0-or-later -"""Wrapper over a QWebEngineView.""" +"""Wrapper over a WebEngineView.""" import math import struct @@ -15,7 +15,6 @@ from typing import cast, Union, Optional from qutebrowser.qt.core import (pyqtSignal, pyqtSlot, Qt, QPoint, QPointF, QTimer, QUrl, QObject, QByteArray) from qutebrowser.qt.network import QAuthenticator -from qutebrowser.qt.webenginewidgets import QWebEngineView from qutebrowser.qt.webenginecore import QWebEnginePage, QWebEngineScript, QWebEngineHistory from qutebrowser.config import config @@ -1267,7 +1266,7 @@ class WebEngineTab(browsertab.AbstractTab): abort_questions = pyqtSignal() - _widget: QWebEngineView + _widget: webview.WebEngineView search: WebEngineSearch audio: WebEngineAudio printing: WebEnginePrinting -- cgit v1.2.3-54-g00ecf From ca2b6c93ea16b4a204e4c8859524614ecbe0145e Mon Sep 17 00:00:00 2001 From: toofar Date: Sun, 12 Nov 2023 11:58:13 +1300 Subject: Override getters for some WebEngineView attributes With PyQt6-WebEngine 6.6.0 some pointer return types are now wrapped in Optionals[]. In practice they should never be none though. So in a low effort way of keeping the types we have to deal with in the calling code to what they were before I'm overriding these getters that just do `assert thing not None` to tell mypy not to worry about that case. QWebEngineView.page() The docs don't say anything but the source says it should always return something: https://github.com/qt/qtwebengine/blob/6.6.0/src/webenginewidgets/api/qwebengineview.cpp#L1001 QWebEngineView.history() calls QWebEnginePage.history() where it is always set in the constructor: https://github.com/qt/qtwebengine/blob/6.6.0/src/core/api/qwebenginepage.cpp#L90 QWebEngineView.settings() calls QWebEnginePage.settings() where it is always set in the constructor: https://github.com/qt/qtwebengine/blob/6.6.0/src/core/api/qwebenginepage.cpp#L90 ref: https://github.com/qutebrowser/qutebrowser/pull/7990 --- qutebrowser/browser/webengine/webview.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/qutebrowser/browser/webengine/webview.py b/qutebrowser/browser/webengine/webview.py index 3c63c59e4..d6c90cb46 100644 --- a/qutebrowser/browser/webengine/webview.py +++ b/qutebrowser/browser/webengine/webview.py @@ -11,7 +11,10 @@ from qutebrowser.qt import machinery from qutebrowser.qt.core import pyqtSignal, pyqtSlot, QUrl from qutebrowser.qt.gui import QPalette from qutebrowser.qt.webenginewidgets import QWebEngineView -from qutebrowser.qt.webenginecore import QWebEnginePage, QWebEngineCertificateError +from qutebrowser.qt.webenginecore import ( + QWebEnginePage, QWebEngineCertificateError, QWebEngineSettings, + QWebEngineHistory, +) from qutebrowser.browser import shared from qutebrowser.browser.webengine import webenginesettings, certificateerror @@ -129,6 +132,25 @@ class WebEngineView(QWebEngineView): return super().contextMenuEvent(ev) + def page(self) -> "WebEnginePage": + """Return the page for this view.""" + maybe_page = super().page() + assert maybe_page is not None + assert isinstance(maybe_page, WebEnginePage) + return maybe_page + + def settings(self) -> "QWebEngineSettings": + """Return the settings for this view.""" + maybe_settings = super().settings() + assert maybe_settings is not None + return maybe_settings + + def history(self) -> "QWebEngineHistory": + """Return the history for this view.""" + maybe_history = super().history() + assert maybe_history is not None + return maybe_history + def extra_suffixes_workaround(upstream_mimetypes): """Return any extra suffixes for mimetypes in upstream_mimetypes. -- cgit v1.2.3-54-g00ecf From 88f165fd771daca404b8efc44106999602cbddcb Mon Sep 17 00:00:00 2001 From: toofar Date: Sun, 12 Nov 2023 12:17:35 +1300 Subject: Handle Optional page getters in webengineinspector With PyQt6-WebEngine 6.6.0 some pointer return types are now wrapped in Optionals[]. In practice they should never be none though so I'm sprinkling some low effort null checking in here. Another alternative is to move the inspector classes to be based off, and to work with, our overridden child classes of the view and page. But that's a whole other piece of work, we might have to deal with signals and such meant for web views that we don't want with the inspector. (On the other hand it might actually be good. The inspector sometimes is surprising in how it acts differently from the main views.) There's a bit later on where I changed a local variable name from `inspector_page` to `new_page`. The `inspector_page` variable is used later and the type checker was complaining. ref: https://github.com/qutebrowser/qutebrowser/pull/7990 --- qutebrowser/browser/webengine/webengineinspector.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/qutebrowser/browser/webengine/webengineinspector.py b/qutebrowser/browser/webengine/webengineinspector.py index 64ef24319..d37f41ba5 100644 --- a/qutebrowser/browser/webengine/webengineinspector.py +++ b/qutebrowser/browser/webengine/webengineinspector.py @@ -35,14 +35,19 @@ class WebEngineInspectorView(QWebEngineView): See WebEngineView.createWindow for details. """ - inspected_page = self.page().inspectedPage() + our_page = self.page() + assert our_page is not None + inspected_page = our_page.inspectedPage() + assert inspected_page is not None if machinery.IS_QT5: view = inspected_page.view() assert isinstance(view, QWebEngineView), view return view.createWindow(wintype) else: # Qt 6 newpage = inspected_page.createWindow(wintype) - return webview.WebEngineView.forPage(newpage) + ret = webview.WebEngineView.forPage(newpage) + assert ret is not None + return ret class WebEngineInspector(inspector.AbstractWebInspector): @@ -88,16 +93,17 @@ class WebEngineInspector(inspector.AbstractWebInspector): def inspect(self, page: QWebEnginePage) -> None: if not self._widget: view = WebEngineInspectorView() - inspector_page = QWebEnginePage( + new_page = QWebEnginePage( page.profile(), self ) - inspector_page.windowCloseRequested.connect(self._on_window_close_requested) - view.setPage(inspector_page) + new_page.windowCloseRequested.connect(self._on_window_close_requested) + view.setPage(new_page) self._settings = webenginesettings.WebEngineSettings(view.settings()) self._set_widget(view) inspector_page = self._widget.page() + assert inspector_page is not None assert inspector_page.profile() == page.profile() inspector_page.setInspectedPage(page) -- cgit v1.2.3-54-g00ecf From 54e3993a59e862d8d6776ed6f6dbc0eb86c2ce67 Mon Sep 17 00:00:00 2001 From: toofar Date: Sun, 12 Nov 2023 12:26:02 +1300 Subject: Adapt chooseFiles() for PyQt6 type hints The type of the two list arguments of chooseFiles() have changed from `Iterable[str]` to `Iterable[Optional[str]]`. I'm not sure it makes much sense to have individual list elements as None. That seems like a pretty unlikely case. So we could just put an ignore comment somewhere. I've added another copy of the lists, with longer names, to strip any hypothetical Nones out. This allows us to be backwards compatible with the old type hints (and the current Qt5 ones), since that doesn't have the Optional part in the signature. ref: https://github.com/qutebrowser/qutebrowser/pull/7990 --- qutebrowser/browser/webengine/webview.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/qutebrowser/browser/webengine/webview.py b/qutebrowser/browser/webengine/webview.py index d6c90cb46..a6f2ae113 100644 --- a/qutebrowser/browser/webengine/webview.py +++ b/qutebrowser/browser/webengine/webview.py @@ -5,7 +5,7 @@ """The main browser widget for QtWebEngine.""" import mimetypes -from typing import List, Iterable +from typing import List, Iterable, Optional from qutebrowser.qt import machinery from qutebrowser.qt.core import pyqtSignal, pyqtSlot, QUrl @@ -316,22 +316,28 @@ class WebEnginePage(QWebEnginePage): def chooseFiles( self, mode: QWebEnginePage.FileSelectionMode, - old_files: Iterable[str], - accepted_mimetypes: Iterable[str], + old_files: Iterable[Optional[str]], + accepted_mimetypes: Iterable[Optional[str]], ) -> List[str]: """Override chooseFiles to (optionally) invoke custom file uploader.""" - extra_suffixes = extra_suffixes_workaround(accepted_mimetypes) + accepted_mimetypes_filtered = [m for m in accepted_mimetypes if m is not None] + old_files_filtered = [f for f in old_files if f is not None] + extra_suffixes = extra_suffixes_workaround(accepted_mimetypes_filtered) if extra_suffixes: log.webview.debug( "adding extra suffixes to filepicker: " - f"before={accepted_mimetypes} " + f"before={accepted_mimetypes_filtered} " f"added={extra_suffixes}", ) - accepted_mimetypes = list(accepted_mimetypes) + list(extra_suffixes) + accepted_mimetypes_filtered = list( + accepted_mimetypes_filtered + ) + list(extra_suffixes) handler = config.val.fileselect.handler if handler == "default": - return super().chooseFiles(mode, old_files, accepted_mimetypes) + return super().chooseFiles( + mode, old_files_filtered, accepted_mimetypes_filtered, + ) assert handler == "external", handler try: qb_mode = _QB_FILESELECTION_MODES[mode] @@ -339,6 +345,8 @@ class WebEnginePage(QWebEnginePage): log.webview.warning( f"Got file selection mode {mode}, but we don't support that!" ) - return super().chooseFiles(mode, old_files, accepted_mimetypes) + return super().chooseFiles( + mode, old_files_filtered, accepted_mimetypes_filtered, + ) return shared.choose_file(qb_mode=qb_mode) -- cgit v1.2.3-54-g00ecf From 399c72a9fb58d204357b39da8c1191dd002dfb55 Mon Sep 17 00:00:00 2001 From: toofar Date: Sun, 12 Nov 2023 12:52:10 +1300 Subject: Handle profile.settings() return type being optional With PyQt6-WebEngine 6.6.0 some pointer return types are now wrapped in Optionals[]. In practice they should never be none though so I'm adding some low effort null checking in here. For the changes in `_SettingsWrapper` I'm not actually sure this is the best way to be resolving this. mypy was complaining that `settings()` might be None. How does asserting on the profile help? idk but that seems to make it happy. Even more weirdly, none of these getters I changed seemed to be used anywhere apart from tests. Except for getAttribute, that's used in webkit code. Also the whole thing is checking the global default profile, generally settings should be checked on the profile on the tab. So I think this might just be some old code? idk, I just want to make mypy happy. For the `init_user_agent()` change that was complaining about the profile maybe being None. ref: https://github.com/qutebrowser/qutebrowser/pull/7990 --- qutebrowser/browser/webengine/webenginesettings.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/qutebrowser/browser/webengine/webenginesettings.py b/qutebrowser/browser/webengine/webenginesettings.py index d0b6b5beb..f84ac7ba2 100644 --- a/qutebrowser/browser/webengine/webenginesettings.py +++ b/qutebrowser/browser/webengine/webenginesettings.py @@ -50,8 +50,12 @@ class _SettingsWrapper: For read operations, the default profile value is always used. """ + def default_profile(self): + assert default_profile is not None + return default_profile + def _settings(self): - yield default_profile.settings() + yield self.default_profile().settings() if private_profile: yield private_profile.settings() @@ -76,19 +80,19 @@ class _SettingsWrapper: settings.setUnknownUrlSchemePolicy(policy) def testAttribute(self, attribute): - return default_profile.settings().testAttribute(attribute) + return self.default_profile().settings().testAttribute(attribute) def fontSize(self, fonttype): - return default_profile.settings().fontSize(fonttype) + return self.default_profile().settings().fontSize(fonttype) def fontFamily(self, which): - return default_profile.settings().fontFamily(which) + return self.default_profile().settings().fontFamily(which) def defaultTextEncoding(self): - return default_profile.settings().defaultTextEncoding() + return self.default_profile().settings().defaultTextEncoding() def unknownUrlSchemePolicy(self): - return default_profile.settings().unknownUrlSchemePolicy() + return self.default_profile().settings().unknownUrlSchemePolicy() class WebEngineSettings(websettings.AbstractSettings): @@ -341,7 +345,10 @@ def _init_user_agent_str(ua): def init_user_agent(): - _init_user_agent_str(QWebEngineProfile.defaultProfile().httpUserAgent()) + """Make the default WebEngine user agent available via parsed_user_agent.""" + actual_default_profile = QWebEngineProfile.defaultProfile() + assert actual_default_profile is not None + _init_user_agent_str(actual_default_profile.httpUserAgent()) def _init_profile(profile: QWebEngineProfile) -> None: -- cgit v1.2.3-54-g00ecf From f83cf4f5044d606b3dc92fe818879083e20542ed Mon Sep 17 00:00:00 2001 From: toofar Date: Sun, 12 Nov 2023 12:56:54 +1300 Subject: Handle PyQt WebEngine version strings being Optional With PyQt6-WebEngine 6.6.0 some pointer return types are now wrapped in Optionals[]. In practice they should never be None, we've been relying on them being set for long enough. `qWebEngineVersion()` and `qWebEngineChromiumVersion()` now are typed as returning `Optional[str]`. In `from_api()` we can handle the `chromium_version` being null, so pass that through, but we are depending on the `qtwe_version` being set, so add an assert there. ref: https://github.com/qutebrowser/qutebrowser/pull/7990 --- qutebrowser/utils/version.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index 75df73ffa..a139d01c5 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -686,7 +686,7 @@ class WebEngineVersions: return cls._CHROMIUM_VERSIONS.get(minor_version) @classmethod - def from_api(cls, qtwe_version: str, chromium_version: str) -> 'WebEngineVersions': + def from_api(cls, qtwe_version: str, chromium_version: Optional[str]) -> 'WebEngineVersions': """Get the versions based on the exact versions. This is called if we have proper APIs to get the versions easily @@ -796,8 +796,10 @@ def qtwebengine_versions(*, avoid_init: bool = False) -> WebEngineVersions: except ImportError: pass # Needs QtWebEngine 6.2+ with PyQtWebEngine 6.3.1+ else: + qtwe_version = qWebEngineVersion() + assert qtwe_version is not None return WebEngineVersions.from_api( - qtwe_version=qWebEngineVersion(), + qtwe_version=qtwe_version, chromium_version=qWebEngineChromiumVersion(), ) -- cgit v1.2.3-54-g00ecf From bb9788f80f2a58c1140e7c9b6f06e40b531c06b5 Mon Sep 17 00:00:00 2001 From: toofar Date: Sun, 12 Nov 2023 13:19:12 +1300 Subject: add pyqt6.6 requirements file What is that big chain of !pyqt- etc mean? idk ref: https://github.com/qutebrowser/qutebrowser/pull/7990 --- misc/requirements/requirements-pyqt-6.6.txt | 7 +++++++ misc/requirements/requirements-pyqt-6.6.txt-raw | 4 ++++ tox.ini | 3 ++- 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 misc/requirements/requirements-pyqt-6.6.txt create mode 100644 misc/requirements/requirements-pyqt-6.6.txt-raw diff --git a/misc/requirements/requirements-pyqt-6.6.txt b/misc/requirements/requirements-pyqt-6.6.txt new file mode 100644 index 000000000..0a9c72e25 --- /dev/null +++ b/misc/requirements/requirements-pyqt-6.6.txt @@ -0,0 +1,7 @@ +# This file is automatically generated by scripts/dev/recompile_requirements.py + +PyQt6==6.6.0 +PyQt6-Qt6==6.6.0 +PyQt6-sip==13.6.0 +PyQt6-WebEngine==6.6.0 +PyQt6-WebEngine-Qt6==6.6.0 diff --git a/misc/requirements/requirements-pyqt-6.6.txt-raw b/misc/requirements/requirements-pyqt-6.6.txt-raw new file mode 100644 index 000000000..7cfe6d34c --- /dev/null +++ b/misc/requirements/requirements-pyqt-6.6.txt-raw @@ -0,0 +1,4 @@ +PyQt6 >= 6.6, < 6.7 +PyQt6-Qt6 >= 6.6, < 6.7 +PyQt6-WebEngine >= 6.6, < 6.7 +PyQt6-WebEngine-Qt6 >= 6.6, < 6.7 diff --git a/tox.ini b/tox.ini index 48cdfa72d..238c532f3 100644 --- a/tox.ini +++ b/tox.ini @@ -51,8 +51,9 @@ deps = pyqt63: -r{toxinidir}/misc/requirements/requirements-pyqt-6.3.txt pyqt64: -r{toxinidir}/misc/requirements/requirements-pyqt-6.4.txt pyqt65: -r{toxinidir}/misc/requirements/requirements-pyqt-6.5.txt + pyqt66: -r{toxinidir}/misc/requirements/requirements-pyqt-6.6.txt commands = - !pyqt-!pyqt515-!pyqt5152-!pyqt62-!pyqt63-!pyqt64-!pyqt65: {envpython} scripts/link_pyqt.py --tox {envdir} + !pyqt-!pyqt515-!pyqt5152-!pyqt62-!pyqt63-!pyqt64-!pyqt65-!pyqt66: {envpython} scripts/link_pyqt.py --tox {envdir} {envpython} -bb -m pytest {posargs:tests} cov: {envpython} scripts/dev/check_coverage.py {posargs} -- cgit v1.2.3-54-g00ecf From 5cc948aeb5702626a26ea434ca433a13bdbfd822 Mon Sep 17 00:00:00 2001 From: toofar Date: Mon, 13 Nov 2023 20:23:06 +1300 Subject: Downgrade mypy for now I believe we are being afflicted by this issue: https://github.com/python/mypy/issues/16451 Although I'm not 100% sure because there is a lot going on in this function and I haven't managed to grok it. The mypy 1.7 release [notes][1.7] say you can disable the new type inference by running `tox -e mypy-pyqt6 -- --old-type-inference` and indeed mypy passes with that. So either our type hints are incorrect or we are hitting a bug. Considering the inferred type hint has a `Never` in it I'm leading toward it being a bug. So I'll bump the mypy version down and hopefully next week the issue will be resolved. The mypy output before this commit was: mypy-pyqt6: commands[0]> .tox/mypy-pyqt6/bin/python -m mypy --always-true=USE_PYQT6 --always-false=USE_PYQT5 --always-false=USE_PYSIDE6 --always-false=IS_QT5 --always-true=IS_QT6 --always-true=IS_PYQT --always-false=IS_PYSIDE qutebrowser qutebrowser/utils/qtutils.py:239: error: Argument 1 to "contextmanager" has incompatible type "Callable[[str, bool, str], Iterator[IO[AnyStr]]]"; expected "Callable[[str, bool, str], Iterator[IO[Never]]]" [arg-type] @contextlib.contextmanager ^ qutebrowser/misc/lineparser.py: note: In member "save" of class "LineParser": qutebrowser/misc/lineparser.py:168: error: Need type annotation for "f" [var-annotated] with qtutils.savefile_open(self._configfile, self._binary) as f: ^ qutebrowser/misc/lineparser.py: note: In member "save" of class "LimitLineParser": qutebrowser/misc/lineparser.py:226: error: Need type annotation for "f" [var-annotated] with qtutils.savefile_open(self._configfile, self._binary) as f: ^ qutebrowser/config/configfiles.py: note: In member "_save" of class "YamlConfig": qutebrowser/config/configfiles.py:292: error: Need type annotation for "f" [var-annotated] with qtutils.savefile_open(self._filename) as f: ^ qutebrowser/misc/sessions.py: note: In member "save" of class "SessionManager": qutebrowser/misc/sessions.py:343: error: Need type annotation for "f" [var-annotated] with qtutils.savefile_open(path) as f: [1.7]: https://mypy-lang.blogspot.com/2023/11/mypy-17-released.html --- misc/requirements/requirements-mypy.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/requirements/requirements-mypy.txt b/misc/requirements/requirements-mypy.txt index 497ac9b92..b8c88cfc0 100644 --- a/misc/requirements/requirements-mypy.txt +++ b/misc/requirements/requirements-mypy.txt @@ -6,7 +6,7 @@ importlib-resources==6.1.1 Jinja2==3.1.2 lxml==4.9.3 MarkupSafe==2.1.3 -mypy==1.7.0 +mypy==1.6.1 mypy-extensions==1.0.0 pluggy==1.3.0 Pygments==2.16.1 -- cgit v1.2.3-54-g00ecf