Commit Graph

6298 Commits

Author SHA1 Message Date
Florian Bruhin 2cb20dbf5b Skip test broken on QtWebKit
(cherry picked from commit d01dd9be07bd1591b1ecda298a2bf84b41ea280c)
2022-06-13 21:46:49 +02:00
Florian Bruhin cd1be710de Fix lint with FindFlags change 2022-06-13 19:37:05 +02:00
Florian Bruhin bf045f7ec7 Add a helper dataclass for find flags
When e.g. doing:
- '?foo' (search with reverse=True -> FindBackwards)
- 'N' (prev_result -> no FindBackwards)
- 'n' (next_result -> FindBackwards again)

we need to take a copy of the flags so that we can temporarily clear
FindBackwards when pressing 'N'.

Relevant history:

- We originally did int(self._flags) in
  d450257485.
- In f0da508c21, we used
  QWebPage.FindFlags(int(self._flags)) instead.
- With 97bdcb8e674c8ff27ab92448effef263880ab3aa (picked from
  c349fbd180) we instead do:
  flags = QWebEnginePage.FindFlag(self._flags)

Using FindFlag instead of FindFlags seemed to work fine with PyQt6 and
enum.Flag. With PyQt5, however, later clearing a flag bit ends up with us
getting 0 as an integer, thus losing the type information about this being a
FindFlag instance, and resulting in a TypeError when calling into Qt.

We could use FindFlags() with PyQt 6 but FindFlag() with PyQt 5 to copy the
original flags, but that's getting rather cumbersome. Instead, let's have a
helper dataclass of bools, do away with the bit-twiddling, and only convert it
to a Qt flags when we actually need them. This solves the copying issue nicely,
and also makes the code a lot nicer.

Finally, this also adds a test case which fails when the flags are mutated in
place instead of copied.

We could do the same kind of change for QtWebKit as well, but given that it's
somewhat dead - and perhaps more importantly, won't run with Qt 6 - let's not
bother. To not break the end2end tests with QtWebKit, the output still is the
same as before.

(cherry picked from commit 96a0cc39512753445bc7a01b218b2f1290819ddd)
2022-06-13 18:40:08 +02:00
Florian Bruhin e15bda307e search: Split navigation/search callbacks
This way, we can move more logic (checking wrapping, etc.) into the API,
thus making the commands much more simple and stateless.
2022-06-13 18:40:08 +02:00
Florian Bruhin 583354d524 Merge remote-tracking branch 'origin/pr/6670' into dev 2022-06-13 15:47:31 +02:00
Florian Bruhin fc17602f79 Add test for using :prompt-fileselect-external on wrong prompt 2022-06-13 14:37:27 +02:00
Florian Bruhin 435e880477 Fix test 2022-06-13 14:25:03 +02:00
Florian Bruhin fe2a5529e6 Merge remote-tracking branch 'origin/pr/7003' 2022-06-13 14:06:51 +02:00
Florian Bruhin 85b867fe8d Merge remote-tracking branch 'origin/pr/7096' 2022-06-13 12:34:33 +02:00
Florian Bruhin 6c99fe7b30 pylint: Ignore new false-positives 2022-06-08 12:43:09 +02:00
Florian Bruhin 6c4e281028 pylint: Fix new unnecessary-lambda-assignment 2022-06-08 12:25:12 +02:00
ugla bb9f15056f
Add `[role="treeitem"]` to hintable elements
This makes e.g. channels in Slack's channel list hintable.
2022-05-27 10:38:49 +02:00
Florian Bruhin 9afcad1224 Update content-disposition parsing workaround
Also adds workaround for https://github.com/python/cpython/issues/93010
2022-05-24 11:53:11 +02:00
Florian Bruhin 8ac522cf55 Fix lint 2022-05-20 12:39:52 +02:00
Florian Bruhin 15dc5e81f7 tests: Improve TestSanitizeFilename
Those special cases were only tested by Hypothesis before
2022-05-20 11:01:46 +02:00
Florian Bruhin db1382f75c elf: Ignore garbage data
With qt5-webengine 5.15.9-3 on Arch Linux, there only was a rebuild:
70aa541b4f

