Merge branch 'master' into qt6-v2
Just a few conflicts around CI and dependencies.
This commit is contained in:
commit
2d66466194
|
|
@ -0,0 +1,6 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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/
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()]
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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!")
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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, '')
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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)}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
|
|
@ -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', [])
|
||||
|
||||
msg = message_mock.getmsg(usertypes.MessageLevel.error)
|
||||
assert msg.text.startswith(
|
||||
"Testprocess 'this_does_not_exist_either' failed to start:")
|
||||
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"
|
||||
|
||||
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)
|
||||
msg = message_mock.getmsg(usertypes.MessageLevel.error)
|
||||
assert msg.text == expected_msg
|
||||
|
||||
assert not proc.outcome.running
|
||||
assert proc.outcome.status is None
|
||||
|
|
|
|||
Loading…
Reference in New Issue