Merge branch 'master' into qt6-v2

This commit is contained in:
Florian Bruhin 2022-12-13 09:05:32 +01:00
commit b4d32e04f4
43 changed files with 203 additions and 225 deletions

View File

@ -75,7 +75,12 @@ jobs:
python -m pip install -U pip
python -m pip install -U -r misc/requirements/requirements-tox.txt
- name: "Run ${{ matrix.testenv }}"
run: "dbus-run-session -- tox -e ${{ matrix.testenv}} -- ${{ matrix.args }}"
run: |
if [[ -z "${{ matrix.args }}" ]]; then
dbus-run-session -- tox -e ${{ matrix.testenv }}
else
dbus-run-session -- tox -e ${{ matrix.testenv }} -- ${{ matrix.args }}
fi
tests-docker:
if: "!contains(github.event.head_commit.message, '[ci skip]')"

View File

@ -75,15 +75,6 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Get asciidoc
uses: actions/checkout@v3
with:
repository: asciidoc-py/asciidoc-py
ref: '9.x'
path: asciidoc
persist-credentials: false
- name: Move asciidoc out of the repo
run: mv asciidoc ..
- name: Install dependencies
run: |
python -m pip install -U pip
@ -93,7 +84,7 @@ jobs:
run: |
sed -i '' '/.-d., .--debug.,/s/$/ default=True,/' qutebrowser/qutebrowser.py
- name: Run tox
run: "tox -e ${{ matrix.toxenv }} -- --asciidoc ../asciidoc/asciidoc.py --gh-token ${{ secrets.GITHUB_TOKEN }} ${{ matrix.args }}"
run: "tox -e ${{ matrix.toxenv }} -- --gh-token ${{ secrets.GITHUB_TOKEN }} ${{ matrix.args }}"
- name: Gather info
id: info
run: |

View File

@ -127,6 +127,13 @@ Fixed
v2.5.3 (unreleased)
-------------------
Added
~~~~~
- New `array_at` quirk, polyfilling the
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at[`Array.at` method],
which is needed by various websites, but only natively available with Qt 6.2.
Fixed
~~~~~
@ -599,13 +606,13 @@ Changed
- When a shown message replaces an existing related one (e.g. for zoom levels),
the replacing now also works even if a different message was shown in between.
- The `.redirect(...)` method on interceptors now supports an
`ignore_unsupported=True` argument which supresses exceptions if a request could
`ignore_unsupported=True` argument which suppresses exceptions if a request could
not be redirected. Note, however, that it is still not public API.
- When the `--config-py` argument is used, no warning about a missing
`config.load_autoconfig` is shown anymore, as the argument is typically used
for temporarily testing a config.
- The internal `_autosave` session used for crash recovery is now only saved
once per minute, since saving it for every page load is a noticable performance
once per minute, since saving it for every page load is a noticeable performance
issue.
- The `readability-js` userscript now displays a small header with page
information.
@ -1033,7 +1040,7 @@ Changed
- `config.py` files now are required to have either
`config.load_autoconfig(False)` (don't load `autoconfig.yml`) or
`config.load_autoconfig()` (do load `autoconfig.yml`) in them.
- Various host-blocking settings have been renamed to accomodate the new ABP-like
- Various host-blocking settings have been renamed to accommodate the new ABP-like
adblocker:
* `content.host_blocking.enabled` -> `content.blocking.enabled` (controlling both blockers)
* `content.host_blocking.whitelist` -> `content.blocking.whitelist` (controlling both blockers)
@ -1209,11 +1216,11 @@ Fixed
~~~~~
- Setting the `content.headers.referer` setting to `same-domain` (the default)
was supposed to truncate referers to only the host with QtWebEngine.
was supposed to truncate referrers to only the host with QtWebEngine.
Unfortunately, this functionality broke in Qt 5.14. It works properly again
with this release, including a test so this won't happen again.
- With QtWebEngine 5.15, setting the `content.headers.referer` setting to
`never` did still send referers. This is now fixed as well.
`never` did still send referrers. This is now fixed as well.
- In v1.14.0, a regression was introduced, causing a crash when qutebrowser was
closed after opening a download with PDF.js. This is now fixed.
- With Qt 5.12, the `Object.fromEntries` JavaScript API is unavailable (it was
@ -1230,7 +1237,7 @@ Fixed
conversion was shown. This is now fixed.
- Ever since Qt 5.11, fetching more completion data when that data is loaded
lazily (such as with history) and the last visible item is selected was broken.
The exact reason is currently unknown, but this release adds a tenative fix.
The exact reason is currently unknown, but this release adds a tentative fix.
- When PgUp/PgDown were used to go beyond the last visible item, the above issue
caused a crash, which is now also fixed.
- As a workaround for an overzealous Microsoft Defender false-positive detecting
@ -1346,9 +1353,9 @@ Changed
which fixes issues with e.g. formulas on Wikipedia.
- The `readability-js` userscript now adds some CSS to improve the reader mode
styling in various scenarios:
* Images are now shrinked to the page width, similarly to what Firefox' reader
* Images are now shrunk to the page width, similarly to what Firefox' reader
mode does.
* Some images ore now displayed as block (rather than inline) which is what
* Some images are now displayed as block (rather than inline) which is what
Firefox' reader mode does as well.
* Blockquotes are now styled more distinctively, again based on the Firefox
reader mode.
@ -3170,7 +3177,7 @@ Fixed
- Fix workaround for black screens or crashes with Nvidia cards
- Handle a filesystem going read-only gracefully
- Fix crash when setting `fonts.monospace`
- Fix list options not being modifyable via `.append()` in `config.py`
- Fix list options not being modifiable via `.append()` in `config.py`
- Mark the content.notifications setting as QtWebKit only correctly
- Fix wrong rendering of keys like `<back>` in the completion
@ -3206,7 +3213,7 @@ Major changes
* New dependency on the QtSql module and Qt sqlite support.
* New dependency on the https://www.attrs.org/[attrs] project (packaged as
`python-attr` in some distributions).
* The depedency on PyOpenGL (when using QtWebEngine) got removed. Note
* The dependency on PyOpenGL (when using QtWebEngine) got removed. Note
that PyQt5.QtOpenGL is still a dependency.
* PyQt5.QtOpenGL is now always required, even with QtWebKit.
- The QtWebEngine backend is now used by default. Note this means that
@ -4427,7 +4434,7 @@ Changed
* Add `-s`/`--space` argument to `:set-cmd-text` (as `:set-cmd-text "foo "` will now set the literal text `"foo "`)
- Ignore `;;` for splitting with some commands like `:bind`.
- Add unbound (new) default keybindings to config. This also adds a new `<unbound>` special command.
* To unbind a command keybinding without binding it to a new key, you now have to bind it to `<unbound>` or it'll be readded automatically.
* To unbind a command keybinding without binding it to a new key, you now have to bind it to `<unbound>` or it'll be re-added automatically.
- If an SSL error is raised multiple times with the same error/certificate/host/scheme/port, the user is only asked once.
- Jump to last instead of first item when pressing Shift-Tab the first time in the completion.
- Add a fullscreen keybinding.

View File

@ -170,7 +170,7 @@ 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
runs as a separate 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.:
+
@ -376,7 +376,7 @@ There is a total of four possible approaches to get dark websites:
How do I make copy to clipboard buttons work?::
You can `:set content.javascript.clipboard access` to allow this globally (not
recommended!), or `:set -u some.domain content.javascript.clipboad access` if
recommended!), or `:set -u some.domain content.javascript.clipboard access` if
you want to limit the setting to `some.domain`.