but somehow, we now have some kind of garbage data in the .data section:

    ...
    \x00QtWebEngine/5.15.9 Chrome/87.0.4xternalclearkey
    \x00ernalclearkey.diy.differentguid
    \x00Portable Documen/usr/src/debug/qtwebengine/src/core/net/proxying_restricted_cookie_manager_qt.cpp
    \x00
    ...

the *actual* string table only seems to follow much later:

    ...
    \x00display
    \x00\x00dispatchCallbackOnIOThread
    \x00/Cache
    \x00DownloadInterruptReason
    \x00General network failure
    \x00The server has gone down
    \x00General server failure
    \x00Unexpected server response
    \x00Download canceled by the user
    \x00shutdownOnUIThread
    \x00qrc://
    \x00RequestQuotaPermission
    \x00\x00\x00\x00/usr/src/debug/qtwebengine/src/core/quota_permission_context_qt.cpp
    \x00\x00\x00\x00\x00QtWebEngine/5.15.9 Chrome/87.0.4280.144
    \x00 - %04d-%02d-%02dT%0"
    ...

So let's include the NUL bytes in our regex, to make sure we get the full
variant, not the garbage.

(cherry picked from commit 511df8af21ed18a65c49881175814efa72329754)
2022-05-19 08:56:16 +02:00
Florian Bruhin 5e2fe7924e Apply MathML darkmode workaround for display math
See e.g. https://en.wikipedia.org/wiki/Gradient#General_coordinates
2022-05-12 10:10:49 +02:00
Florian Bruhin f2c969da58 Merge branch 'update-dependencies' 2022-05-10 14:47:46 +02:00
Florian Bruhin b6c16f11f2 Update pylint ignores
See https://github.com/PyCQA/astroid/pull/1550 for the signal
disconnect.

Not reporting the gen_classes() one, as we have another ignore for that,
and doing something a bit unorthodox there anyways.
2022-05-10 14:46:39 +02:00
Florian Bruhin dea188d184 Fix lint and coverage 2022-05-09 12:26:23 +02:00
Florian Bruhin a84ecfb80a Display close matches for invalid commands 2022-05-09 11:48:41 +02:00
Florian Bruhin c9380605a1 Display close matches for invalid settings 2022-05-09 11:48:41 +02:00
Florian Bruhin fc57a80ac8 Update YAML C extension check 2022-04-26 17:14:38 +02:00
Florian Bruhin 7932d44dab Fix lint 2022-04-25 17:57:57 +02:00
Florian Bruhin a20bb67a87 mypy: Upgrade to PyQt5-stubs 5.15.6.0
For some unknown reason, those new stubs cause a *lot* of things now to be
checked by mypy which formerly probably got skipped due to Any being implied
somewhere.

The stubs themselves mainly improved, with a couple of regressions too.

In total, there were some 337 (!) new mypy errors. This commit fixes almost all
of them, and the next commit improves a fix to get things down to 0 errors
again.

Overview of the changes:

==== qutebrowser/app.py

- Drop type ignore due to improved stubs.

==== qutebrowser/browser/browsertab.py

- Specify the type of _widget members more closely than just QWidget.
  This is debatable: I suppose the abstract stuff shouldn't need to know
  anything about the concrete backends at all. But it seems like we cut some
  corners when initially implementing things, and put some code in browsertab.py
  just because the APIs of both backends happened to be compatible. Perhaps
  something to reconsider once we drop QtWebKit and hopefully implement a dummy
  backend.

- Add an additional assertion in AbstractAction.run_string. This is already
  covered by the isinstance(member, self.action_base) above it, but that's too
  dynamic for mypy to understand.

- Fix the return type of AbstractScroller.pos_px, which is a QPoint (with x
  and y components), not a single int.

