summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoofar <toofar@spalge.com>2022-11-20 15:48:00 +1300
committertoofar <toofar@spalge.com>2022-11-20 15:48:00 +1300
commit2d6646619449d0baa72b35c9e88a3cc8f7c0b790 (patch)
tree1501ae07ce9917d257ce900e17a921f369c3ae88
parentd9a46b1a62792b3f74e428bbde852209328f1e8d (diff)
parent1417ffa519a7c43197edafde76dd49fc348784f7 (diff)
downloadqutebrowser-2d6646619449d0baa72b35c9e88a3cc8f7c0b790.tar.gz
qutebrowser-2d6646619449d0baa72b35c9e88a3cc8f7c0b790.zip
Merge branch 'master' into qt6-v2
Just a few conflicts around CI and dependencies.
-rw-r--r--.github/dependabot.yml6
-rw-r--r--.github/workflows/nightly.yml4
-rw-r--r--.github/workflows/recompile-requirements.yml2
-rw-r--r--.mypy.ini4
-rw-r--r--doc/changelog.asciidoc6
-rw-r--r--doc/faq.asciidoc25
-rw-r--r--doc/help/configuring.asciidoc1
-rw-r--r--doc/help/settings.asciidoc4
-rw-r--r--misc/requirements/requirements-check-manifest.txt2
-rw-r--r--misc/requirements/requirements-dev.txt34
-rw-r--r--misc/requirements/requirements-flake8.txt8
-rw-r--r--misc/requirements/requirements-flake8.txt-raw2
-rw-r--r--misc/requirements/requirements-mypy.txt14
-rw-r--r--misc/requirements/requirements-pyinstaller.txt6
-rw-r--r--misc/requirements/requirements-pylint.txt24
-rw-r--r--misc/requirements/requirements-pyroma.txt8
-rw-r--r--misc/requirements/requirements-qutebrowser.txt-raw11
-rw-r--r--misc/requirements/requirements-sphinx.txt16
-rw-r--r--misc/requirements/requirements-tests-bleeding.txt4
-rw-r--r--misc/requirements/requirements-tests.txt48
-rw-r--r--misc/requirements/requirements-tox.txt16
-rw-r--r--misc/requirements/requirements-vulture.txt2
-rw-r--r--misc/requirements/requirements-yamllint.txt4
-rw-r--r--misc/userscripts/README.md8
-rwxr-xr-xmisc/userscripts/readability2
-rw-r--r--pytest.ini3
-rw-r--r--qutebrowser/api/cmdutils.py2
-rw-r--r--qutebrowser/browser/commands.py3
-rw-r--r--qutebrowser/completion/completer.py1
-rw-r--r--qutebrowser/config/configdata.yml9
-rw-r--r--qutebrowser/config/configfiles.py3
-rw-r--r--qutebrowser/javascript/webelem.js8
-rw-r--r--qutebrowser/mainwindow/statusbar/bar.py2
-rw-r--r--qutebrowser/mainwindow/tabwidget.py16
-rw-r--r--qutebrowser/misc/checkpyver.py4
-rw-r--r--qutebrowser/misc/guiprocess.py13
-rw-r--r--qutebrowser/utils/objreg.py2
-rw-r--r--qutebrowser/utils/utils.py2
-rw-r--r--requirements.txt15
-rwxr-xr-xscripts/asciidoc2html.py6
-rw-r--r--scripts/dev/changelog_urls.json5
-rw-r--r--scripts/dev/ci/docker/Dockerfile.j215
-rw-r--r--scripts/dev/ci/docker/generate.py2
-rw-r--r--scripts/dev/misc_checks.py8
-rw-r--r--scripts/dev/ua_fetch.py1
-rwxr-xr-xscripts/dictcli.py2
-rwxr-xr-xscripts/mkvenv.py2
-rw-r--r--tests/conftest.py5
-rw-r--r--tests/end2end/features/prompts.feature5
-rw-r--r--tests/end2end/features/test_downloads_bdd.py6
-rw-r--r--tests/end2end/features/test_history_bdd.py1
-rw-r--r--tests/helpers/fixtures.py6
-rw-r--r--tests/helpers/testutils.py4
-rw-r--r--tests/unit/browser/test_pdfjs.py2
-rw-r--r--tests/unit/browser/test_qutescheme.py4
-rw-r--r--tests/unit/browser/webkit/network/test_filescheme.py2
-rw-r--r--tests/unit/commands/test_userscripts.py4
-rw-r--r--tests/unit/config/test_configfiles.py2
-rw-r--r--tests/unit/mainwindow/statusbar/test_backforward.py71
-rw-r--r--tests/unit/mainwindow/statusbar/test_progress.py8
-rw-r--r--tests/unit/misc/test_editor.py2
-rw-r--r--tests/unit/misc/test_guiprocess.py17
62 files changed, 324 insertions, 200 deletions
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 000000000..5ace4600a
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,6 @@
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index 073f2c69c..5aaafb666 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -97,8 +97,8 @@ jobs:
- name: Gather info
id: info
run: |
- echo "::set-output name=date::$(date +'%Y-%m-%d')"
- echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
+ echo "date=$(date +'%Y-%m-%d')" >> "$GITHUB_OUTPUT"
+ echo "sha_short=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
diff --git a/.github/workflows/recompile-requirements.yml b/.github/workflows/recompile-requirements.yml
index 3c7442a61..c7d9702a7 100644
--- a/.github/workflows/recompile-requirements.yml
+++ b/.github/workflows/recompile-requirements.yml
@@ -45,7 +45,7 @@ jobs:
- name: Run qutebrowser smoke test
run: "xvfb-run .venv/bin/python3 -m qutebrowser --no-err-windows --nowindow --temp-basedir about:blank ':later 500 quit'"
- name: Create pull request
- uses: peter-evans/create-pull-request@v3
+ uses: peter-evans/create-pull-request@v4
with:
committer: qutebrowser bot <bot@qutebrowser.org>
author: qutebrowser bot <bot@qutebrowser.org>
diff --git a/.mypy.ini b/.mypy.ini
index 820b2f966..56124b5c3 100644
--- a/.mypy.ini
+++ b/.mypy.ini
@@ -10,7 +10,6 @@ disallow_subclassing_any = True
disallow_incomplete_defs = True
check_untyped_defs = True
disallow_untyped_decorators = True
-# no_implicit_optional = True
warn_redundant_casts = True
warn_unused_ignores = True
# warn_return_any = True
@@ -27,6 +26,9 @@ show_error_codes = True
show_error_context = True
pretty = True
+### FIXME:qt6 get rid of this for v3
+no_implicit_optional = False
+
[mypy-colorama]
# https://github.com/tartley/colorama/issues/206
ignore_missing_imports = True
diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc
index 991673d11..6d740fe3f 100644
--- a/doc/changelog.asciidoc
+++ b/doc/changelog.asciidoc
@@ -119,6 +119,9 @@ Fixed
shown, qutebrowser used to only show one message. This is now only done when the
two messages are completely equivalent (text, level, etc.) instead of doing so
when only the text matches.
+- The `progress` and `backforward` statusbar widgets now stay removed if you
+ choose to remove them. Previously they would appear again on navigation.
+- Rare crash when running userscripts with crashed renderer processes.
[[v2.5.3]]
v2.5.3 (unreleased)
@@ -138,6 +141,9 @@ Fixed
- Wrong type handling when using `:config-{dict,list}-*` commands with a config
option with non-string values. The only affected option is `bindings.commands`,
which is probably rarely used with those commands.
+- The `readability` userscript now correctly passes the source URL to
+ Breadability, to make relative links work.
+- Update `dictcli.py` to use the `main` branch, fixing a 404 error.
- Minor documentation fixes
[[v2.5.2]]
diff --git a/doc/faq.asciidoc b/doc/faq.asciidoc
index 4b3596285..bcbd0d29a 100644
--- a/doc/faq.asciidoc
+++ b/doc/faq.asciidoc
@@ -158,7 +158,7 @@ It also works nicely with rapid hints:
:bind ;M hint --rapid links spawn umpv {hint-url}
----
-How do I use qutebrowser with mutt?::
+How do I use qutebrowser with mutt/neomutt or other mail clients?::
For security reasons, local files without `.html` extensions aren't
rendered as HTML, see
https://bugs.chromium.org/p/chromium/issues/detail?id=777737[this Chromium issue]
@@ -166,8 +166,29 @@ How do I use qutebrowser with mutt?::
extension:
+
----
- text/html; qutebrowser %s; needsterminal; nametemplate=%s.html
+text/html; qutebrowser %s; needsterminal; nametemplate=%s.html
----
++
+Note that you might want to add additional options to qutebrowser, so that it
+runs as a seperate instance configured to disable JavaScript and avoid network
+requests, in order to avoid privacy leaks when reading mails. The easiest way
+to do so is by specifying a non-existent proxy server, e.g.:
++
+----
+qutebrowser --temp-basedir -s content.proxy http://localhost:666 -s content.dns_prefetch false -s content.javascript.enabled false %s
+----
++
+With Qt 6, using something like:
++
+----
+qutebrowser --temp-basedir -s content.dns_prefetch false -s content.javascript.enabled false %s
+----
++
+should lead to a similar result, due to a more restrictive implementation of
+the `content.local_content_can_access_remote_urls` setting (`false` by default
+already). However, it's advised to use a page like
+https://www.emailprivacytester.com/[Email Privacy Tester] to verify your
+configuration.
What is the difference between bookmarks and quickmarks?::
Bookmarks will always use the title of the website as their name, but with quickmarks
diff --git a/doc/help/configuring.asciidoc b/doc/help/configuring.asciidoc
index 3ecef8ecf..cab3df59a 100644
--- a/doc/help/configuring.asciidoc
+++ b/doc/help/configuring.asciidoc
@@ -449,6 +449,7 @@ Various emacs/conkeror-like keybinding configs exist:
- https://gitlab.com/Kaligule/qutebrowser-emacs-config/blob/master/config.py[Kaligule]
- https://web.archive.org/web/20210512185023/https://me0w.net/pit/1540882719[nm0i]
- https://www.reddit.com/r/qutebrowser/comments/eh10i7/config_share_qute_with_emacs_keybindings/[jasonsun0310]
+- https://git.sr.ht/~willvaughn/dots/tree/mjolnir/item/.config/qutebrowser/qutemacs.py[willvaughn]
It's also mostly possible to get rid of modal keybindings by setting
`input.insert_mode.auto_enter` to `false`, and `input.forward_unbound_keys` to
diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc
index 033261df8..32656d461 100644
--- a/doc/help/settings.asciidoc
+++ b/doc/help/settings.asciidoc
@@ -218,7 +218,7 @@
|<<editor.encoding,editor.encoding>>|Encoding to use for the editor.
|<<editor.remove_file,editor.remove_file>>|Delete the temporary file upon closing the editor.
|<<fileselect.folder.command,fileselect.folder.command>>|Command (and arguments) to use for selecting a single folder in forms. The command should write the selected folder path to the specified file or stdout.
-|<<fileselect.handler,fileselect.handler>>|Handler for selecting file(s) in forms. If `external`, then the commands specified by `fileselect.single_file.command` and `fileselect.multiple_files.command` are used to select one or multiple files respectively.
+|<<fileselect.handler,fileselect.handler>>|Handler for selecting file(s) in forms. If `external`, then the commands specified by `fileselect.single_file.command`, `fileselect.multiple_files.command` and `fileselect.folder.command` are used to select one file, multiple files, and folders, respectively.
|<<fileselect.multiple_files.command,fileselect.multiple_files.command>>|Command (and arguments) to use for selecting multiple files in forms. The command should write the selected file paths to the specified file or to stdout, separated by newlines.
|<<fileselect.single_file.command,fileselect.single_file.command>>|Command (and arguments) to use for selecting a single file in forms. The command should write the selected file path to the specified file or stdout.
|<<fonts.completion.category,fonts.completion.category>>|Font used in the completion categories.
@@ -3011,7 +3011,7 @@ Default:
[[fileselect.handler]]
=== fileselect.handler
-Handler for selecting file(s) in forms. If `external`, then the commands specified by `fileselect.single_file.command` and `fileselect.multiple_files.command` are used to select one or multiple files respectively.
+Handler for selecting file(s) in forms. If `external`, then the commands specified by `fileselect.single_file.command`, `fileselect.multiple_files.command` and `fileselect.folder.command` are used to select one file, multiple files, and folders, respectively.
Type: <<types,String>>
diff --git a/misc/requirements/requirements-check-manifest.txt b/misc/requirements/requirements-check-manifest.txt
index 1eee9b06c..2e804cbeb 100644
--- a/misc/requirements/requirements-check-manifest.txt
+++ b/misc/requirements/requirements-check-manifest.txt
@@ -1,6 +1,6 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-build==0.8.0
+build==0.9.0
check-manifest==0.48
packaging==21.3
pep517==0.13.0
diff --git a/misc/requirements/requirements-dev.txt b/misc/requirements/requirements-dev.txt
index 777c78796..b3dafe27c 100644
--- a/misc/requirements/requirements-dev.txt
+++ b/misc/requirements/requirements-dev.txt
@@ -1,45 +1,47 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
bleach==5.0.1
-build==0.8.0
+build==0.9.0
bump2version==1.0.1
-certifi==2022.6.15
+certifi==2022.9.24
cffi==1.15.1
charset-normalizer==2.1.1
commonmark==0.9.1
-cryptography==37.0.4
+cryptography==38.0.3
docutils==0.19
github3.py==3.2.0
-hunter==3.4.3
-idna==3.3
-importlib-metadata==4.12.0
+hunter==3.5.1
+idna==3.4
+importlib-metadata==5.0.0
+jaraco.classes==3.2.3
jeepney==0.8.0
-keyring==23.8.2
+keyring==23.11.0
manhole==1.8.0
+more-itertools==9.0.0
packaging==21.3
pep517==0.13.0
pkginfo==1.8.3
ply==3.11
pycparser==2.21
Pygments==2.13.0
-PyJWT==2.4.0
+PyJWT==2.6.0
Pympler==1.0.1
pyparsing==3.0.9
-PyQt-builder==1.13.0
+PyQt-builder==1.14.0
python-dateutil==2.8.2
-readme-renderer==37.0
+readme-renderer==37.3
requests==2.28.1
-requests-toolbelt==0.9.1
+requests-toolbelt==0.10.1
rfc3986==2.0.0
-rich==12.5.1
+rich==12.6.0
SecretStorage==3.3.3
-sip==6.6.2
+sip==6.7.4
six==1.16.0
toml==0.10.2
tomli==2.0.1
twine==4.0.1
-typing_extensions==4.3.0
+typing_extensions==4.4.0
uritemplate==4.1.1
-# urllib3==1.26.11
+# urllib3==1.26.12
webencodings==0.5.1
-zipp==3.8.1
+zipp==3.10.0
diff --git a/misc/requirements/requirements-flake8.txt b/misc/requirements/requirements-flake8.txt
index 78660a405..413c5be78 100644
--- a/misc/requirements/requirements-flake8.txt
+++ b/misc/requirements/requirements-flake8.txt
@@ -2,12 +2,12 @@
attrs==22.1.0
flake8==5.0.4
-flake8-bugbear==22.7.1
-flake8-builtins==1.5.3
-flake8-comprehensions==3.10.0
+flake8-bugbear==22.10.27
+flake8-builtins==2.0.1
+flake8-comprehensions==3.10.1
flake8-copyright==0.2.3
flake8-debugger==4.1.2
-flake8-deprecated==1.3
+flake8-deprecated==2.0.1
flake8-docstrings==1.6.0
flake8-future-import==0.4.7
flake8-plugin-utils==1.3.2
diff --git a/misc/requirements/requirements-flake8.txt-raw b/misc/requirements/requirements-flake8.txt-raw
index de6bb733a..f5ecb7c8d 100644
--- a/misc/requirements/requirements-flake8.txt-raw
+++ b/misc/requirements/requirements-flake8.txt-raw
@@ -3,7 +3,7 @@ flake8-bugbear
flake8-builtins
flake8-comprehensions
flake8-debugger
-flake8-deprecated
+flake8-deprecated!=2.0.0
flake8-docstrings
flake8-copyright
flake8-future-import
diff --git a/misc/requirements/requirements-mypy.txt b/misc/requirements/requirements-mypy.txt
index d40954835..1cd283d8a 100644
--- a/misc/requirements/requirements-mypy.txt
+++ b/misc/requirements/requirements-mypy.txt
@@ -1,18 +1,18 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
chardet==5.0.0
-diff-cover==6.5.1
-importlib-metadata==4.12.0
-importlib-resources==5.9.0
+diff-cover==7.0.2
+importlib-metadata==5.0.0
+importlib-resources==5.10.0
Jinja2==3.1.2
lxml==4.9.1
MarkupSafe==2.1.1
-mypy==0.971
+mypy==0.990
mypy-extensions==0.4.3
pluggy==1.0.0
Pygments==2.13.0
PyQt5-stubs==5.15.6.0
tomli==2.0.1
-types-PyYAML==6.0.11
-typing_extensions==4.3.0
-zipp==3.8.1
+types-PyYAML==6.0.12.2
+typing_extensions==4.4.0
+zipp==3.10.0
diff --git a/misc/requirements/requirements-pyinstaller.txt b/misc/requirements/requirements-pyinstaller.txt
index 3db372d82..5c938bea0 100644
--- a/misc/requirements/requirements-pyinstaller.txt
+++ b/misc/requirements/requirements-pyinstaller.txt
@@ -1,5 +1,5 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-altgraph==0.17.2
-pyinstaller==5.3
-pyinstaller-hooks-contrib==2022.8
+altgraph==0.17.3
+pyinstaller==5.6.2
+pyinstaller-hooks-contrib==2022.13
diff --git a/misc/requirements/requirements-pylint.txt b/misc/requirements/requirements-pylint.txt
index acc335c55..52211c92c 100644
--- a/misc/requirements/requirements-pylint.txt
+++ b/misc/requirements/requirements-pylint.txt
@@ -1,30 +1,30 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-astroid==2.11.7
-certifi==2022.6.15
+astroid==2.12.12
+certifi==2022.9.24
cffi==1.15.1
charset-normalizer==2.1.1
-cryptography==37.0.4
-dill==0.3.5.1
+cryptography==38.0.3
+dill==0.3.6
future==0.18.2
github3.py==3.2.0
-idna==3.3
+idna==3.4
isort==5.10.1
-lazy-object-proxy==1.7.1
+lazy-object-proxy==1.8.0
mccabe==0.7.0
pefile==2022.5.30
-platformdirs==2.5.2
+platformdirs==2.5.4
pycparser==2.21
-PyJWT==2.4.0
-pylint==2.14.5
+PyJWT==2.6.0
+pylint==2.15.5
python-dateutil==2.8.2
./scripts/dev/pylint_checkers
requests==2.28.1
six==1.16.0
tomli==2.0.1
-tomlkit==0.11.4
+tomlkit==0.11.6
typed-ast==1.5.4 ; python_version<"3.8"
-typing_extensions==4.3.0
+typing_extensions==4.4.0
uritemplate==4.1.1
-# urllib3==1.26.11
+# urllib3==1.26.12
wrapt==1.14.1
diff --git a/misc/requirements/requirements-pyroma.txt b/misc/requirements/requirements-pyroma.txt
index f7f97fba1..5ca054ae8 100644
--- a/misc/requirements/requirements-pyroma.txt
+++ b/misc/requirements/requirements-pyroma.txt
@@ -1,10 +1,10 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-build==0.8.0
-certifi==2022.6.15
+build==0.9.0
+certifi==2022.9.24
charset-normalizer==2.1.1
docutils==0.19
-idna==3.3
+idna==3.4
packaging==21.3
pep517==0.13.0
Pygments==2.13.0
@@ -12,4 +12,4 @@ pyparsing==3.0.9
pyroma==4.0
requests==2.28.1
tomli==2.0.1
-urllib3==1.26.11
+urllib3==1.26.12
diff --git a/misc/requirements/requirements-qutebrowser.txt-raw b/misc/requirements/requirements-qutebrowser.txt-raw
index 34cf4abde..4c1d32ae7 100644
--- a/misc/requirements/requirements-qutebrowser.txt-raw
+++ b/misc/requirements/requirements-qutebrowser.txt-raw
@@ -4,8 +4,13 @@ PyYAML
## Only used on macOS to make borderless windows resizable
# Not needed anymore with Qt 6.3, but we can't express that
# here, and it won't hurt either.
-pyobjc-core
-pyobjc-framework-Cocoa
+## our recompile_requirements.py can't really deal with
+## platform-specific dependencies unfortunately...
+# pyobjc-core
+# pyobjc-framework-Cocoa
+#@ add: # Unpinned due to recompile_requirements.py limitations
+#@ add: pyobjc-core ; sys_platform=="darwin"
+#@ add: pyobjc-framework-Cocoa ; sys_platform=="darwin"
## stdlib backports
importlib-resources
@@ -22,5 +27,3 @@ typing_extensions # from importlib-metadata
#@ markers: importlib-resources python_version=="3.7.*" or python_version=="3.8.*"
#@ markers: importlib-metadata python_version=="3.7.*"
#@ markers: typing_extensions python_version<"3.8"
-#@ markers: pyobjc-core sys_platform=="darwin"
-#@ markers: pyobjc-framework-Cocoa sys_platform=="darwin"
diff --git a/misc/requirements/requirements-sphinx.txt b/misc/requirements/requirements-sphinx.txt
index 50c892cf0..f04f2d829 100644
--- a/misc/requirements/requirements-sphinx.txt
+++ b/misc/requirements/requirements-sphinx.txt
@@ -1,27 +1,27 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
alabaster==0.7.12
-Babel==2.10.3
-certifi==2022.6.15
+Babel==2.11.0
+certifi==2022.9.24
charset-normalizer==2.1.1
docutils==0.19
-idna==3.3
+idna==3.4
imagesize==1.4.1
-importlib-metadata==4.12.0
+importlib-metadata==5.0.0
Jinja2==3.1.2
MarkupSafe==2.1.1
packaging==21.3
Pygments==2.13.0
pyparsing==3.0.9
-pytz==2022.2.1
+pytz==2022.6
requests==2.28.1
snowballstemmer==2.2.0
-Sphinx==5.1.1
+Sphinx==5.3.0
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
-urllib3==1.26.11
-zipp==3.8.1
+urllib3==1.26.12
+zipp==3.10.0
diff --git a/misc/requirements/requirements-tests-bleeding.txt b/misc/requirements/requirements-tests-bleeding.txt
index f1ad30158..d249a7e7e 100644
--- a/misc/requirements/requirements-tests-bleeding.txt
+++ b/misc/requirements/requirements-tests-bleeding.txt
@@ -9,7 +9,9 @@ git+https://github.com/HypothesisWorks/hypothesis.git#subdirectory=hypothesis-py
git+https://github.com/pytest-dev/pytest.git
git+https://github.com/pytest-dev/pytest-bdd.git
git+https://github.com/ionelmc/pytest-benchmark.git
-git+https://github.com/pytest-dev/pytest-instafail.git
+# WORKAROUND for pytest-instafail using deprectated pytest functionality
+# See https://github.com/pytest-dev/pytest-instafail/pull/26
+git+https://github.com/The-Compiler/pytest-instafail.git@new-hookimpl
git+https://github.com/pytest-dev/pytest-mock.git
git+https://github.com/pytest-dev/pytest-qt.git
git+https://github.com/pytest-dev/pytest-rerunfailures.git
diff --git a/misc/requirements/requirements-tests.txt b/misc/requirements/requirements-tests.txt
index a7e55e32d..daa7f1dd8 100644
--- a/misc/requirements/requirements-tests.txt
+++ b/misc/requirements/requirements-tests.txt
@@ -2,47 +2,44 @@
attrs==22.1.0
beautifulsoup4==4.11.1
-certifi==2022.6.15
+certifi==2022.9.24
charset-normalizer==2.1.1
cheroot==8.6.0
click==8.1.3
-coverage==6.4.4
-exceptiongroup==1.0.0rc8
+coverage==6.5.0
+exceptiongroup==1.0.2
execnet==1.9.0
filelock==3.8.0
Flask==2.2.2
-glob2==0.7
-hunter==3.4.3
-hypothesis==6.54.4
-idna==3.3
-importlib-metadata==4.12.0
+hunter==3.5.1
+hypothesis==6.56.4
+idna==3.4
+importlib-metadata==5.0.0
iniconfig==1.1.1
itsdangerous==2.1.2
-jaraco.functools==3.5.1
+jaraco.functools==3.5.2
# Jinja2==3.1.2
-Mako==1.2.1
+Mako==1.2.3
manhole==1.8.0
# MarkupSafe==2.1.1
-more-itertools==8.14.0
+more-itertools==9.0.0
packaging==21.3
parse==1.19.0
parse-type==0.6.0
pluggy==1.0.0
-py==1.11.0
-py-cpuinfo==8.0.0
+py-cpuinfo==9.0.0
Pygments==2.13.0
pyparsing==3.0.9
-pytest==7.1.2
-pytest-bdd==6.0.1
-pytest-benchmark==3.4.1
-pytest-cov==3.0.0
-pytest-forked==1.4.0
+pytest==7.2.0
+pytest-bdd==6.1.1
+pytest-benchmark==4.0.0
+pytest-cov==4.0.0
pytest-instafail==0.4.2
-pytest-mock==3.8.2
-pytest-qt==4.1.0
+pytest-mock==3.10.0
+pytest-qt==4.2.0
pytest-repeat==0.9.1
pytest-rerunfailures==10.2
-pytest-xdist==2.5.0
+pytest-xdist==3.0.2
pytest-xvfb==2.0.0
PyVirtualDisplay==3.0
requests==2.28.1
@@ -50,10 +47,11 @@ requests-file==1.5.1
six==1.16.0
sortedcontainers==2.4.0
soupsieve==2.3.2.post1
-tldextract==3.3.1
+tldextract==3.4.0
toml==0.10.2
tomli==2.0.1
-urllib3==1.26.11
-vulture==2.5
+typing_extensions==4.4.0
+urllib3==1.26.12
+vulture==2.6
Werkzeug==2.2.2
-zipp==3.8.1
+zipp==3.10.0
diff --git a/misc/requirements/requirements-tox.txt b/misc/requirements/requirements-tox.txt
index e8975efda..520b410b1 100644
--- a/misc/requirements/requirements-tox.txt
+++ b/misc/requirements/requirements-tox.txt
@@ -1,16 +1,16 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-distlib==0.3.5
+distlib==0.3.6
filelock==3.8.0
packaging==21.3
-pip==22.2.2
-platformdirs==2.5.2
+pip==22.3.1
+platformdirs==2.5.4
pluggy==1.0.0
py==1.11.0
pyparsing==3.0.9
-setuptools==65.2.0
+setuptools==65.5.1
six==1.16.0
-toml==0.10.2
-tox==3.25.1
-virtualenv==20.16.3
-wheel==0.37.1
+tomli==2.0.1
+tox==3.27.0
+virtualenv==20.16.7
+wheel==0.38.4
diff --git a/misc/requirements/requirements-vulture.txt b/misc/requirements/requirements-vulture.txt
index 482a74195..7d0ef20d3 100644
--- a/misc/requirements/requirements-vulture.txt
+++ b/misc/requirements/requirements-vulture.txt
@@ -1,4 +1,4 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
toml==0.10.2
-vulture==2.5
+vulture==2.6
diff --git a/misc/requirements/requirements-yamllint.txt b/misc/requirements/requirements-yamllint.txt
index 78e80a261..2dccc1085 100644
--- a/misc/requirements/requirements-yamllint.txt
+++ b/misc/requirements/requirements-yamllint.txt
@@ -1,5 +1,5 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-pathspec==0.9.0
+pathspec==0.10.2
PyYAML==6.0
-yamllint==1.27.1
+yamllint==1.28.0
diff --git a/misc/userscripts/README.md b/misc/userscripts/README.md
index 7e247f4ba..4c08e0c31 100644
--- a/misc/userscripts/README.md
+++ b/misc/userscripts/README.md
@@ -80,7 +80,7 @@ The following userscripts can be found on their own repositories.
- [1password](https://github.com/tomoakley/dotfiles/blob/master/qutebrowser/userscripts/1password):
Integration with 1password on macOS.
- [localhost](https://github.com/SidharthArya/.qutebrowser/blob/master/userscripts/localhost):
- Quickly navigate to localhost:port. For reference: [A quicker way to reach localhost with qutebrowser](https://sidhartharya.me/a-quicker-way-to-reach-localhost-with-qutebrowser/)
+ Quickly navigate to localhost:port. For reference: [A quicker way to reach localhost with qutebrowser](https://blog.sidhartharya.com/a-quicker-way-to-reach-localhost-with-qutebrowser/)
- [untrack-url](https://github.com/qutebrowser/qutebrowser/discussions/6555),
convert various URLs (YouTube/Reddit/Twitter/Instagram/Google Maps) to other
services (Invidious, Teddit, Nitter, Bibliogram, OpenStreetMap).
@@ -100,6 +100,12 @@ The following userscripts can be found on their own repositories.
- [qute-containers](https://github.com/s-praveen-kumar/qute-containers):
A simple interface to manage browser containers by manipulating the basedir
parameter.
+- [qutebrowser-metascript](https://codeberg.org/mister_monster/qutebrowser-metascript):
+ A user configurable arbitrary sequential command running userscript for qutebrowser
+- [tab-manager](https://codeberg.org/mister_monster/tab-manager):
+ More powerfully manage single window sessions
+- [qutebrowser-url-mutator](https://codeberg.org/mister_monster/qutebrowser-url-mutator):
+ automatically mutates input URLs based on configurable rules
[Zotero]: https://www.zotero.org/
[Pocket]: https://getpocket.com/
diff --git a/misc/userscripts/readability b/misc/userscripts/readability
index 19b687939..07095a5b8 100755
--- a/misc/userscripts/readability
+++ b/misc/userscripts/readability
@@ -47,7 +47,7 @@ with codecs.open(os.environ['QUTE_HTML'], 'r', 'utf-8') as source:
try:
from breadability.readable import Article as reader
- doc = reader(data)
+ doc = reader(data, os.environ['QUTE_URL'])
title = doc._original_document.title
content = HEADER % title + doc.readable + "</html>"
except ImportError:
diff --git a/pytest.ini b/pytest.ini
index 0dcf47429..ab46bd391 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -35,6 +35,7 @@ markers =
fake_os: Fake utils.is_* to a fake operating system
unicode_locale: Tests which need a unicode locale to work
qtwebkit_pdf_imageformat_skip: Broken on QtWebKit with PDF image format plugin installed
+ qtwebkit_openssl3_skip: Broken due to cheroot bug with OpenSSL 3 on QtWebKit
windows_skip: Tests which should be skipped on Windows
qt5_only: Tests which should only run with Qt 5
qt6_only: Tests which should only run with Qt 6
@@ -62,4 +63,6 @@ filterwarnings =
# https://github.com/HypothesisWorks/hypothesis/issues/3309
ignore:module 'sre_constants' is deprecated:DeprecationWarning
ignore:module 'sre_parse' is deprecated:DeprecationWarning
+ # https://github.com/pytest-dev/pytest-instafail/pull/26
+ ignore:The hookimpl pytest_.* uses old-style configuration options:pytest.PytestDeprecationWarning:pytest_instafail
faulthandler_timeout = 90
diff --git a/qutebrowser/api/cmdutils.py b/qutebrowser/api/cmdutils.py
index 73c6a1bc5..3e1bc9432 100644
--- a/qutebrowser/api/cmdutils.py
+++ b/qutebrowser/api/cmdutils.py
@@ -233,7 +233,7 @@ class argument: # noqa: N801,N806 pylint: disable=invalid-name
self._argname))
if not hasattr(func, 'qute_args'):
func.qute_args = {} # type: ignore[attr-defined]
- elif func.qute_args is None: # type: ignore[attr-defined]
+ elif func.qute_args is None:
raise ValueError("@cmdutils.argument got called above (after) "
"@cmdutils.register for {}!".format(funcname))
diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py
index 5b431f8e7..7929ae005 100644
--- a/qutebrowser/browser/commands.py
+++ b/qutebrowser/browser/commands.py
@@ -1191,8 +1191,9 @@ class CommandDispatcher:
env['QUTE_TAB_INDEX'] = str(idx + 1)
env['QUTE_TITLE'] = self._tabbed_browser.widget.page_title(idx)
- # FIXME:qtwebengine: If tab is None, run_async will fail!
tab = self._tabbed_browser.widget.currentWidget()
+ if tab is None:
+ raise cmdutils.CommandError("No current tab!")
try:
url = self._tabbed_browser.current_url()
diff --git a/qutebrowser/completion/completer.py b/qutebrowser/completion/completer.py
index f8d69cc8f..45c287717 100644
--- a/qutebrowser/completion/completer.py
+++ b/qutebrowser/completion/completer.py
@@ -165,7 +165,6 @@ class Completer(QObject):
# cursor is in a space between two existing words
parts.insert(i, '')
prefix = [x.strip() for x in parts[:i]]
- # pylint: disable-next=unnecessary-list-index-lookup
center = parts[i].strip()
# strip trailing whitespace included as a separate token
postfix = [x.strip() for x in parts[i+1:] if not x.isspace()]
diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml
index 6600399bd..afd83585f 100644
--- a/qutebrowser/config/configdata.yml
+++ b/qutebrowser/config/configdata.yml
@@ -1507,11 +1507,10 @@ fileselect.handler:
- default: "Use the default file selector."
- external: "Use an external command."
desc: >-
- Handler for selecting file(s) in forms.
- If `external`, then the commands specified by
- `fileselect.single_file.command` and
- `fileselect.multiple_files.command` are used to select one or
- multiple files respectively.
+ Handler for selecting file(s) in forms. If `external`, then the commands
+ specified by `fileselect.single_file.command`,
+ `fileselect.multiple_files.command` and `fileselect.folder.command` are
+ used to select one file, multiple files, and folders, respectively.
fileselect.single_file.command:
type:
diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py
index 47b799f88..d88e3e91d 100644
--- a/qutebrowser/config/configfiles.py
+++ b/qutebrowser/config/configfiles.py
@@ -170,8 +170,7 @@ class StateConfig(configparser.ConfigParser):
"""Detect a qutebrowser version change."""
old_qutebrowser_version = self['general'].get('version', None)
if old_qutebrowser_version is None:
- # https://github.com/python/typeshed/issues/2093
- return # type: ignore[unreachable]
+ return
try:
old_version = utils.VersionNumber.parse(old_qutebrowser_version)
diff --git a/qutebrowser/javascript/webelem.js b/qutebrowser/javascript/webelem.js
index b4cef24bc..1a753c380 100644
--- a/qutebrowser/javascript/webelem.js
+++ b/qutebrowser/javascript/webelem.js
@@ -197,8 +197,12 @@ window._qutebrowser.webelem = (function() {
try {
frame.document; // eslint-disable-line no-unused-expressions
return true;
- } catch (err) {
- return false;
+ } catch (exc) {
+ if (exc instanceof DOMException && exc.name === "SecurityError") {
+ // FIXME:qtwebengine This does not work for cross-origin frames.
+ return false;
+ }
+ throw exc;
}
}
diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py
index 1205b5466..eb65a0928 100644
--- a/qutebrowser/mainwindow/statusbar/bar.py
+++ b/qutebrowser/mainwindow/statusbar/bar.py
@@ -287,6 +287,8 @@ class StatusBar(QWidget):
self.backforward, self.tabindex,
self.keystring, self.prog, self.clock, *self._text_widgets]:
assert isinstance(widget, QWidget)
+ if widget in [self.prog, self.backforward]:
+ widget.enabled = False # type: ignore[attr-defined]
widget.hide()
self._hbox.removeWidget(widget)
self._text_widgets.clear()
diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py
index 4af9d2f80..b157fc07a 100644
--- a/qutebrowser/mainwindow/tabwidget.py
+++ b/qutebrowser/mainwindow/tabwidget.py
@@ -806,10 +806,22 @@ class TabBarStyle(QCommonStyle):
'itemPixmapRect', 'itemTextRect', 'polish', 'styleHint',
'subControlRect', 'unpolish', 'drawItemText',
'sizeFromContents', 'drawPrimitive']:
- target = getattr(self._style, method)
- setattr(self, method, functools.partial(target))
+ setattr(self, method, functools.partial(self._fusion_call, method))
super().__init__()
+ def _fusion_call(self, method: str, *args: Any) -> Any:
+ """Wrap a call to self._style to log RuntimeErrors.
+
+ WORKAROUND for https://github.com/qutebrowser/qutebrowser/issues/5124
+ """
+ target = getattr(self._style, method)
+ try:
+ return target(*args)
+ except RuntimeError:
+ info = f"self._style.{method}{args}"
+ log.misc.warning(f"Got RuntimeError while calling {info}")
+ raise
+
def _draw_indicator(self, layouts, opt, p):
"""Draw the tab indicator.
diff --git a/qutebrowser/misc/checkpyver.py b/qutebrowser/misc/checkpyver.py
index 7d6a524c3..82fe3d70f 100644
--- a/qutebrowser/misc/checkpyver.py
+++ b/qutebrowser/misc/checkpyver.py
@@ -49,7 +49,9 @@ def check_python_version():
version_str = '.'.join(map(str, sys.version_info[:3]))
text = ("At least Python 3.7 is required to run qutebrowser, but " +
"it's running with " + version_str + ".\n")
- if Tk and '--no-err-windows' not in sys.argv: # pragma: no cover
+
+ show_errors = '--no-err-windows' not in sys.argv
+ if Tk and show_errors: # type: ignore[truthy-function] # pragma: no cover
root = Tk()
root.withdraw()
messagebox.showerror("qutebrowser: Fatal error!", text)
diff --git a/qutebrowser/misc/guiprocess.py b/qutebrowser/misc/guiprocess.py
index 8fcfb2803..3a6ab156a 100644
--- a/qutebrowser/misc/guiprocess.py
+++ b/qutebrowser/misc/guiprocess.py
@@ -266,18 +266,21 @@ class GUIProcess(QObject):
QProcess.ProcessError.WriteError: f"Write error for {what}",
QProcess.ProcessError.ReadError: f"Read error for {what}",
}
- error_string = self._proc.errorString()
- msg = ': '.join([error_descriptions[error], error_string])
# We can't get some kind of error code from Qt...
# https://bugreports.qt.io/browse/QTBUG-44769
# but we pre-resolve the executable in Python, which also checks if it's
# runnable.
- if self.resolved_cmd is None: # pragma: no branch
- msg += f'\nHint: Make sure {self.cmd!r} exists and is executable'
+ if self.resolved_cmd is None:
+ # No point in showing the "No program defined" we got due to
+ # passing None into Qt.
+ error_string = f"{self.cmd!r} doesn't exist or isn't executable"
if version.is_flatpak():
- msg += ' inside the Flatpak container'
+ error_string += " inside the Flatpak container"
+ else: # pragma: no cover
+ error_string = self._proc.errorString()
+ msg = ': '.join([error_descriptions[error], error_string])
message.error(msg)
def _elide_output(self, output: str) -> str:
diff --git a/qutebrowser/utils/objreg.py b/qutebrowser/utils/objreg.py
index 3b6823df4..58ac18b16 100644
--- a/qutebrowser/utils/objreg.py
+++ b/qutebrowser/utils/objreg.py
@@ -170,7 +170,7 @@ def _get_tab_registry(win_id: _WindowTab,
window: Optional[QWidget] = QApplication.activeWindow()
if window is None or not hasattr(window, 'win_id'):
raise RegistryUnavailableError('tab')
- win_id = window.win_id # type: ignore[attr-defined]
+ win_id = window.win_id
elif win_id is None:
raise TypeError("window is None with scope tab!")
diff --git a/qutebrowser/utils/utils.py b/qutebrowser/utils/utils.py
index ddd82cb76..bd2746337 100644
--- a/qutebrowser/utils/utils.py
+++ b/qutebrowser/utils/utils.py
@@ -55,7 +55,7 @@ try:
CSafeDumper as YamlDumper)
YAML_C_EXT = True
except ImportError: # pragma: no cover
- from yaml import (SafeLoader as YamlLoader, # type: ignore[misc]
+ from yaml import (SafeLoader as YamlLoader, # type: ignore[assignment]
SafeDumper as YamlDumper)
YAML_C_EXT = False
diff --git a/requirements.txt b/requirements.txt
index fe6001ae4..cc254cf60 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,14 +1,15 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
adblock==0.6.0
-colorama==0.4.5
-importlib-metadata==4.12.0 ; python_version=="3.7.*"
-importlib-resources==5.9.0 ; python_version=="3.7.*" or python_version=="3.8.*"
+colorama==0.4.6
+importlib-metadata==5.0.0 ; python_version=="3.7.*"
+importlib-resources==5.10.0 ; python_version=="3.7.*" or python_version=="3.8.*"
Jinja2==3.1.2
MarkupSafe==2.1.1
Pygments==2.13.0
-pyobjc-core==8.5 ; sys_platform=="darwin"
-pyobjc-framework-Cocoa==8.5 ; sys_platform=="darwin"
PyYAML==6.0
-typing_extensions==4.3.0 ; python_version<"3.8"
-zipp==3.8.1
+typing_extensions==4.4.0 ; python_version<"3.8"
+zipp==3.10.0
+# Unpinned due to recompile_requirements.py limitations
+pyobjc-core ; sys_platform=="darwin"
+pyobjc-framework-Cocoa ; sys_platform=="darwin"
diff --git a/scripts/asciidoc2html.py b/scripts/asciidoc2html.py
index ba8493247..1b904736d 100755
--- a/scripts/asciidoc2html.py
+++ b/scripts/asciidoc2html.py
@@ -73,7 +73,7 @@ class AsciiDoc:
def cleanup(self) -> None:
"""Clean up the temporary home directory for asciidoc."""
if self._homedir is not None and not self._failed:
- shutil.rmtree(str(self._homedir))
+ shutil.rmtree(self._homedir)
def build(self) -> None:
"""Build either the website or the docs."""
@@ -119,7 +119,7 @@ class AsciiDoc:
for filename in ['cheatsheet-big.png', 'cheatsheet-small.png']:
src = REPO_ROOT / 'doc' / 'img' / filename
dst = dst_path / filename
- shutil.copy(str(src), str(dst))
+ shutil.copy(src, dst)
def _build_website_file(self, root: pathlib.Path, filename: str) -> None:
"""Build a single website file."""
@@ -131,7 +131,7 @@ class AsciiDoc:
assert self._tempdir is not None # for mypy
modified_src = self._tempdir / src.name
- shutil.copy(str(REPO_ROOT / 'www' / 'header.asciidoc'), modified_src)
+ shutil.copy(REPO_ROOT / 'www' / 'header.asciidoc', modified_src)
outfp = io.StringIO()
diff --git a/scripts/dev/changelog_urls.json b/scripts/dev/changelog_urls.json
index 69e847818..f19112f17 100644
--- a/scripts/dev/changelog_urls.json
+++ b/scripts/dev/changelog_urls.json
@@ -8,7 +8,6 @@
"mccabe": "https://github.com/PyCQA/mccabe#changes",
"pytest-cov": "https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst",
"pytest-xdist": "https://github.com/pytest-dev/pytest-xdist/blob/master/CHANGELOG.rst",
- "pytest-forked": "https://github.com/pytest-dev/pytest-forked/blob/master/CHANGELOG.rst",
"pytest-xvfb": "https://github.com/The-Compiler/pytest-xvfb/blob/master/CHANGELOG.rst",
"PyVirtualDisplay": "https://github.com/ponty/PyVirtualDisplay/commits/master",
"execnet": "https://execnet.readthedocs.io/en/latest/changelog.html",
@@ -24,11 +23,10 @@
"soupsieve": "https://facelessuser.github.io/soupsieve/about/changelog/",
"Flask": "https://flask.palletsprojects.com/en/latest/changes/",
"Mako": "https://docs.makotemplates.org/en/latest/changelog.html",
- "glob2": "https://github.com/miracle2k/python-glob2/blob/master/CHANGES",
"hypothesis": "https://hypothesis.readthedocs.io/en/latest/changes.html",
"exceptiongroup": "https://github.com/agronholm/exceptiongroup/blob/main/CHANGES.rst",
"mypy": "https://mypy-lang.blogspot.com/",
- "types-PyYAML": "https://github.com/python/typeshed/commits/master/stubs/PyYAML",
+ "types-PyYAML": "https://github.com/python/typeshed/commits/main/stubs/PyYAML",
"pytest": "https://docs.pytest.org/en/latest/changelog.html",
"iniconfig": "https://github.com/pytest-dev/iniconfig/blob/master/CHANGELOG",
"tox": "https://tox.readthedocs.io/en/latest/changelog.html",
@@ -150,6 +148,7 @@
"bleach": "https://github.com/mozilla/bleach/blob/main/CHANGES",
"jeepney": "https://gitlab.com/takluyver/jeepney/-/blob/master/docs/release-notes.rst",
"keyring": "https://github.com/jaraco/keyring/blob/main/CHANGES.rst",
+ "jaraco.classes": "https://github.com/jaraco/jaraco.classes/blob/main/CHANGES.rst",
"pkginfo": "https://bazaar.launchpad.net/~tseaver/pkginfo/trunk/view/head:/CHANGES.txt",
"readme-renderer": "https://github.com/pypa/readme_renderer/blob/main/CHANGES.rst",
"requests-toolbelt": "https://github.com/requests/toolbelt/blob/master/HISTORY.rst",
diff --git a/scripts/dev/ci/docker/Dockerfile.j2 b/scripts/dev/ci/docker/Dockerfile.j2
index 1af90283c..90804d08e 100644
--- a/scripts/dev/ci/docker/Dockerfile.j2
+++ b/scripts/dev/ci/docker/Dockerfile.j2
@@ -15,7 +15,8 @@ RUN pacman -Suyy --noconfirm \
{% else %}
qt5-base \
qt5-declarative \
- {% if webengine %}qt5-webengine python-pyqt5-webengine{% else %}qt5-webkit{% endif %} \
+ {% if webengine %}
+ qt5-webengine python-pyqtwebengine \
python-pyqt5 \
{% endif %}
xorg-xinit \
@@ -25,6 +26,18 @@ RUN pacman -Suyy --noconfirm \
libyaml \
xorg-xdpyinfo
+{% if not webengine %}
+RUN pacman -U --noconfirm \
+ https://archive.archlinux.org/packages/q/qt5-webkit/qt5-webkit-5.212.0alpha4-18-x86_64.pkg.tar.zst \
+ https://archive.archlinux.org/packages/p/python-pyqt5/python-pyqt5-5.15.7-2-x86_64.pkg.tar.zst
+{% endif %}
+
+{% if webengine %}
+RUN python3 -c "from PyQt5 import QtWebEngineCore, QtWebEngineWidgets"
+{% else %}
+RUN python3 -c "from PyQt5 import QtWebKit, QtWebKitWidgets"
+{% endif %}
+
RUN useradd user -u 1001 && \
mkdir /home/user && \
chown user:users /home/user
diff --git a/scripts/dev/ci/docker/generate.py b/scripts/dev/ci/docker/generate.py
index 00ba34a78..763a04ecf 100644
--- a/scripts/dev/ci/docker/generate.py
+++ b/scripts/dev/ci/docker/generate.py
@@ -27,7 +27,7 @@ import jinja2
def main():
with open('Dockerfile.j2') as f:
- template = jinja2.Template(f.read())
+ template = jinja2.Template(f.read(), trim_blocks=True, lstrip_blocks=True)
image = sys.argv[1]
config = {
diff --git a/scripts/dev/misc_checks.py b/scripts/dev/misc_checks.py
index 0e015e03d..c5c20a593 100644
--- a/scripts/dev/misc_checks.py
+++ b/scripts/dev/misc_checks.py
@@ -38,7 +38,7 @@ from scripts import utils
from scripts.dev import recompile_requirements
BINARY_EXTS = {'.png', '.icns', '.ico', '.bmp', '.gz', '.bin', '.pdf',
- '.sqlite', '.woff2', '.whl'}
+ '.sqlite', '.woff2', '.whl', '.egg'}
def _get_files(
@@ -64,7 +64,7 @@ def _get_files(
continue
try:
- with tokenize.open(str(path)):
+ with tokenize.open(path):
pass
except SyntaxError as e:
# Could not find encoding
@@ -275,7 +275,7 @@ def check_spelling(args: argparse.Namespace) -> Optional[bool]:
try:
ok = True
for path in _get_files(verbose=args.verbose, ignored=ignored):
- with tokenize.open(str(path)) as f:
+ with tokenize.open(path) as f:
if not _check_spelling_file(path, f, patterns):
ok = False
print()
@@ -325,7 +325,7 @@ def check_vcs_conflict(args: argparse.Namespace) -> Optional[bool]:
if path.suffix in {'.rst', '.asciidoc'}:
# False positives
continue
- with tokenize.open(str(path)) as f:
+ with tokenize.open(path) as f:
for line in f:
if any(line.startswith(c * 7) for c in '<>=|'):
print("Found conflict marker in {}".format(path))
diff --git a/scripts/dev/ua_fetch.py b/scripts/dev/ua_fetch.py
index 6e5bc66ac..743cd252e 100644
--- a/scripts/dev/ua_fetch.py
+++ b/scripts/dev/ua_fetch.py
@@ -42,6 +42,7 @@ def wrap(ini, sub, string):
return textwrap.wrap(string, width=80, initial_indent=ini, subsequent_indent=sub)
+# pylint: disable-next=missing-timeout
response = requests.get('https://raw.githubusercontent.com/Kikobeats/top-user-agents/master/index.json')
if response.status_code != 200:
diff --git a/scripts/dictcli.py b/scripts/dictcli.py
index a937fd31d..0b14bb831 100755
--- a/scripts/dictcli.py
+++ b/scripts/dictcli.py
@@ -40,7 +40,7 @@ from qutebrowser.config import configdata
from qutebrowser.utils import standarddir
-API_URL = 'https://chromium.googlesource.com/chromium/deps/hunspell_dictionaries.git/+/master/'
+API_URL = 'https://chromium.googlesource.com/chromium/deps/hunspell_dictionaries.git/+/main/'
class InvalidLanguageError(Exception):
diff --git a/scripts/mkvenv.py b/scripts/mkvenv.py
index 8d0a26a17..cc9c9403d 100755
--- a/scripts/mkvenv.py
+++ b/scripts/mkvenv.py
@@ -197,7 +197,7 @@ def delete_old_venv(venv_dir: pathlib.Path) -> None:
'remove it.'.format(venv_dir))
print_command('rm -r', venv_dir, venv=False)
- shutil.rmtree(str(venv_dir))
+ shutil.rmtree(venv_dir)
def create_venv(venv_dir: pathlib.Path, use_virtualenv: bool = False) -> None:
diff --git a/tests/conftest.py b/tests/conftest.py
index c74d67566..134f967e9 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -22,6 +22,7 @@
import os
import pathlib
import sys
+import ssl
import pytest
import hypothesis
@@ -122,6 +123,10 @@ def _apply_platform_markers(config, item):
f"Only runs on Qt 6, not {machinery.WRAPPER}"),
('qt5_xfail', pytest.mark.xfail, machinery.IS_QT5, "Fails on Qt 5"),
('qt6_xfail', pytest.mark.skipif, machinery.IS_QT6, "Fails on Qt 6"),
+ ('qtwebkit_openssl3_skip',
+ pytest.mark.skipif,
+ not config.webengine and ssl.OPENSSL_VERSION_INFO[0] == 3,
+ "Failing due to cheroot: https://github.com/cherrypy/cheroot/issues/346"),
]
for searched_marker, new_marker_kind, condition, default_reason in markers:
diff --git a/tests/end2end/features/prompts.feature b/tests/end2end/features/prompts.feature
index 6802a93ef..f4ed605f9 100644
--- a/tests/end2end/features/prompts.feature
+++ b/tests/end2end/features/prompts.feature
@@ -171,6 +171,7 @@ Feature: Prompts
Then the error "Certificate error: *" should be shown
And the page should contain the plaintext "Hello World via SSL!"
+ @qtwebkit_openssl3_skip
Scenario: SSL error with content.tls.certificate_errors = block
When I clear SSL errors
And I set content.tls.certificate_errors to block
@@ -186,6 +187,7 @@ Feature: Prompts
And I wait until the SSL page finished loading
Then the page should contain the plaintext "Hello World via SSL!"
+ @qtwebkit_openssl3_skip
Scenario: SSL error with content.tls.certificate_errors = ask -> no
When I clear SSL errors
And I set content.tls.certificate_errors to ask
@@ -194,6 +196,7 @@ Feature: Prompts
And I run :prompt-accept no
Then a SSL error page should be shown
+ @qtwebkit_openssl3_skip
Scenario: SSL error with content.tls.certificate_errors = ask -> abort
When I clear SSL errors
And I set content.tls.certificate_errors to ask
@@ -221,6 +224,7 @@ Feature: Prompts
Then the javascript message "Script loaded" should be logged
And the page should contain the plaintext "Script loaded"
+ @qtwebkit_openssl3_skip
Scenario: SSL resource error with content.tls.certificate_errors = ask -> no
When I clear SSL errors
And I set content.tls.certificate_errors to ask
@@ -231,6 +235,7 @@ Feature: Prompts
Then the javascript message "Script loaded" should not be logged
And the page should contain the plaintext "Script not loaded"
+ @qtwebkit_openssl3_skip
Scenario: SSL resource error with content.tls.certificate_errors = ask-block-thirdparty
When I clear SSL errors
And I set content.tls.certificate_errors to ask-block-thirdparty
diff --git a/tests/end2end/features/test_downloads_bdd.py b/tests/end2end/features/test_downloads_bdd.py
index f19133d35..72f420141 100644
--- a/tests/end2end/features/test_downloads_bdd.py
+++ b/tests/end2end/features/test_downloads_bdd.py
@@ -38,7 +38,7 @@ def download_dir(tmpdir):
downloads.ensure(dir=True)
(downloads / 'subdir').ensure(dir=True)
try:
- os.mkfifo(str(downloads / 'fifo'))
+ os.mkfifo(downloads / 'fifo')
except AttributeError:
pass
unwritable = downloads / 'unwritable'
@@ -79,7 +79,7 @@ def download_ssl_redirect(server, ssl_server, quteproc):
@bdd.when("the unwritable dir is unwritable")
def check_unwritable(tmpdir):
unwritable = tmpdir / 'downloads' / 'unwritable'
- if os.access(str(unwritable), os.W_OK):
+ if os.access(unwritable, os.W_OK):
# Docker container or similar
pytest.skip("Unwritable dir was writable")
@@ -173,4 +173,4 @@ def delete_file(tmpdir, filename):
def fifo_should_be_fifo(tmpdir):
download_dir = tmpdir / 'downloads'
assert download_dir.exists()
- assert not os.path.isfile(str(download_dir / 'fifo'))
+ assert not os.path.isfile(download_dir / 'fifo')
diff --git a/tests/end2end/features/test_history_bdd.py b/tests/end2end/features/test_history_bdd.py
index f2e018b9f..a68c7d621 100644
--- a/tests/end2end/features/test_history_bdd.py
+++ b/tests/end2end/features/test_history_bdd.py
@@ -67,4 +67,5 @@ def check_history(quteproc, server, tmpdir, expected):
@bdd.then("the history should be empty")
def check_history_empty(quteproc, server, tmpdir):
+ quteproc.wait_for(message='DELETE FROM History', category='sql')
check_history(quteproc, server, tmpdir, '')
diff --git a/tests/helpers/fixtures.py b/tests/helpers/fixtures.py
index b46deaa4e..d4744c67d 100644
--- a/tests/helpers/fixtures.py
+++ b/tests/helpers/fixtures.py
@@ -36,7 +36,7 @@ import os.path
import dataclasses
import pytest
-import py.path # pylint: disable=no-name-in-module
+import py.path
from qutebrowser.qt.core import QSize, Qt
from qutebrowser.qt.widgets import QWidget, QHBoxLayout, QVBoxLayout
from qutebrowser.qt.network import QNetworkCookieJar
@@ -639,7 +639,7 @@ def redirect_webengine_data(data_tmpdir, monkeypatch):
def short_tmpdir():
"""A short temporary directory for a XDG_RUNTIME_DIR."""
with tempfile.TemporaryDirectory() as tdir:
- yield py.path.local(tdir) # pylint: disable=no-member
+ yield py.path.local(tdir)
class ModelValidator:
@@ -720,7 +720,7 @@ def state_config(data_tmpdir, monkeypatch):
@pytest.fixture
def unwritable_tmp_path(tmp_path):
tmp_path.chmod(0)
- if os.access(str(tmp_path), os.W_OK):
+ if os.access(tmp_path, os.W_OK):
# Docker container or similar
pytest.skip("Directory was still writable")
diff --git a/tests/helpers/testutils.py b/tests/helpers/testutils.py
index 574c57cb0..0c8cdb8d0 100644
--- a/tests/helpers/testutils.py
+++ b/tests/helpers/testutils.py
@@ -220,11 +220,11 @@ def nop_contextmanager():
def change_cwd(path):
"""Use a path as current working directory."""
old_cwd = pathlib.Path.cwd()
- os.chdir(str(path))
+ os.chdir(path)
try:
yield
finally:
- os.chdir(str(old_cwd))
+ os.chdir(old_cwd)
@contextlib.contextmanager
diff --git a/tests/unit/browser/test_pdfjs.py b/tests/unit/browser/test_pdfjs.py
index e9ca51796..d002a3823 100644
--- a/tests/unit/browser/test_pdfjs.py
+++ b/tests/unit/browser/test_pdfjs.py
@@ -178,7 +178,7 @@ def unreadable_file(tmpdir):
unreadable_file = tmpdir / 'unreadable'
unreadable_file.ensure()
unreadable_file.chmod(0)
- if os.access(str(unreadable_file), os.R_OK):
+ if os.access(unreadable_file, os.R_OK):
# Docker container or similar
pytest.skip("File was still readable")
diff --git a/tests/unit/browser/test_qutescheme.py b/tests/unit/browser/test_qutescheme.py
index 499b2c584..3caee5621 100644
--- a/tests/unit/browser/test_qutescheme.py
+++ b/tests/unit/browser/test_qutescheme.py
@@ -23,7 +23,7 @@ import os
import time
import logging
-import py.path # pylint: disable=no-name-in-module
+import py.path
from qutebrowser.qt.core import QUrl, QUrlQuery
import pytest
@@ -223,7 +223,7 @@ class TestPDFJSHandler:
@pytest.fixture
def download_tmpdir(self):
tdir = downloads.temp_download_manager.get_tmpdir()
- yield py.path.local(tdir.name) # pylint: disable=no-member
+ yield py.path.local(tdir.name)
tdir.cleanup()
def test_existing_resource(self):
diff --git a/tests/unit/browser/webkit/network/test_filescheme.py b/tests/unit/browser/webkit/network/test_filescheme.py
index 3f0a4dfa0..4f9d22108 100644
--- a/tests/unit/browser/webkit/network/test_filescheme.py
+++ b/tests/unit/browser/webkit/network/test_filescheme.py
@@ -48,7 +48,7 @@ def test_get_file_list(tmpdir, create_file, create_dir, filterfunc, expected):
if create_file or create_dir:
path.ensure(dir=create_dir)
- all_files = os.listdir(str(tmpdir))
+ all_files = os.listdir(tmpdir)
result = filescheme.get_file_list(str(tmpdir), all_files, filterfunc)
item = {'name': 'foo', 'absname': str(path)}
diff --git a/tests/unit/commands/test_userscripts.py b/tests/unit/commands/test_userscripts.py
index 9d8d65fd6..bc83ed499 100644
--- a/tests/unit/commands/test_userscripts.py
+++ b/tests/unit/commands/test_userscripts.py
@@ -201,6 +201,10 @@ def test_killed_command(qtbot, tmp_path, py_proc, runner, caplog):
runner.store_text('Hello World')
runner.store_html('')
+ # For some reason, this tends to be flaky on Windows, and we got the
+ # directoryChanged signal *without* the file existing (wut?)...
+ qtbot.wait_until(data_file.exists)
+
# Make sure the PID was written to the file, not just the file created
time.sleep(0.5)
diff --git a/tests/unit/config/test_configfiles.py b/tests/unit/config/test_configfiles.py
index 05b823f99..6c14c86c3 100644
--- a/tests/unit/config/test_configfiles.py
+++ b/tests/unit/config/test_configfiles.py
@@ -596,7 +596,7 @@ class TestYaml:
def unreadable_autoconfig(self, autoconfig):
autoconfig.fobj.ensure()
autoconfig.fobj.chmod(0)
- if os.access(str(autoconfig.fobj), os.R_OK):
+ if os.access(autoconfig.fobj, os.R_OK):
# Docker container or similar
pytest.skip("File was still readable")
diff --git a/tests/unit/mainwindow/statusbar/test_backforward.py b/tests/unit/mainwindow/statusbar/test_backforward.py
index d3e033b34..ac73f8ee1 100644
--- a/tests/unit/mainwindow/statusbar/test_backforward.py
+++ b/tests/unit/mainwindow/statusbar/test_backforward.py
@@ -31,55 +31,72 @@ def backforward_widget(qtbot):
return widget
+@pytest.fixture
+def tabs(tabbed_browser_stubs):
+ tabbed_browser = tabbed_browser_stubs[0]
+ tabbed_browser.widget.current_index = 1
+ return tabbed_browser
+
+
@pytest.mark.parametrize('can_go_back, can_go_forward, expected_text', [
(False, False, ''),
(True, False, '[<]'),
(False, True, '[>]'),
(True, True, '[<>]'),
])
-def test_backforward_widget(backforward_widget, tabbed_browser_stubs,
- fake_web_tab, can_go_back, can_go_forward,
- expected_text):
+def test_widget_state(backforward_widget, tabs,
+ fake_web_tab, can_go_back, can_go_forward,
+ expected_text):
"""Ensure the Backforward widget shows the correct text."""
tab = fake_web_tab(can_go_back=can_go_back, can_go_forward=can_go_forward)
- tabbed_browser = tabbed_browser_stubs[0]
- tabbed_browser.widget.current_index = 1
- tabbed_browser.widget.tabs = [tab]
+ tabs.widget.tabs = [tab]
backforward_widget.enabled = True
- backforward_widget.on_tab_cur_url_changed(tabbed_browser)
+ backforward_widget.on_tab_cur_url_changed(tabs)
assert backforward_widget.text() == expected_text
assert backforward_widget.isVisible() == bool(expected_text)
- # Check that the widget stays hidden if not in the statusbar
- backforward_widget.enabled = False
- backforward_widget.hide()
- backforward_widget.on_tab_cur_url_changed(tabbed_browser)
- assert backforward_widget.isHidden()
- # Check that the widget gets reset if empty.
- if can_go_back and can_go_forward:
- tab = fake_web_tab(can_go_back=False, can_go_forward=False)
- tabbed_browser.widget.tabs = [tab]
- backforward_widget.enabled = True
- backforward_widget.on_tab_cur_url_changed(tabbed_browser)
- assert backforward_widget.text() == ''
- assert not backforward_widget.isVisible()
+def test_state_changes_on_tab_change(backforward_widget, tabs, fake_web_tab):
+ """Test we go invisible when switching to a tab without history."""
+ tab_with_history = fake_web_tab(can_go_back=True, can_go_forward=True)
+ tab_without_history = fake_web_tab(can_go_back=False, can_go_forward=False)
+ tabs.widget.tabs = [tab_with_history]
+ backforward_widget.enabled = True
+
+ backforward_widget.on_tab_cur_url_changed(tabs)
+ assert backforward_widget.isVisible()
+
+ tabs.widget.tabs = [tab_without_history]
+ backforward_widget.on_tab_cur_url_changed(tabs)
+ assert backforward_widget.text() == ''
+ assert not backforward_widget.isVisible()
-def test_none_tab(backforward_widget, tabbed_browser_stubs, fake_web_tab):
+def test_none_tab(backforward_widget, tabs, fake_web_tab):
"""Make sure nothing crashes when passing None as tab."""
tab = fake_web_tab(can_go_back=True, can_go_forward=True)
- tabbed_browser = tabbed_browser_stubs[0]
- tabbed_browser.widget.current_index = 1
- tabbed_browser.widget.tabs = [tab]
+ tabs.widget.tabs = [tab]
backforward_widget.enabled = True
- backforward_widget.on_tab_cur_url_changed(tabbed_browser)
+ backforward_widget.on_tab_cur_url_changed(tabs)
assert backforward_widget.text() == '[<>]'
assert backforward_widget.isVisible()
- tabbed_browser.widget.current_index = -1
- backforward_widget.on_tab_cur_url_changed(tabbed_browser)
+ tabs.widget.current_index = -1
+ backforward_widget.on_tab_cur_url_changed(tabs)
assert backforward_widget.text() == ''
assert not backforward_widget.isVisible()
+
+
+def test_not_shown_when_disabled(backforward_widget, tabs, fake_web_tab):
+ """The widget shouldn't get shown on an event when it's disabled."""
+ tab = fake_web_tab(can_go_back=True, can_go_forward=True)
+ tabs.widget.tabs = [tab]
+
+ backforward_widget.enabled = False
+ backforward_widget.on_tab_cur_url_changed(tabs)
+ assert not backforward_widget.isVisible()
+
+ backforward_widget.on_tab_changed(tab)
+ assert not backforward_widget.isVisible()
diff --git a/tests/unit/mainwindow/statusbar/test_progress.py b/tests/unit/mainwindow/statusbar/test_progress.py
index 888ed5943..1cc3bf9af 100644
--- a/tests/unit/mainwindow/statusbar/test_progress.py
+++ b/tests/unit/mainwindow/statusbar/test_progress.py
@@ -69,6 +69,14 @@ def test_tab_changed(fake_web_tab, progress_widget, progress, load_status,
assert actual == expected
+def test_not_shown_when_disabled(progress_widget, fake_web_tab):
+ """The widget shouldn't get shown on an event when it's disabled."""
+ tab = fake_web_tab(progress=15, load_status=usertypes.LoadStatus.loading)
+ progress_widget.enabled = False
+ progress_widget.on_tab_changed(tab)
+ assert not progress_widget.isVisible()
+
+
def test_progress_affecting_statusbar_height(config_stub, fake_statusbar,
progress_widget):
"""Make sure the statusbar stays the same height when progress is shown.
diff --git a/tests/unit/misc/test_editor.py b/tests/unit/misc/test_editor.py
index 628ee8545..4fd915062 100644
--- a/tests/unit/misc/test_editor.py
+++ b/tests/unit/misc/test_editor.py
@@ -128,7 +128,7 @@ class TestFileHandling:
filename = pathlib.Path(editor._filename)
assert filename.exists()
filename.chmod(0o277)
- if os.access(str(filename), os.R_OK):
+ if os.access(filename, os.R_OK):
# Docker container or similar
pytest.skip("File was still readable")
diff --git a/tests/unit/misc/test_guiprocess.py b/tests/unit/misc/test_guiprocess.py
index 702a1dca8..d225ab2e2 100644
--- a/tests/unit/misc/test_guiprocess.py
+++ b/tests/unit/misc/test_guiprocess.py
@@ -403,16 +403,15 @@ def test_failing_to_start(qtbot, proc, caplog, message_mock, monkeypatch, is_fla
with qtbot.wait_signal(proc.error, timeout=5000):
proc.start('this_does_not_exist_either', [])
+ expected_msg = (
+ "Testprocess 'this_does_not_exist_either' failed to start:"
+ " 'this_does_not_exist_either' doesn't exist or isn't executable"
+ )
+ if is_flatpak:
+ expected_msg += " inside the Flatpak container"
+
msg = message_mock.getmsg(usertypes.MessageLevel.error)
- assert msg.text.startswith(
- "Testprocess 'this_does_not_exist_either' failed to start:")
-
- if not utils.is_windows:
- expected_msg = (
- "Hint: Make sure 'this_does_not_exist_either' exists and is executable")
- if is_flatpak:
- expected_msg += ' inside the Flatpak container'
- assert msg.text.endswith(expected_msg)
+ assert msg.text == expected_msg
assert not proc.outcome.running
assert proc.outcome.status is None