View File

@ -48,7 +48,7 @@ instructions!
Note you'll need some basic libraries to use the virtualenv-installed PyQt:
----
# apt install --no-install-recommends git ca-certificates python3 python3-venv asciidoc libglib2.0-0 libgl1 libfontconfig1 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 libxcb-xfixes0 libxcb-xinerama0 libxcb-xkb1 libxkbcommon-x11-0 libdbus-1-3 libyaml-dev gcc python3-dev libnss3 libasound2
# apt install --no-install-recommends git ca-certificates python3 python3-venv libglib2.0-0 libgl1 libfontconfig1 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 libxcb-xfixes0 libxcb-xinerama0 libxcb-xkb1 libxkbcommon-x11-0 libdbus-1-3 libyaml-dev gcc python3-dev libnss3 libasound2
----
// FIXME not needed anymore?
@ -72,7 +72,7 @@ qutebrowser in a virtualenv>> with a newer PyQt/Qt binary instead.
Note you'll need some basic libraries to use the virtualenv-installed PyQt:
----
# apt install --no-install-recommends git ca-certificates python3 python3-venv asciidoc libglib2.0-0 libgl1 libfontconfig1 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 libxcb-xfixes0 libxcb-xinerama0 libxcb-xkb1 libxkbcommon-x11-0 libdbus-1-3 libyaml-dev gcc python3-dev libnss3 libasound2
# apt install --no-install-recommends git ca-certificates python3 python3-venv libglib2.0-0 libgl1 libfontconfig1 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 libxcb-xfixes0 libxcb-xinerama0 libxcb-xkb1 libxkbcommon-x11-0 libdbus-1-3 libyaml-dev gcc python3-dev libnss3 libasound2
----
Ubuntu 20.04 LTS / Linux Mint 20 (or newer)
@ -93,7 +93,7 @@ Additional hints
this for you):
+
----
# apt install --no-install-recommends asciidoc
$ pip install -r misc/requirements/requirements-docs.txt # or install asciidoc manually
$ python3 scripts/asciidoc2html.py
----
@ -292,7 +292,7 @@ Nightly builds
If you want to test out new features before an official qutebrowser release, automated
https://github.com/qutebrowser/qutebrowser/actions/workflows/nightly.yml[nightly
builds] are available. To download them, open the lastest run (usually the first one),
builds] are available. To download them, open the latest run (usually the first one),
then download the archive at the bottom of the page.
Those builds also include variants with debug logging enabled, which can be useful to
@ -369,7 +369,7 @@ Nightly builds
If you want to test out new features before an official qutebrowser release, automated
https://github.com/qutebrowser/qutebrowser/actions/workflows/nightly.yml[nightly
builds] are available. To download them, open the lastest run (usually the first one),
builds] are available. To download them, open the latest run (usually the first one),
then download the archive at the bottom of the page.
Those builds also include variants with debug logging enabled, which can be useful to
@ -514,18 +514,6 @@ You can create a simple wrapper script to start qutebrowser somewhere in your
~/path/to/qutebrowser/.venv/bin/python3 -m qutebrowser "$@"
----
Building the docs
~~~~~~~~~~~~~~~~~
To build the documentation, install `asciidoc` (note that LaTeX which comes as
optional/recommended dependency with some distributions is not required).
Then, run:
----
$ python3 scripts/asciidoc2html.py
----
Updating
~~~~~~~~

View File

@ -1,8 +1,7 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
build==0.9.0
check-manifest==0.48
packaging==21.3
check-manifest==0.49
packaging==22.0
pep517==0.13.0
pyparsing==3.0.9
tomli==2.0.1

