summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/changelog.asciidoc29
-rw-r--r--qutebrowser/browser/commands.py3
-rw-r--r--qutebrowser/misc/guiprocess.py11
-rw-r--r--qutebrowser/utils/version.py2
-rw-r--r--scripts/dev/misc_checks.py4
-rw-r--r--tests/unit/misc/test_guiprocess.py18
-rw-r--r--tests/unit/utils/test_version.py1
7 files changed, 55 insertions, 13 deletions
diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc
index 58fbecb6f..a939de539 100644
--- a/doc/changelog.asciidoc
+++ b/doc/changelog.asciidoc
@@ -21,6 +21,20 @@ v2.0.0 (unreleased)
Major changes
~~~~~~~~~~~~~
+- Quick checklist for packagers:
+ * Ensure you're providing at least Python 3.6.1
+ * Ensure you're providing at least Qt 5.12 and PyQt 5.12
+ * Add a new optional dependency on the Python `adblock` library (if packaged -
+ if not, consider packaging it, albeit optional it's very useful for users)
+ * Remove the `cssutils` optional dependency (if present)
+ * Remove the `attrs` (`attr`) dependency
+ * Move the `pygments` dependency from required to optional
+ * TODO: Move the `setuptools` dependency from runtime (for `pkg_resources`) to
+ build-time.
+ * For Python 3.6, 3.7 or 3.8, add a dependency on the `importlib_resources`
+ backport.
+ * For Python 3.6 only, add a dependency on the `dataclasses` backport.
+ * TODO complete?
- At least Python 3.6.1 is now required to run qutebrowser, support for Python
3.5 (and 3.6.0) is dropped. Note that Python 3.5 is
https://www.python.org/downloads/release/python-3510/[no longer supported
@@ -37,7 +51,8 @@ Major changes
with a newer version of Qt/PyQt.
- New optional dependency on the Python `adblock` library, which is now used to
integrate Brave's Rust adblocker library, if the `adblock` module is available.
-- Windows 7 is not supported anymore by the Windows binaries.
+ If it is unavailable, qutebrowser falls back to host-blocking, i.e. the same
+ blocking technique it used before this release.
- The (formerly optional) `cssutils` dependency is now removed. It was only
needed for improved behavior in corner cases when using `:download --mhtml`
with the (non-default) QtWebKit backend, and as such it's unlikely anyone is
@@ -56,6 +71,8 @@ Major changes
thus requiring the backports for those versions as well.
- The former dependency on the `attrs`/`attr` package is now dropped.
- On Python 3.6, a new dependency on the `dataclasses` backport is now required.
+- Windows 7 is not supported anymore by the Windows binaries.
+- TODO: The Windows and macOS binaries are now updated to Python 3.9.
Removed
~~~~~~~
@@ -87,10 +104,10 @@ Added
the desktop filename passed to Qt (which is used to set the `app_id` on
Wayland).
- New userscripts:
- - `kodi` to play videos in Kodi
- - `qr` to generate a QR code of the current URL
- - `add-nextcloud-bookmarks` to create bookmarks in Nextcloud's Bookmarks app
- - `add-nextcloud-cookbook` to add recipes to Nextcloud's Cookbook app
+ * `kodi` to play videos in Kodi
+ * `qr` to generate a QR code of the current URL
+ * `add-nextcloud-bookmarks` to create bookmarks in Nextcloud's Bookmarks app
+ * `add-nextcloud-cookbook` to add recipes to Nextcloud's Cookbook app
Changed
~~~~~~~
@@ -156,6 +173,8 @@ Fixed
contains a proper extension. Before this fix, qutebrowser would use the URL's
data contents as filename with QtWebEngine; or "binary blob" with the Qt network
stack.
+- When `:tab-only` is run before a tab is available, an error is now shown
+ instead of crashing.
- TODO: Due to a long-standing bug in the `pkg_resources` dependency, it caused
qutebrowser's startup to slow down by around 150ms-1s (heavily depending on
the system). Since the dependency is now removed, qutebrowser's startup time
diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py
index ec43a3210..936af5402 100644
--- a/qutebrowser/browser/commands.py
+++ b/qutebrowser/browser/commands.py
@@ -764,7 +764,8 @@ class CommandDispatcher:
"""
cmdutils.check_exclusive((prev, next_), 'pn')
cur_idx = self._tabbed_browser.widget.currentIndex()
- assert cur_idx != -1
+ if cur_idx == -1:
+ raise cmdutils.CommandError("Failed to get current tab for :tab-only")
def _to_close(i):
"""Helper method to check if a tab should be closed or not."""
diff --git a/qutebrowser/misc/guiprocess.py b/qutebrowser/misc/guiprocess.py
index 872a594f3..4b0727793 100644
--- a/qutebrowser/misc/guiprocess.py
+++ b/qutebrowser/misc/guiprocess.py
@@ -25,7 +25,7 @@ import shlex
from PyQt5.QtCore import (pyqtSlot, pyqtSignal, QObject, QProcess,
QProcessEnvironment)
-from qutebrowser.utils import message, log
+from qutebrowser.utils import message, log, utils
from qutebrowser.browser import qutescheme
@@ -75,9 +75,12 @@ class GUIProcess(QObject):
procenv.insert(k, v)
self._proc.setProcessEnvironment(procenv)
- @pyqtSlot()
- def _on_error(self):
+ @pyqtSlot(QProcess.ProcessError)
+ def _on_error(self, error):
"""Show a message if there was an error while spawning."""
+ if error == QProcess.Crashed and not utils.is_windows:
+ # Already handled via ExitStatus in _on_finished
+ return
msg = self._proc.errorString()
message.error("Error while spawning {}: {}".format(self._what, msg))
@@ -101,7 +104,7 @@ class GUIProcess(QObject):
message.error(stderr.strip())
if status == QProcess.CrashExit:
- exitinfo = "{} crashed!".format(self._what.capitalize())
+ exitinfo = "{} crashed.".format(self._what.capitalize())
message.error(exitinfo)
elif status == QProcess.NormalExit and code == 0:
exitinfo = "{} exited successfully.".format(
diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py
index 74ad73833..94c835357 100644
--- a/qutebrowser/utils/version.py
+++ b/qutebrowser/utils/version.py
@@ -365,8 +365,6 @@ MODULE_INFO: Mapping[str, ModuleInfo] = collections.OrderedDict([
('pygments', ['__version__']),
('yaml', ['__version__']),
('adblock', ['__version__'], "0.3.2"),
- ('dataclasses', []),
- ('importlib_resources', []),
('PyQt5.QtWebEngineWidgets', []),
('PyQt5.QtWebEngine', ['PYQT_WEBENGINE_VERSION_STR']),
('PyQt5.QtWebKitWidgets', []),
diff --git a/scripts/dev/misc_checks.py b/scripts/dev/misc_checks.py
index 5c654235c..afbb5e791 100644
--- a/scripts/dev/misc_checks.py
+++ b/scripts/dev/misc_checks.py
@@ -214,6 +214,10 @@ def check_spelling(args: argparse.Namespace) -> Optional[bool]:
re.compile(r'Q_(ENUM|FLAG)'),
"Q_ENUM and Q_FLAG are removed in PyQt 6",
),
+ (
+ re.compile(r'attr\.(s|ib)($|\()'),
+ "attrs have been replaced by dataclasses in qutebrowser.",
+ ),
]
# Files which should be ignored, e.g. because they come from another
diff --git a/tests/unit/misc/test_guiprocess.py b/tests/unit/misc/test_guiprocess.py
index 4ed19f64e..9b2e1e7b3 100644
--- a/tests/unit/misc/test_guiprocess.py
+++ b/tests/unit/misc/test_guiprocess.py
@@ -25,7 +25,7 @@ import pytest
from PyQt5.QtCore import QProcess
from qutebrowser.misc import guiprocess
-from qutebrowser.utils import usertypes
+from qutebrowser.utils import usertypes, utils
from qutebrowser.browser import qutescheme
@@ -237,6 +237,22 @@ def test_exit_unsuccessful(qtbot, proc, message_mock, py_proc, caplog):
assert msg.text == expected
+def test_exit_crash(qtbot, proc, message_mock, py_proc, caplog):
+ with caplog.at_level(logging.ERROR):
+ with qtbot.waitSignal(proc.finished, timeout=10000):
+ proc.start(*py_proc("""
+ import os, signal
+ os.kill(os.getpid(), signal.SIGSEGV)
+ """))
+
+ expected = (
+ "Testprocess exited with status 11, see :messages for details."
+ if utils.is_windows else "Testprocess crashed."
+ )
+ msg = message_mock.getmsg(usertypes.MessageLevel.error)
+ assert msg.text == expected
+
+
@pytest.mark.parametrize('stream', ['stdout', 'stderr'])
def test_exit_unsuccessful_output(qtbot, proc, caplog, py_proc, stream):
"""When a process fails, its output should be logged."""
diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py
index 912be3bec..6d94fc72c 100644
--- a/tests/unit/utils/test_version.py
+++ b/tests/unit/utils/test_version.py
@@ -715,6 +715,7 @@ class TestModuleVersions:
('yaml', True),
('adblock', True),
('dataclasses', False),
+ ('importlib_resources', False),
])
def test_existing_attributes(self, name, has_version):
"""Check if all dependencies have an expected __version__ attribute.