- Fix the return type of AbstractScroller.pos_perc, which is a Tuple (with x
  and y components), not a single int.

- Fix the argument types of AbstractScroller.to_perc, as it's possible to pass
  fractional percentages too.

- Specify the type for AbstractHistoryPrivate._history. See above (_widget) re
  this being debatable.

- Fix the return type of AbstractTabPrivate.event_target(), which can be None
  (see #3888).

- Fix the return type of AbstractTabPrivate.run_js_sync, which is Any (the JS
  return value), not None.

- Fix the argument type for AbstractTabPrivate.toggle_inspector: position can
  be None to use the last used position.

- Declare the type of sub-objects of AbstractTab.

- Fix the return value of AbstractTab.icon(), which is the QIcon, not None.

==== qutebrowser/browser/commands.py

- Make sure the active window is a MainWindow (with a .win_id attribute).

==== qutebrowser/browser/downloadview.py

- Add _model() which makes sure that self.model() is a DownloadModel, not None
  or any other model. This is needed because other methods access a variety of
  custom attributes on it, e.g. last_index().

==== qutebrowser/browser/greasemonkey.py

- Add an ignore for AbstractDownload.requested_url which we patch onto the
  downloads. Probably would be nicer to add it as a proper attribute which always
  gets set by the DownloadManager.

==== qutebrowser/browser/hints.py

- Remove type ignores for QUrl.toString().
- Add a new type ignore for combining different URL flags (which works, but is
  not exactly type safe... still probably a regression in the stubs).
- Make sure the things we get back from self._get_keyparser are what we actually
  expect. Probably should introduce a TypedDict (and/or overloads for
  _get_keyparser with typing.Literal) to teach mypy about the exact return value.
  See #7098.
  This is needed because we access Hint/NormalKeyParser-specific attributes such
  as .set_inhibited_timout() or .update_bindings().

==== qutebrowser/browser/inspector.py

- Similar changes than in browsertab.py to make some types where we share API
  (e.g. .setPage()) more concrete. Didn't work out unfortunately, see next
  commit.

==== qutebrowser/browser/network/pac.py

- Remove now unneeded type ignore for signal.

==== qutebrowser/browser/qtnetworkdownloads.py

- Make sure that downloads is a qtnetworkdownloads.DownloadItem (rather than an
  AbstractDownload), so that we can call ._uses_nam() on it.

==== qutebrowser/browser/qutescheme.py

- Remove now unneeded type ignore for QUrl flags.

==== qutebrowser/browser/urlmarks.py

- Specify the type of UrlMarkManager._lineparser, as those only get initialized
  in _init_lineparser of subclasses, so mypy doesn't know it's supposed to exist.

==== qutebrowser/browser/webelem.py

- New casts to turn single KeyboardModifier (enum) entries into
  KeyboardModifiers (flags). Might not be needed anymore with Qt 6.
- With that, casting the final value is now unneeded.

==== qutebrowser/browser/webengine/notification.py

- Remove now unneeded type ignore for signal.
- Make sure the self.sender() we get in HerbeNotificationAdapter._on_finished()
  is a QProcess, not just any QObject.

==== qutebrowser/browser/webengine/webenginedownloads.py

- Remove now unneeded type ignores for signals.

==== qutebrowser/browser/webengine/webengineelem.py

- Specify the type of WebEngineElement._tab.
- Remove now unneeded type ignore for mixed flags.

==== qutebrowser/browser/webengine/webengineinspector.py

- See changes to inspector.py and next commit.
- Remove now unneeded type ignore for signal.

==== qutebrowser/browser/webengine/webenginequtescheme.py

- Remove now unneeded type ignore for mixed flags.

==== qutebrowser/browser/webengine/webenginesettings.py

- Ignore access of .setter attribute which we patch onto QWebEngineProfile.
  Would be nice to have a subclass or wrapper-class instead.

==== qutebrowser/browser/webengine/webenginetab.py

- Specified the type of _widget members more closely than just QWidget.
  See browsertab.py changes for details.
- Remove some now-unneeded type ignores for creating FindFlags.
- Specify more concrete types for WebEngineTab members where we actually need to
  access WebEngine-specific attributes.
- Make sure the page we get is our custom WebEnginePage subclass, not just any
  QWebEnginePage. This is needed because we access custom attributes on it.

==== qutebrowser/browser/webengine/webview.py

- Make sure the page we get is our custom WebEnginePage subclass, not just any
  QWebEnginePage. This is needed because we access custom attributes on it.

==== qutebrowser/browser/webkit/network/networkreply.py

- Remove now unneeded type ignores for signals.

==== qutebrowser/browser/webkit/webkitinspector.py

- See changes to inspector.py and next commit.

==== qutebrowser/browser/webkit/webkittab.py

- Specify the type of _widget members more closely than just QWidget.
  See browsertab.py changes for details.
- Add a type ignore for WebKitAction because our workaround needs to
  treat them as ints (which is allowed by PyQt, even if not type-safe).
- Add new ignores for findText calls: The text is a QString and can be None; the
  flags are valid despite mypy thinking they aren't (stubs regression?).
- Specify the type for WebKitHistoryPrivate._history, because we access
  WebKit-specific attributes. See above (_widget) re this being debatable.
- Make mypy aware that .currentFrame() and .frameAt() can return None (stubs
  regression?).
- Make sure the .page() and .page().networkAccessManager() are our subclasses
  rather than the more generic QtWebKit objects, as we use custom attributes.
- Add new type ignores for signals (stubs regression!)

==== qutebrowser/browser/webkit/webpage.py

- Make sure the .networkAccessManager() is our subclass rather than the more
  generic QtWebKit object, as we use custom attributes.
- Replace a cast by a type ignore. The cast didn't work anymore.

==== qutebrowser/browser/webkit/webview.py

- Make sure the .page() is our subclass rather than the more generic QtWebKit
  object, as we use custom attributes.

==== qutebrowser/commands/userscripts.py

- Remove now unneeded type ignore for signal.

==== qutebrowser/completion/completer.py

- Add a new _completion() getter (which ensures it actually gets the completion
  view) rather than accessing the .parent() directly (which could be any QObject).

==== qutebrowser/completion/completiondelegate.py

- Make sure self.parent() is a CompletionView (no helper method as there is only
  one instance).
- Remove a now-unneeded type ignore for adding QSizes.

==== qutebrowser/completion/completionwidget.py

- Add a ._model() getter which ensures that we get a CompletionModel (with
  custom attributes) rather than Qt's .model() which can be any QAbstractItemModel
  (or None).
- Removed a now-unneeded type ignore for OR-ing flags.

==== qutebrowser/completion/models/completionmodel.py

- Remove now unneeded type ignores for signals.
- Ignore a complaint about .set_pattern() not being defined. Completion
  categories don't share any common parent class, so it would be good to introduce
  a typing.Protocol for this. See #7098.

==== qutebrowser/components/misccommands.py

- Removed a now-unneeded type ignore for OR-ing flags.

==== qutebrowser/components/readlinecommands.py

- Make sure QApplication.instance() is a QApplication (and not just a
  QCoreApplication). This includes the former "not None" check.

==== qutebrowser/components/scrollcommands.py

- Add basic annotation for "funcs" dict. Could have a callable protocol to
  specify it needs a count kwarg, see #7098.

==== qutebrowser/config/stylesheet.py

- Correctly specify that stylesheet apply to QWidgets, not any QObject.
- Ignore an attr-defined for obj.STYLESHEET. Perhaps could somehow teach mypy
  about this with overloads and protocols (stylesheet for set_register being None
  => STYLESHEET needs to be defined, otherwise anything goes), but perhaps not
  worth the troble. See #7098.

==== qutebrowser/keyinput/keyutils.py

- Remove some now-unneeded type ignores and add a cast for using a single enum
  value as flags. Might need to look at this again with Qt 6 support.

==== qutebrowser/keyinput/modeman.py

- Add a FIXME for using a TypedDict, see comments for hints.py above.

==== qutebrowser/mainwindow/mainwindow.py

- Remove now-unneeded type ignores for calling with OR-ed flags.
- Improve where we cast from WindowType to WindowFlags, no int needed
- Use new .tab_bar() getter, see below.

==== qutebrowser/mainwindow/prompt.py

- Remove now-unneeded type ignores for calling with OR-ed flags.

==== qutebrowser/mainwindow/statusbar/bar.py

- Adjust type ignores around @pyqtProperty. The fact one is still needed seems
  like a stub regression.

==== qutebrowser/mainwindow/statusbar/command.py

- Fix type for setText() override (from QLineEdit): text can be None
  (QString in C++).

==== qutebrowser/mainwindow/statusbar/url.py

- Adjust type ignores around @pyqtProperty. The fact one is still needed seems
  like a stub regression.

==== qutebrowser/mainwindow/tabbedbrowser.py

- Specify that TabDeque manages browser tabs, not any QWidgets. It accesses
  AbstractTab-specific attributes.
- Make sure that the .tabBar() we get is a tabwidget.TabBar, as we access
  .maybe_hide.
- Fix the annotations for stored marks: Scroll positions are a QPoint, not int.
- Add _current_tab() and _tab_by_idx() wrappers for .currentWidget() and
  .widget(), which ensures that the return values are valid AbstractTabs (or None
  for _tab_by_idx). This is needed because we access AbstractTab-specific
  attributes.
- For some places, where the tab can be None, continue using .currentTab() but
  add asserts.
- Remove some now-unneeded [unreachable] ignores, as mypy knows about the None
  possibility now.

==== qutebrowser/mainwindow/tabwidget.py

- Add new tab_bar() and _tab_by_idx() helpers which check that the .tabBar() and
  .widget() are of type TabBar and AbstractTab, respectively.
- Add additional assertions where we expect ._tab_by_idx() to never be None.
- Remove dead code in get_tab_fields for handling a None y scroll position. I
  was unable to find any place in the code where this could be set to None.
- Remove some now-unneeded type ignores and casts, as mypy now knows that
  _type_by_idx() could be None.
- Work around a strange instance where mypy complains about not being able to
  find the type of TabBar.drag_in_progress from TabWidget._toggle_visibility,
  despite it clearly being shown as a bool *inside* that class without any
  annotation.
- Add a ._tab_widget() getter in TabBar which ensures that the .parent() is in
  fact a TabWidget.

==== qutebrowser/misc/crashsignal.py

- Remove now unneeded type ignores for signals.

==== qutebrowser/misc/editor.py

- Remove now unneeded type ignores for signals.

==== qutebrowser/misc/ipc.py

- Remove now unneeded type ignores for signals.
- Add new type ignores for .error() which is both a signal and a getter
  (stub regression?). Won't be relevant for Qt 6 anymore, as the signal was
  renamed to errorOccurred in 5.15.

==== qutebrowser/misc/objects.py

- Make sure mypy knows that objects.app is our custom Application (with custom
  attributes) rather than any QApplication.

==== qutebrowser/utils/objreg.py

- Ignore attr-defined for .win_id attributes. Maybe could add a typing.Protocol,
  but ideally, the whole objreg stuff should die one day anyways.

==== tests/unit/completion/test_completer.py

- Make CompletionWidgetStub inherit from CompletionView so that it passes the
  new isinstance() asserts in completer.py (see above).
2022-04-25 17:23:16 +02:00
Florian Bruhin 3e9203b829 tests: Update bs4 argument name 2022-04-11 10:29:44 +02:00
Nicholas Schwab d1bc60edb8 Adapte errors on click-element to filter. 2022-04-08 14:28:17 +02:00
Nicholas Schwab 39dbf2266f Remove duplicate value in error message for invalid point. 2022-04-08 14:25:07 +02:00
Nicholas Schwab bf562a74fa Added missing Then in test case for click-element. 2022-04-08 14:05:16 +02:00
Nicholas Schwab e7cf3e41bc Add more unit tests. 2022-04-08 14:00:57 +02:00
Nicholas Schwab c48719f014 Fix missing conversion to str in unit test hypothesis. 2022-04-08 14:00:39 +02:00
Nicholas42 d8af9617d9
Simplify unit test for click-element.
Co-authored-by: Florian Bruhin <me@the-compiler.org>
2022-04-08 13:54:30 +02:00
Axel Dahlberg 55303587b8 test(download) no folder chosen 2022-04-08 09:27:26 +02:00
Nicholas Schwab 709592b46a Adapted expected errors in end2end test for click-element. 2022-04-06 20:09:03 +02:00
Nicholas Schwab ae61f02831 Add parse_point utility and tests for it. 2022-04-06 19:37:54 +02:00
Axel Dahlberg bf34f18f09 style(prompt) fix 2022-04-06 16:06:08 +02:00
Axel Dahlberg 6411db1228 test(downloads) fix fixture replacements 2022-04-06 15:54:30 +02:00
Axel Dahlberg 6462133477
Apply suggestions from code review
Co-authored-by: Florian Bruhin <me@the-compiler.org>
2022-04-06 15:38:35 +02:00
Florian Bruhin 96425c93bf Merge remote-tracking branch 'origin/pr/7103' 2022-04-05 12:14:53 +02:00
Florian Bruhin ac8d2949a2 Fix qute-lastpass tests 2022-04-04 17:30:41 +02:00
Florian Bruhin ab7a2ee558 Switch to Python 3.7 subprocess API
Follow-up for #6905
2022-04-04 16:58:31 +02:00
Florian Bruhin da280df809 Clean up some remaining Python version references 2022-04-04 10:51:34 +02:00
Jimmy e9ed6456fd Load icons via importlib.resources
The PyQt resources system is gone in 6.2 and deprecated before that. This
should be the last usage of it.

Switches icons to be read with `utils.resources.read_file_binary()` in
`notification.py` (fallback desktop notification icon) and `app.py` (icon for
the desktop window).

importlib only loads resources under a package, so the icons are moved under
the `qutebrowser/` directory.

Closes: #6062
2022-04-04 18:03:54 +12:00
Jimmy 060e4fbf80 Drop python3.6 support.
Commits for dropping 3.5 support to copy from:

c245b7d855ccd "Initial drop of Python 3.5"
ccdfb44b85 "Drop support for Python 3.6.0"

Anything needed to update regarding OS version support in
doc/install.asciidoc?
TODO: remove 3.6/7 annotations in requirements files and
  rebuild

workflows: not sure I updated it right (run 5.12 with 3.7, same 18.04 OS) but
18.04 seems to have 3.7 on it too so it should work. It'll all change when we
drop <5.15 anyway. Not sure what the minimum ubuntu version will be going
forward.

Regarding mimetype overrides (ebb3046822) the doctring says they can all go
in 3.7 but .h5 is still missing on py39, not sure if we should care.

There are a bunch of old(?) warning messages still ignored in tests/end2end/fixtures/quteprocess.py.
2022-04-04 12:08:19 +12:00
Florian Bruhin bd8c940320 Simplify some syntax
Found via pyupgrade
2022-04-03 12:18:09 +02:00
Nicholas Schwab eb1e49c468 Fixed spaces at line end. 2022-04-01 20:45:16 +02:00
Nicholas Schwab 93e548eccf Added tests for click-element focused. 2022-04-01 20:32:21 +02:00
Nicholas Schwab 061542808b Added some tests for click-element with position filter. 2022-04-01 20:27:07 +02:00
Nicholas Schwab 2c0470d098 Add tests for click-element with CSS filter. 2022-04-01 20:27:07 +02:00
Nicholas Schwab 53b87f024c Adapt tests to new error output. 2022-04-01 20:27:07 +02:00