View File

@ -3,30 +3,29 @@
bleach==5.0.1
build==0.9.0
bump2version==1.0.1
certifi==2022.9.24
certifi==2022.12.7
cffi==1.15.1
charset-normalizer==2.1.1
commonmark==0.9.1
cryptography==38.0.3
cryptography==38.0.4
docutils==0.19
github3.py==3.2.0
hunter==3.5.1
idna==3.4
importlib-metadata==5.0.0
importlib-metadata==5.1.0
jaraco.classes==3.2.3
jeepney==0.8.0
keyring==23.11.0
manhole==1.8.0
more-itertools==9.0.0
packaging==21.3
packaging==22.0
pep517==0.13.0
pkginfo==1.8.3
pkginfo==1.9.2
ply==3.11
pycparser==2.21
Pygments==2.13.0
PyJWT==2.6.0
Pympler==1.0.1
pyparsing==3.0.9
PyQt-builder==1.14.0
python-dateutil==2.8.2
readme-renderer==37.3
@ -35,13 +34,13 @@ requests-toolbelt==0.10.1
rfc3986==2.0.0
rich==12.6.0
SecretStorage==3.3.3
sip==6.7.4
sip==6.7.5
six==1.16.0
toml==0.10.2
tomli==2.0.1
twine==4.0.1
twine==4.0.2
typing_extensions==4.4.0
uritemplate==4.1.1
# urllib3==1.26.12
# urllib3==1.26.13
webencodings==0.5.1
zipp==3.10.0
zipp==3.11.0

View File

@ -0,0 +1,3 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
asciidoc==10.2.0

View File

@ -0,0 +1 @@
asciidoc

View File

@ -1,11 +1,10 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
attrs==22.1.0
flake8==5.0.4
flake8-bugbear==22.10.27
flake8==6.0.0
flake8-bugbear==22.12.6
flake8-builtins==2.0.1
flake8-comprehensions==3.10.1
flake8-copyright==0.2.3
flake8-debugger==4.1.2
flake8-deprecated==2.0.1
flake8-docstrings==1.6.0
@ -17,8 +16,8 @@ flake8-tidy-imports==4.8.0
flake8-tuple==0.4.1
mccabe==0.7.0
pep8-naming==0.13.2
pycodestyle==2.9.1
pycodestyle==2.10.0
pydocstyle==6.1.1
pyflakes==2.5.0
pyflakes==3.0.1
six==1.16.0
snowballstemmer==2.2.0

View File

@ -5,7 +5,8 @@ flake8-comprehensions
flake8-debugger
flake8-deprecated!=2.0.0
flake8-docstrings
flake8-copyright
# https://github.com/savoirfairelinux/flake8-copyright/issues/19
# flake8-copyright
flake8-future-import
# https://github.com/aleGpereira/flake8-mock/issues/10
# flake8-mock

View File

@ -1,13 +1,13 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
chardet==5.0.0
diff-cover==7.0.2
importlib-metadata==5.0.0
importlib-resources==5.10.0
chardet==5.1.0
diff-cover==7.3.0
importlib-metadata==5.1.0
importlib-resources==5.10.1
Jinja2==3.1.2
lxml==4.9.1
MarkupSafe==2.1.1
mypy==0.990
mypy==0.991
mypy-extensions==0.4.3
pluggy==1.0.0
Pygments==2.13.0
@ -15,4 +15,4 @@ PyQt5-stubs==5.15.6.0
tomli==2.0.1
types-PyYAML==6.0.12.2
typing_extensions==4.4.0
zipp==3.10.0
zipp==3.11.0

View File

@ -1,5 +1,5 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
altgraph==0.17.3
pyinstaller==5.6.2
pyinstaller-hooks-contrib==2022.13
pyinstaller==5.7.0
pyinstaller-hooks-contrib==2022.14

View File

@ -1,10 +1,10 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
astroid==2.12.12
certifi==2022.9.24
astroid==2.12.13
certifi==2022.12.7
cffi==1.15.1
charset-normalizer==2.1.1
cryptography==38.0.3
cryptography==38.0.4
dill==0.3.6
future==0.18.2
github3.py==3.2.0
@ -13,10 +13,10 @@ isort==5.10.1
lazy-object-proxy==1.8.0
mccabe==0.7.0
pefile==2022.5.30
platformdirs==2.5.4
platformdirs==2.6.0
pycparser==2.21
PyJWT==2.6.0
pylint==2.15.5
pylint==2.15.8
python-dateutil==2.8.2
./scripts/dev/pylint_checkers
requests==2.28.1
@ -26,5 +26,5 @@ tomlkit==0.11.6
typed-ast==1.5.4 ; python_version<"3.8"
typing_extensions==4.4.0
uritemplate==4.1.1
# urllib3==1.26.12
# urllib3==1.26.13
wrapt==1.14.1

View File

@ -1,15 +1,15 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
build==0.9.0
certifi==2022.9.24
certifi==2022.12.7
charset-normalizer==2.1.1
docutils==0.19
idna==3.4
packaging==21.3
packaging==22.0
pep517==0.13.0
Pygments==2.13.0
pyparsing==3.0.9
pyroma==4.0
pyroma==4.1
requests==2.28.1
tomli==2.0.1
urllib3==1.26.12
trove-classifiers==2022.12.1
urllib3==1.26.13

View File

