From 291dda69e5ffe2aadce7d9b7212d0b60b61101fd Mon Sep 17 00:00:00 2001 From: qutebrowser bot Date: Mon, 2 Jun 2025 04:26:41 +0000 Subject: [PATCH 1/3] Update dependencies --- misc/requirements/requirements-check-manifest.txt | 2 +- misc/requirements/requirements-dev.txt | 2 +- misc/requirements/requirements-mypy.txt | 5 +++-- misc/requirements/requirements-pyinstaller.txt | 2 +- misc/requirements/requirements-pyroma.txt | 2 +- misc/requirements/requirements-sphinx.txt | 2 +- misc/requirements/requirements-tests.txt | 8 ++++---- misc/requirements/requirements-tox.txt | 2 +- 8 files changed, 13 insertions(+), 12 deletions(-) diff --git a/misc/requirements/requirements-check-manifest.txt b/misc/requirements/requirements-check-manifest.txt index bd5fb65c2..7b9da018b 100644 --- a/misc/requirements/requirements-check-manifest.txt +++ b/misc/requirements/requirements-check-manifest.txt @@ -6,4 +6,4 @@ importlib_metadata==8.7.0 packaging==25.0 pyproject_hooks==1.2.0 tomli==2.2.1 -zipp==3.21.0 +zipp==3.22.0 diff --git a/misc/requirements/requirements-dev.txt b/misc/requirements/requirements-dev.txt index 411882fae..fc1f2c676 100644 --- a/misc/requirements/requirements-dev.txt +++ b/misc/requirements/requirements-dev.txt @@ -71,4 +71,4 @@ uritemplate==4.1.1 # urllib3==2.4.0 wcmatch==10.0 wcwidth==0.2.13 -zipp==3.21.0 +zipp==3.22.0 diff --git a/misc/requirements/requirements-mypy.txt b/misc/requirements/requirements-mypy.txt index ee999e744..bda2a164b 100644 --- a/misc/requirements/requirements-mypy.txt +++ b/misc/requirements/requirements-mypy.txt @@ -1,12 +1,13 @@ # This file is automatically generated by scripts/dev/recompile_requirements.py chardet==5.2.0 -diff_cover==9.3.1 +diff_cover==9.3.2 Jinja2==3.1.6 lxml==5.4.0 MarkupSafe==3.0.2 -mypy==1.15.0 +mypy==1.16.0 mypy_extensions==1.1.0 +pathspec==0.12.1 pluggy==1.6.0 Pygments==2.19.1 PyQt5-stubs==5.15.6.0 diff --git a/misc/requirements/requirements-pyinstaller.txt b/misc/requirements/requirements-pyinstaller.txt index 08eec477e..a811e09c0 100644 --- a/misc/requirements/requirements-pyinstaller.txt +++ b/misc/requirements/requirements-pyinstaller.txt @@ -5,4 +5,4 @@ importlib_metadata==8.7.0 packaging==25.0 pyinstaller==6.13.0 pyinstaller-hooks-contrib==2025.4 -zipp==3.21.0 +zipp==3.22.0 diff --git a/misc/requirements/requirements-pyroma.txt b/misc/requirements/requirements-pyroma.txt index 0070d7d28..1dc373b3d 100644 --- a/misc/requirements/requirements-pyroma.txt +++ b/misc/requirements/requirements-pyroma.txt @@ -14,4 +14,4 @@ requests==2.32.3 tomli==2.2.1 trove-classifiers==2025.5.9.12 urllib3==2.4.0 -zipp==3.21.0 +zipp==3.22.0 diff --git a/misc/requirements/requirements-sphinx.txt b/misc/requirements/requirements-sphinx.txt index 7fa9542c6..6d0e7b09c 100644 --- a/misc/requirements/requirements-sphinx.txt +++ b/misc/requirements/requirements-sphinx.txt @@ -23,4 +23,4 @@ sphinxcontrib-qthelp==2.0.0 sphinxcontrib-serializinghtml==2.0.0 tomli==2.2.1 urllib3==2.4.0 -zipp==3.21.0 +zipp==3.22.0 diff --git a/misc/requirements/requirements-tests.txt b/misc/requirements/requirements-tests.txt index fe7840291..e6be10d0a 100644 --- a/misc/requirements/requirements-tests.txt +++ b/misc/requirements/requirements-tests.txt @@ -16,7 +16,7 @@ filelock==3.18.0 Flask==3.1.1 gherkin-official==29.0.0 hunter==3.7.0 -hypothesis==6.131.28 +hypothesis==6.132.0 idna==3.10 importlib_metadata==8.7.0 importlib_resources==6.5.2 @@ -45,11 +45,11 @@ pytest-bdd==8.1.0 pytest-benchmark==5.1.0 pytest-cov==6.1.1 pytest-instafail==0.5.0 -pytest-mock==3.14.0 +pytest-mock==3.14.1 pytest-qt==4.4.0 pytest-repeat==0.9.4 pytest-rerunfailures==15.1 -pytest-xdist==3.6.1 +pytest-xdist==3.7.0 pytest-xvfb==3.1.1 PyVirtualDisplay==3.0 requests==2.32.3 @@ -64,4 +64,4 @@ typing_extensions==4.13.2 urllib3==2.4.0 vulture==2.14 Werkzeug==3.1.3 -zipp==3.21.0 +zipp==3.22.0 diff --git a/misc/requirements/requirements-tox.txt b/misc/requirements/requirements-tox.txt index c2037a90c..c8ec5724f 100644 --- a/misc/requirements/requirements-tox.txt +++ b/misc/requirements/requirements-tox.txt @@ -10,7 +10,7 @@ pip==25.1.1 platformdirs==4.3.8 pluggy==1.6.0 pyproject-api==1.9.1 -setuptools==80.8.0 +setuptools==80.9.0 tomli==2.2.1 tox==4.26.0 ; python_full_version!="3.14.0b1" typing_extensions==4.13.2 From 060f4a59d6565c58d19aed0d8b7f49cc361990f9 Mon Sep 17 00:00:00 2001 From: toofar Date: Mon, 2 Jun 2025 18:42:23 +1200 Subject: [PATCH 2/3] mypy: cast variable only on Qt5 We only have to cast these variables on Qt5. If we cast them on Qt6 mypy warns of a redundant cast. If we ignore that warning mypy complains of a redundant ignore on Qt5. Add a conditional on `machinery.IS_QT5` and only cast it required. But also move that conditional out to a utility function to avoid duplicating code in the function doing the actual logic. I'm re-using the `_T` generic TypeVar defined above. Not sure if it's proper to re-use them or not. Doesn't python have a better way of defining generics now? I added the `valid-type` ignore because mypy was complaining: Variable "to_type" is not valid as a type I'm not sure if there is some way to do it better, but `reveal_type()` says that the call site is getting the right type back in the end. --- qutebrowser/completion/models/completionmodel.py | 6 +++--- qutebrowser/misc/nativeeventfilter.py | 8 ++++---- qutebrowser/utils/qtutils.py | 11 +++++++++++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/qutebrowser/completion/models/completionmodel.py b/qutebrowser/completion/models/completionmodel.py index a4eed93d1..c0f6a86ff 100644 --- a/qutebrowser/completion/models/completionmodel.py +++ b/qutebrowser/completion/models/completionmodel.py @@ -4,7 +4,7 @@ """A model that proxies access to one or more completion categories.""" -from typing import overload, Optional, Any, cast +from typing import overload, Optional, Any from collections.abc import MutableSequence from qutebrowser.qt import machinery @@ -91,14 +91,14 @@ class CompletionModel(QAbstractItemModel): Return: The item flags, or Qt.ItemFlag.NoItemFlags on error. """ if not index.isValid(): - return cast(_FlagType, Qt.ItemFlag.NoItemFlags) + return qtutils.maybe_cast(_FlagType, machinery.IS_QT5, Qt.ItemFlag.NoItemFlags) if index.parent().isValid(): # item return (Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemNeverHasChildren) else: # category - return cast(_FlagType, Qt.ItemFlag.NoItemFlags) + return qtutils.maybe_cast(_FlagType, machinery.IS_QT5, Qt.ItemFlag.NoItemFlags) def index(self, row: int, col: int, parent: QModelIndex = QModelIndex()) -> QModelIndex: """Get an index into the model. diff --git a/qutebrowser/misc/nativeeventfilter.py b/qutebrowser/misc/nativeeventfilter.py index 1933dc63f..e93b3c6d1 100644 --- a/qutebrowser/misc/nativeeventfilter.py +++ b/qutebrowser/misc/nativeeventfilter.py @@ -7,7 +7,7 @@ This entire file is a giant WORKAROUND for https://bugreports.qt.io/browse/QTBUG-114334. """ -from typing import Union, cast, Optional +from typing import Union, Optional import enum import ctypes import ctypes.util @@ -16,7 +16,7 @@ from qutebrowser.qt import sip, machinery from qutebrowser.qt.core import QAbstractNativeEventFilter, QByteArray, qVersion from qutebrowser.misc import objects -from qutebrowser.utils import log +from qutebrowser.utils import log, qtutils # Needs to be saved to avoid garbage collection @@ -104,8 +104,8 @@ class NativeEventFilter(QAbstractNativeEventFilter): # # Tuple because PyQt uses the second value as the *result out-pointer, which # according to the Qt documentation is only used on Windows. - _PASS_EVENT_RET = (False, cast(_PointerRetType, 0)) - _FILTER_EVENT_RET = (True, cast(_PointerRetType, 0)) + _PASS_EVENT_RET = (False, qtutils.maybe_cast(_PointerRetType, machinery.IS_QT6, 0)) + _FILTER_EVENT_RET = (True, qtutils.maybe_cast(_PointerRetType, machinery.IS_QT6, 0)) def __init__(self) -> None: super().__init__() diff --git a/qutebrowser/utils/qtutils.py b/qutebrowser/utils/qtutils.py index a027db74a..d55f9bc2f 100644 --- a/qutebrowser/utils/qtutils.py +++ b/qutebrowser/utils/qtutils.py @@ -749,3 +749,14 @@ else: return obj QT_NONE: None = None + + +def maybe_cast(to_type: type[_T], do_cast: bool, value: Any) -> _T: + """Cast `value` to `to_type` only if `do_cast` is true.""" + if do_cast: + return cast( + to_type, # type: ignore[valid-type] + value, + ) + + return value From 422680046e45679551ceb0d08804ad4b008a284a Mon Sep 17 00:00:00 2001 From: toofar Date: Mon, 2 Jun 2025 20:32:09 +1200 Subject: [PATCH 3/3] Update PDF.js version extraction for 5.3.31 It's changed in this PR: https://github.com/mozilla/pdf.js/pull/19956 to have the version string as a comment in the file, instead of the variable. Making the regex more forgiving increases the chance of matching on the wrong string on a past or future version. I've only tested with the previous version (v5.2.133) and it seemed to still work there. Changes I made to the regex: * add the literal * to the match group of possible prefixes of pdfjsVersion * make the quotes around the version optional * make the semicolon at the end of the line optional * add newline to the list of characters that can terminate the match group (otherwise it was matching across the end of the line up to the first string, kinda odd when there was a $ after the match group) --- qutebrowser/utils/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index e9cea7866..37bfe0dc4 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -487,7 +487,7 @@ def _pdfjs_version() -> str: else: pdfjs_file = pdfjs_file.decode('utf-8') version_re = re.compile( - r"""^ *(PDFJS\.version|(var|const) pdfjsVersion) = ['"](?P[^'"]+)['"];$""", + r"""^ *(PDFJS\.version|(var|const|\*) pdfjsVersion) = ['"]?(?P[^'"\n]+)['"]?;?$""", re.MULTILINE) match = version_re.search(pdfjs_file)