@ -2,17 +2,16 @@
alabaster==0.7.12
Babel==2.11.0
certifi==2022.9.24
certifi==2022.12.7
charset-normalizer==2.1.1
docutils==0.19
idna==3.4
imagesize==1.4.1
importlib-metadata==5.0.0
importlib-metadata==5.1.0
Jinja2==3.1.2
MarkupSafe==2.1.1
packaging==21.3
packaging==22.0
Pygments==2.13.0
pyparsing==3.0.9
pytz==2022.6
requests==2.28.1
snowballstemmer==2.2.0
@ -23,5 +22,5 @@ sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
urllib3==1.26.12
zipp==3.10.0
urllib3==1.26.13
zipp==3.11.0

View File

@ -9,9 +9,7 @@ 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
# 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-instafail.git
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

View File

@ -2,34 +2,33 @@
attrs==22.1.0
beautifulsoup4==4.11.1
certifi==2022.9.24
certifi==2022.12.7
charset-normalizer==2.1.1
cheroot==8.6.0
cheroot==9.0.0
click==8.1.3
coverage==6.5.0
exceptiongroup==1.0.2
exceptiongroup==1.0.4
execnet==1.9.0
filelock==3.8.0
filelock==3.8.2
Flask==2.2.2
hunter==3.5.1
hypothesis==6.56.4
hypothesis==6.61.0
idna==3.4
importlib-metadata==5.0.0
importlib-metadata==5.1.0
iniconfig==1.1.1
itsdangerous==2.1.2
jaraco.functools==3.5.2
# Jinja2==3.1.2
Mako==1.2.3
Mako==1.2.4
manhole==1.8.0
# MarkupSafe==2.1.1
more-itertools==9.0.0
packaging==21.3
packaging==22.0
parse==1.19.0
parse-type==0.6.0
pluggy==1.0.0
py-cpuinfo==9.0.0
Pygments==2.13.0
pyparsing==3.0.9
pytest==7.2.0
pytest-bdd==6.1.1
pytest-benchmark==4.0.0
@ -38,8 +37,8 @@ pytest-instafail==0.4.2
pytest-mock==3.10.0
pytest-qt==4.2.0
pytest-repeat==0.9.1
pytest-rerunfailures==10.2
pytest-xdist==3.0.2
pytest-rerunfailures==10.3
pytest-xdist==3.1.0
pytest-xvfb==2.0.0
PyVirtualDisplay==3.0
requests==2.28.1
@ -51,7 +50,7 @@ tldextract==3.4.0
toml==0.10.2
tomli==2.0.1
typing_extensions==4.4.0
urllib3==1.26.12
urllib3==1.26.13
vulture==2.6
Werkzeug==2.2.2
zipp==3.10.0
zipp==3.11.0

View File

@ -1,16 +1,17 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
cachetools==5.2.0
chardet==5.1.0
colorama==0.4.6
distlib==0.3.6
filelock==3.8.0
packaging==21.3
filelock==3.8.2
packaging==22.0
pip==22.3.1
platformdirs==2.5.4
platformdirs==2.6.0
pluggy==1.0.0
py==1.11.0
pyparsing==3.0.9
setuptools==65.5.1
six==1.16.0
pyproject_api==1.2.1
setuptools==65.6.3
tomli==2.0.1
tox==3.27.0
virtualenv==20.16.7
tox==4.0.8
virtualenv==20.17.1
wheel==0.38.4

View File

@ -1,5 +1,5 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
pathspec==0.10.2
pathspec==0.10.3
PyYAML==6.0
yamllint==1.28.0

View File

@ -143,6 +143,7 @@ no_entries_found() {
# expected to write the username of that entry to the $username variable and
# the corresponding password to $password
# shellcheck disable=SC2317
reset_backend() {
init() { true ; }
query_entries() { true ; }
@ -198,7 +199,7 @@ choose_entry_zenity() {
}
choose_entry_zenity_radio() {
zenity_helper() {
zenity_helper() { # shellcheck disable=SC2317
awk '{ print $0 ; print $0 }' \
| zenity --list --radiolist \
--title "qutebrowser password fill" \
@ -278,6 +279,7 @@ pass_backend() {
# =======================================================
# backend: secret
# shellcheck disable=SC2317
secret_backend() {
init() {
return

View File

@ -19,7 +19,7 @@
"""Completion category for filesystem paths.
NOTE: This module deliberatly uses os.path rather than pathlib, because of how
NOTE: This module deliberately uses os.path rather than pathlib, because of how
it interacts with the completion, which operates on strings. For example, we
need to be able to tell the difference between "~/input" and "~/input/". Also,
if we get "~/input", we want to glob "~/input*" rather than "~/input/*" which

View File

@ -109,7 +109,7 @@ class change_filter: # noqa: N801,N806 pylint: disable=invalid-name
and calls the wrapped function if we are.
We assume the function passed doesn't take any parameters. However, it
could take a "self" argument, so we can't cleary express this in the
could take a "self" argument, so we can't clearly express this in the
type above.
Args:
@ -188,7 +188,7 @@ class KeyConfig:
def get_reverse_bindings_for(self, mode: str) -> '_ReverseBindings':
"""Get a dict of commands to a list of bindings for the mode.
This is intented for user-facing display of keybindings.
This is intended for user-facing display of keybindings.
As such, bindings for 'set-cmd-text [flags] :<cmd> ...' are translated
to '<cmd> ...', as from the user's perspective these keys behave like
bindings for '<cmd>' (that allow for further input before running).

View File

@ -412,7 +412,7 @@ class MainWindow(QWidget):
self._set_decoration(config.val.window.hide_decoration)
def _add_widgets(self):
"""Add or readd all widgets to the VBox."""
"""Add or re-add all widgets to the VBox."""
self._vbox.removeWidget(self.tabbed_browser.widget)
self._vbox.removeWidget(self._downloadview)
self._vbox.removeWidget(self.status)

View File

@ -752,9 +752,21 @@ class FilenamePrompt(_BasePrompt):
self._file_view.setColumnHidden(col, True)
# Nothing selected initially
self._file_view.setCurrentIndex(QModelIndex())
# The model needs to be sorted so we get the correct first/last index
self._file_model.directoryLoaded.connect(
lambda: self._file_model.sort(0))
self._file_model.directoryLoaded.connect(self.on_directory_loaded)
@pyqtSlot()
def on_directory_loaded(self):
"""Sort the model after a directory gets loaded.
The model needs to be sorted so we get the correct first/last index.
NOTE: This needs to be a proper @pystSlot() function, and not a lambda.
Otherwise, PyQt seems to fail to disconnect it immediately after the
object gets destroyed, and we get segfaults when deleting the directory
in unit tests.
"""
self._file_model.sort(0)
def accept(self, value=None, save=False):
self._check_save_support(save)

View File

@ -2,14 +2,14 @@
adblock==0.6.0
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.*"
importlib-metadata==5.1.0 ; python_version=="3.7.*"
importlib-resources==5.10.1 ; python_version=="3.7.*" or python_version=="3.8.*"
Jinja2==3.1.2
MarkupSafe==2.1.1
Pygments==2.13.0
PyYAML==6.0
typing_extensions==4.4.0 ; python_version<"3.8"
zipp==3.10.0
zipp==3.11.0
# Unpinned due to recompile_requirements.py limitations
pyobjc-core ; sys_platform=="darwin"
pyobjc-framework-Cocoa ; sys_platform=="darwin"

View File

@ -20,7 +20,7 @@
"""Generate the html documentation based on the asciidoc files."""
from typing import List, Optional
from typing import Optional
import re
import os
import sys
@ -48,13 +48,7 @@ class AsciiDoc:
'install', 'stacktrace'
]
def __init__(self,
asciidoc: Optional[str],
asciidoc_python: Optional[str],
website: Optional[str]) -> None:
self._cmd: Optional[List[str]] = None
self._asciidoc = asciidoc
self._asciidoc_python = asciidoc_python
def __init__(self, website: Optional[str]) -> None:
self._website = website
self._homedir: Optional[pathlib.Path] = None
self._themedir: Optional[pathlib.Path] = None
@ -63,7 +57,6 @@ class AsciiDoc:
def prepare(self) -> None:
"""Get the asciidoc command and create the homedir to use."""
self._cmd = self._get_asciidoc_cmd()
self._homedir = pathlib.Path(tempfile.mkdtemp())
self._themedir = self._homedir / '.asciidoc' / 'themes' / 'qute'
self._tempdir = self._homedir / 'tmp'
@ -224,26 +217,6 @@ class AsciiDoc:
except FileExistsError:
pass
def _get_asciidoc_cmd(self) -> List[str]:
"""Try to find out what commandline to use to invoke asciidoc."""
if self._asciidoc is not None:
python = (sys.executable if self._asciidoc_python is None
else self._asciidoc_python)
return [python, self._asciidoc]
for executable in ['asciidoc', 'asciidoc.py']:
try:
subprocess.run([executable, '--version'],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
check=True)
except OSError:
pass
else:
return [executable]
raise FileNotFoundError
def call(self, src: pathlib.Path, dst: pathlib.Path, *args):
"""Call asciidoc for the given files.
@ -253,8 +226,7 @@ class AsciiDoc:
*args: Additional arguments passed to asciidoc.
"""
print("Calling asciidoc for {}...".format(src.name))
assert self._cmd is not None # for mypy
cmdline = self._cmd[:]
cmdline = [sys.executable, "-m", "asciidoc"]
if dst is not None:
cmdline += ['--out-file', str(dst)]
cmdline += args
@ -281,12 +253,6 @@ def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument('--website', help="Build website into a given "
"directory.")
parser.add_argument('--asciidoc', help="Full path to asciidoc.py. "
"If not given, it's searched in PATH.",
nargs='?')
parser.add_argument('--asciidoc-python', help="Python to use for asciidoc."
"If not given, the current Python interpreter is used.",
nargs='?')
return parser.parse_args()
@ -298,9 +264,8 @@ def run(**kwargs) -> None:
try:
asciidoc.prepare()
except FileNotFoundError:
utils.print_error("Could not find asciidoc! Please install it, or use "
"the --asciidoc argument to point this script to "
"the correct asciidoc.py location!")
utils.print_error("Could not find asciidoc! Please install it, e.g. via "
"pip install -r misc/requirements/requirements-docs.txt")
sys.exit(1)
try:
@ -314,8 +279,7 @@ def main(colors: bool = False) -> None:
utils.change_cwd()
utils.use_color = colors
args = parse_args()
run(asciidoc=args.asciidoc, asciidoc_python=args.asciidoc_python,
website=args.website)
run(website=args.website)
if __name__ == '__main__':

View File

@ -100,15 +100,10 @@ def call_tox(
env=env, check=True)
def run_asciidoc2html(args: argparse.Namespace) -> None:
def run_asciidoc2html() -> None:
"""Run the asciidoc2html script."""
utils.print_title("Running asciidoc2html.py")
a2h_args = []
if args.asciidoc is not None:
a2h_args += ['--asciidoc', args.asciidoc]
if args.asciidoc_python is not None:
a2h_args += ['--asciidoc-python', args.asciidoc_python]
call_script('asciidoc2html.py', *a2h_args)
call_script('asciidoc2html.py')
def _maybe_remove(path: pathlib.Path) -> None:
@ -724,12 +719,6 @@ def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument('--skip-docs', action='store_true',
help="Don't generate docs")
parser.add_argument('--asciidoc', help="Full path to asciidoc.py. "
"If not given, it's searched in PATH.",
nargs='?')
parser.add_argument('--asciidoc-python', help="Python to use for asciidoc."
"If not given, the current Python interpreter is used.",
nargs='?')
parser.add_argument('--gh-token', help="GitHub token to use.",
nargs='?')
parser.add_argument('--upload', action='store_true', required=False,
@ -766,7 +755,7 @@ def main() -> None:
if args.skip_docs:
pathlib.Path("qutebrowser", "html", "doc").mkdir(parents=True, exist_ok=True)
else:
run_asciidoc2html(args)
run_asciidoc2html()
if IS_WINDOWS:
artifacts = build_windows(

View File

@ -1,5 +1,4 @@
{
"pyparsing": "https://github.com/pyparsing/pyparsing/blob/master/CHANGES",
"pylint": "https://pylint.pycqa.org/en/latest/whatsnew/2/index.html",
"tomlkit": "https://github.com/sdispater/tomlkit/blob/master/CHANGELOG.md",
"dill": "https://github.com/uqfoundation/dill/commits/master",
@ -30,6 +29,8 @@
"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",
"cachetools": "https://github.com/tkem/cachetools/blob/master/CHANGELOG.rst",
"pyproject_api": "https://pyproject-api.readthedocs.io/en/latest/changelog.html",
"PyYAML": "https://github.com/yaml/pyyaml/blob/master/CHANGES",
"pytest-bdd": "https://github.com/pytest-dev/pytest-bdd/blob/master/CHANGES.rst",
"snowballstemmer": "https://github.com/snowballstem/snowball/blob/master/NEWS",
@ -47,7 +48,6 @@
"flake8-tidy-imports": "https://github.com/adamchainz/flake8-tidy-imports/blob/main/HISTORY.rst",
"flake8-tuple": "https://github.com/ar4s/flake8_tuple/blob/master/HISTORY.rst",
"flake8-comprehensions": "https://github.com/adamchainz/flake8-comprehensions/blob/main/HISTORY.rst",
"flake8-copyright": "https://github.com/savoirfairelinux/flake8-copyright/blob/master/CHANGELOG.rst",
"flake8-deprecated": "https://github.com/gforcada/flake8-deprecated/blob/master/CHANGES.rst",
"flake8-future-import": "https://github.com/xZise/flake8-future-import#changes",
"flake8-string-format": "https://github.com/xZise/flake8-string-format#changes",
@ -78,7 +78,6 @@
"sphinxcontrib-serializinghtml": "https://www.sphinx-doc.org/en/master/changes.html",
"jaraco.functools": "https://github.com/jaraco/jaraco.functools/blob/main/CHANGES.rst",
"parse": "https://github.com/r1chardj0n3s/parse#potential-gotchas",
"py": "https://py.readthedocs.io/en/latest/changelog.html#changelog",
"Pympler": "https://github.com/pympler/pympler/blob/master/CHANGELOG.md",
"pytest-mock": "https://github.com/pytest-dev/pytest-mock/blob/main/CHANGELOG.rst",
"pytest-qt": "https://github.com/pytest-dev/pytest-qt/blob/master/CHANGELOG.rst",
@ -160,5 +159,7 @@
"rich": "https://github.com/Textualize/rich/blob/master/CHANGELOG.md",
"ply": "https://github.com/dabeaz/ply/blob/master/CHANGES",
"pyobjc-core": "https://pyobjc.readthedocs.io/en/latest/changelog.html",
"pyobjc-framework-Cocoa": "https://pyobjc.readthedocs.io/en/latest/changelog.html"
"pyobjc-framework-Cocoa": "https://pyobjc.readthedocs.io/en/latest/changelog.html",
"trove-classifiers": "https://github.com/pypa/trove-classifiers/commits/main",
"asciidoc": "https://asciidoc-py.github.io/CHANGELOG.html"
}

View File

@ -29,6 +29,11 @@ RUN pacman -Suyy --noconfirm \
libyaml \
xorg-xdpyinfo
# WORKAROUND for https://bugs.archlinux.org/task/76720
{% if unstable %}
RUN pacman -U --noconfirm https://archlinux.org/packages/extra/x86_64/mesa/download/
{% endif %}
{% 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 \

View File

@ -165,7 +165,7 @@ def check_spelling(args: argparse.Namespace) -> Optional[bool]:
'artefact', 'an unix', 'an utf', 'an unicode', 'unparseable',
'dependancies', 'convertable', 'chosing', 'authentification'}
# Words which look better when splitted, but might need some fine tuning.
# Words which look better when split, but might need some fine tuning.
words |= {'webelements', 'mouseevent', 'keysequence', 'normalmode',
'eventloops', 'sizehint', 'statemachine', 'metaobject',
'logrecord'}

View File

@ -81,8 +81,7 @@ if __name__ == "__main__":
"tox -e build-release -- --upload"
.format(v=version))
print("* Windows: git fetch; git checkout v{v}; "
"py -3.9 -m tox -e build-release -- --asciidoc "
"$env:userprofile\\bin\\asciidoc-9.1.0\\asciidoc.py --upload"
"py -3.9 -m tox -e build-release -- --upload"
.format(v=version))
print("* macOS: git fetch && git checkout v{v} && "
"tox -e build-release -- --upload"

View File

@ -31,7 +31,7 @@ import shutil
import venv as pyvenv
import subprocess
import platform
from typing import List, Optional, Tuple, Dict, Union
from typing import List, Tuple, Dict, Union
sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir))
from scripts import utils, link_pyqt
@ -92,9 +92,6 @@ def parse_args(argv: List[str] = None) -> argparse.Namespace:
parser.add_argument('--virtualenv',
action='store_true',
help="Use virtualenv instead of venv.")
parser.add_argument('--asciidoc', help="Full path to asciidoc.py. "
"If not given, asciidoc is searched in PATH.",
nargs='?',)
parser.add_argument('--dev',
action='store_true',
help="Also install dev/test dependencies.")
@ -475,17 +472,14 @@ def install_qutebrowser(venv_dir: pathlib.Path) -> None:
pip_install(venv_dir, '-e', str(REPO_ROOT))
def regenerate_docs(venv_dir: pathlib.Path, asciidoc: Optional[str]):
def regenerate_docs(venv_dir: pathlib.Path):
"""Regenerate docs using asciidoc."""
utils.print_title("Generating documentation")
if asciidoc is not None:
a2h_args = ['--asciidoc', asciidoc]
else:
a2h_args = []
script_path = pathlib.Path(__file__).parent / 'asciidoc2html.py'
pip_install(venv_dir, '-r', str(requirements_file('docs')))
print_command('python3 scripts/asciidoc2html.py', *a2h_args, venv=True)
run_venv(venv_dir, 'python', str(script_path), *a2h_args)
script_path = pathlib.Path(__file__).parent / 'asciidoc2html.py'
print_command('python3 scripts/asciidoc2html.py', venv=True)
run_venv(venv_dir, 'python', str(script_path))
def update_repo():
@ -558,7 +552,7 @@ def run(args) -> None:
if args.pyqt_type != 'skip' and not args.skip_smoke_test:
run_qt_smoke_test(venv_dir, pyqt_version=args.pyqt_version)
if not args.skip_docs:
regenerate_docs(venv_dir, args.asciidoc)
regenerate_docs(venv_dir)
def main():

View File

@ -11,7 +11,7 @@ Feature: Miscellaneous utility commands exposed to the user.
Scenario: :later before
When I run :later 500 scroll down
Then the page should not be scrolled
# wait for scroll to execture so we don't ruin our future
# wait for scroll to execute so we don't ruin our future
And the page should be scrolled vertically
Scenario: :later after

View File

@ -846,7 +846,7 @@ def test_unavailable_backend(request, quteproc_new):
def test_json_logging_without_debug(request, quteproc_new, runtime_tmpdir):
args = _base_args(request.config) + ['--temp-basedir', ':quit']
args.remove('--debug')
args.remove('about:blank') # interfers with :quit at the end
args.remove('about:blank') # interferes with :quit at the end
quteproc_new.exit_expected = True
quteproc_new.start(args, env={'XDG_RUNTIME_DIR': str(runtime_tmpdir)})

View File

@ -26,10 +26,9 @@ from qutebrowser.browser import navigate
from qutebrowser.utils import urlutils
@pytest.mark.usefixtures('config_stub')
class TestIncDec:
pytestmark = pytest.mark.usefixtures('config_stub')
@pytest.mark.parametrize('incdec', ['increment', 'decrement'])
@pytest.mark.parametrize('value', [
'{}foo', 'foo{}', 'foo{}bar', '42foo{}'

View File

@ -678,10 +678,9 @@ class TestIsVisibleIframe:
assert not invalid_objects.elems[1]._is_visible(invalid_objects.frame)
@pytest.mark.usefixtures('config_stub')
class TestRectOnView:
pytestmark = pytest.mark.usefixtures('config_stub')
@pytest.mark.parametrize('js_rect', [
None, # real geometry via getElementRects
{}, # no geometry at all via getElementRects

View File

@ -196,7 +196,7 @@ def _set_cmd_prompt(cmd, txt):
marks=pytest.mark.xfail(reason='issue #74')),
(':set -t -p |', 'section', '', []),
(':open -- |', None, '', []),
(':gibberish nonesense |', None, '', []),
(':gibberish nonsense |', None, '', []),
('/:help|', None, '', []),
('::bind|', 'command', ':bind', []),
(':-w open |', None, '', []),

View File

@ -36,7 +36,8 @@ def hist(data_tmpdir, config_stub):
db = sql.Database(str(data_tmpdir / 'test_histcategory.db'))
config_stub.val.completion.timestamp_format = '%Y-%m-%d'
config_stub.val.completion.web_history.max_items = -1
return sql.SqlTable(db, 'CompletionHistory', ['url', 'title', 'last_atime'])
yield sql.SqlTable(db, 'CompletionHistory', ['url', 'title', 'last_atime'])
db.close() # pytest could re-use the filename
@pytest.mark.parametrize('pattern, before, after', [

View File

@ -522,13 +522,12 @@ class TestUnsetAndClear:
assert yaml_value(name) == (usertypes.UNSET if save else 'never')
@pytest.mark.usefixtures('config_tmpdir', 'data_tmpdir',
'config_stub', 'key_config_stub')
class TestSource:
"""Test :config-source."""
pytestmark = pytest.mark.usefixtures('config_tmpdir', 'data_tmpdir',
'config_stub', 'key_config_stub')
@pytest.mark.parametrize('location', ['default', 'absolute', 'relative'])
@pytest.mark.parametrize('clear', [True, False])
def test_config_source(self, tmp_path, commands, config_stub, config_tmpdir,
@ -606,14 +605,13 @@ class TestSource:
assert str(excinfo.value) == expected
@pytest.mark.usefixtures('config_tmpdir', 'data_tmpdir',
'config_stub', 'key_config_stub',
'qapp')
class TestEdit:
"""Tests for :config-edit."""
pytestmark = pytest.mark.usefixtures('config_tmpdir', 'data_tmpdir',
'config_stub', 'key_config_stub',
'qapp')
def test_no_source(self, commands, mocker):
mock = mocker.patch('qutebrowser.config.configcommands.editor.'
'ExternalEditor._start_editor', autospec=True)

View File

@ -942,10 +942,9 @@ def confpy(tmp_path, config_tmpdir, data_tmpdir, config_stub, key_config_stub):
return ConfPy(tmp_path)
@pytest.mark.usefixtures('config_stub', 'key_config_stub')
class TestConfigPyModules:
pytestmark = pytest.mark.usefixtures('config_stub', 'key_config_stub')
@pytest.fixture
def qbmodulepy(self, tmp_path):
return ConfPy(tmp_path, filename="qbmodule.py")
@ -1002,12 +1001,11 @@ class TestConfigPyModules:
assert sys.path.count(tmp_path) == 1
@pytest.mark.usefixtures('config_stub', 'key_config_stub')
class TestConfigPy:
"""Tests for ConfigAPI and read_config_py()."""
pytestmark = pytest.mark.usefixtures('config_stub', 'key_config_stub')
def test_assertions(self, confpy):
"""Make sure assertions in config.py work for these tests."""
confpy.write('assert False')

View File

@ -59,6 +59,12 @@ from qutebrowser.config import configdata
2,
id='array-at',
),
pytest.param(
QUrl("https://test.qutebrowser.org/linkedin"),
'[1, 2, 3].at(1)',
2,
id='array-at',
),
])
def test_js_quirks(config_stub, js_tester_webengine, base_url, source, expected):
config_stub.val.content.site_specific_quirks.skip = []

37
tox.ini
View File

@ -16,7 +16,20 @@ setenv =
pyqt{62,63,64}: PYTEST_QT_API=pyqt6
pyqt{62,63,64}: QUTE_QT_WRAPPER=PyQt6
cov: PYTEST_ADDOPTS=--cov --cov-report xml --cov-report=html --cov-report=
passenv = PYTHON DISPLAY XAUTHORITY HOME USERNAME USER CI XDG_* QUTE_* DOCKER QT_QUICK_BACKEND FORCE_COLOR DBUS_SESSION_BUS_ADDRESS
passenv =
PYTHON
DISPLAY
XAUTHORITY
HOME
USERNAME
USER
CI
XDG_*
QUTE_*
DOCKER
QT_QUICK_BACKEND
FORCE_COLOR
DBUS_SESSION_BUS_ADDRESS
basepython =
py: {env:PYTHON:python3}
py3: {env:PYTHON:python3}
@ -144,10 +157,12 @@ commands =
[testenv:docs]
basepython = {env:PYTHON:python3}
whitelist_externals = git
passenv = CI GITHUB_REF
passenv =
CI
GITHUB_REF
deps =
-r{toxinidir}/requirements.txt
-r{toxinidir}/misc/requirements/requirements-docs.txt
-r{toxinidir}/misc/requirements/requirements-pyqt.txt
commands =
{envpython} scripts/dev/src2asciidoc.py {posargs}
@ -156,7 +171,10 @@ commands =
[testenv:pyinstaller-{64,32}{,-qt6}]
basepython = {env:PYTHON:python3}
passenv = APPDATA HOME PYINSTALLER_DEBUG
passenv =
APPDATA
HOME
PYINSTALLER_DEBUG
setenv =
qt6: PYINSTALLER_QT6=true
deps =
@ -171,19 +189,21 @@ commands =
basepython = python3
deps =
passenv = TERM
whitelist_externals = eslint
allowlist_externals = eslint
changedir = {toxinidir}/qutebrowser/javascript
commands = eslint --report-unused-disable-directives .
[testenv:shellcheck]
basepython = python3
deps =
whitelist_externals = bash
allowlist_externals = bash
commands = bash scripts/dev/run_shellcheck.sh {posargs}
[testenv:mypy-{pyqt5,pyqt6}]
basepython = {env:PYTHON:python3}
passenv = TERM MYPY_FORCE_TERMINAL_WIDTH
passenv =
TERM
MYPY_FORCE_TERMINAL_WIDTH
setenv =
pyqt6: QUTE_CONSTANTS_ARGS=--always-true=USE_PYQT6 --always-false=USE_PYQT5 --always-false=USE_PYSIDE2 --always-false=USE_PYSIDE6 --always-false=IS_QT5 --always-true=IS_QT6
pyqt5: QUTE_CONSTANTS_ARGS=--always-false=USE_PYQT6 --always-true=USE_PYQT5 --always-false=USE_PYSIDE2 --always-false=USE_PYSIDE6 --always-true=IS_QT5 --always-false=IS_QT6
@ -205,7 +225,7 @@ commands =
[testenv:actionlint]
basepython = python3
deps =
whitelist_externals = actionlint
allowlist_externals = actionlint
commands =
actionlint
@ -241,6 +261,7 @@ usedevelop = true
deps =
-r{toxinidir}/requirements.txt
-r{toxinidir}/misc/requirements/requirements-tox.txt
-r{toxinidir}/misc/requirements/requirements-docs.txt
!qt6: -r{toxinidir}/misc/requirements/requirements-pyqt.txt
qt6: -r{toxinidir}/misc/requirements/requirements-pyqt-6.txt
-r{toxinidir}/misc/requirements/requirements-dev.txt