mypy: use from-import for typing in remaining files in `browser`

The type comments have also been changed to annotations, since Python
3.5 support will be dropped with the next release.

See #5396
This commit is contained in:
Tim Brown 2020-10-26 23:08:35 +10:00
parent 37d7a195a9
commit 4279a4da6f
24 changed files with 218 additions and 240 deletions

View File

@ -22,7 +22,8 @@
import enum
import itertools
import functools
import typing
from typing import (cast, TYPE_CHECKING, Any, Callable, Iterable, List, Optional,
Sequence, Set, Type, Union)
import attr
from PyQt5.QtCore import (pyqtSignal, pyqtSlot, QUrl, QObject, QSizeF, Qt,
@ -32,7 +33,7 @@ from PyQt5.QtWidgets import QWidget, QApplication, QDialog
from PyQt5.QtPrintSupport import QPrintDialog, QPrinter
from PyQt5.QtNetwork import QNetworkAccessManager
if typing.TYPE_CHECKING:
if TYPE_CHECKING:
from PyQt5.QtWebKit import QWebHistory
from PyQt5.QtWebEngineWidgets import QWebEngineHistory
@ -48,7 +49,7 @@ from qutebrowser.misc import miscwidgets, objects, sessions
from qutebrowser.browser import eventfilter, inspector
from qutebrowser.qt import sip
if typing.TYPE_CHECKING:
if TYPE_CHECKING:
from qutebrowser.browser import webelem
from qutebrowser.browser.inspector import AbstractWebInspector
@ -71,7 +72,7 @@ def create(win_id: int,
mode_manager = modeman.instance(win_id)
if objects.backend == usertypes.Backend.QtWebEngine:
from qutebrowser.browser.webengine import webenginetab
tab_class = webenginetab.WebEngineTab # type: typing.Type[AbstractTab]
tab_class: Type[AbstractTab] = webenginetab.WebEngineTab
elif objects.backend == usertypes.Backend.QtWebKit:
from qutebrowser.browser.webkit import webkittab
tab_class = webkittab.WebKitTab
@ -141,19 +142,17 @@ class TabData:
splitter: InspectorSplitter used to show inspector inside the tab.
"""
keep_icon = attr.ib(False) # type: bool
viewing_source = attr.ib(False) # type: bool
inspector = attr.ib(None) # type: typing.Optional[AbstractWebInspector]
open_target = attr.ib(
usertypes.ClickTarget.normal) # type: usertypes.ClickTarget
override_target = attr.ib(
None) # type: typing.Optional[usertypes.ClickTarget]
pinned = attr.ib(False) # type: bool
fullscreen = attr.ib(False) # type: bool
netrc_used = attr.ib(False) # type: bool
input_mode = attr.ib(usertypes.KeyMode.normal) # type: usertypes.KeyMode
last_navigation = attr.ib(None) # type: usertypes.NavigationRequest
splitter = attr.ib(None) # type: miscwidgets.InspectorSplitter
keep_icon: bool = attr.ib(False)
viewing_source: bool = attr.ib(False)
inspector: Optional['AbstractWebInspector'] = attr.ib(None)
open_target: usertypes.ClickTarget = attr.ib(usertypes.ClickTarget.normal)
override_target: Optional[usertypes.ClickTarget] = attr.ib(None)
pinned: bool = attr.ib(False)
fullscreen: bool = attr.ib(False)
netrc_used: bool = attr.ib(False)
input_mode: usertypes.KeyMode = attr.ib(usertypes.KeyMode.normal)
last_navigation: usertypes.NavigationRequest = attr.ib(None)
splitter: miscwidgets.InspectorSplitter = attr.ib(None)
def should_show_icon(self) -> bool:
return (config.val.tabs.favicons.show == 'always' or
@ -165,12 +164,12 @@ class AbstractAction:
"""Attribute ``action`` of AbstractTab for Qt WebActions."""
# The class actions are defined on (QWeb{Engine,}Page)
action_class = None # type: type
action_class: Any = None
# The type of the actions (QWeb{Engine,}Page.WebAction)
action_base = None # type: type
action_base: Any = None
def __init__(self, tab: 'AbstractTab') -> None:
self._widget = typing.cast(QWidget, None)
self._widget = cast(QWidget, None)
self._tab = tab
def exit_fullscreen(self) -> None:
@ -221,7 +220,7 @@ class AbstractPrinting:
"""Attribute ``printing`` of AbstractTab for printing the page."""
def __init__(self, tab: 'AbstractTab') -> None:
self._widget = typing.cast(QWidget, None)
self._widget = cast(QWidget, None)
self._tab = tab
def check_pdf_support(self) -> None:
@ -253,7 +252,7 @@ class AbstractPrinting:
raise NotImplementedError
def to_printer(self, printer: QPrinter,
callback: typing.Callable[[bool], None] = None) -> None:
callback: Callable[[bool], None] = None) -> None:
"""Print the tab.
Args:
@ -305,13 +304,13 @@ class AbstractSearch(QObject):
#: Signal emitted when an existing search was cleared.
cleared = pyqtSignal()
_Callback = typing.Callable[[bool], None]
_Callback = Callable[[bool], None]
def __init__(self, tab: 'AbstractTab', parent: QWidget = None):
super().__init__(parent)
self._tab = tab
self._widget = typing.cast(QWidget, None)
self.text = None # type: typing.Optional[str]
self._widget = cast(QWidget, None)
self.text: Optional[str] = None
self.search_displayed = False
def _is_case_sensitive(self, ignore_case: usertypes.IgnoreCase) -> bool:
@ -374,7 +373,7 @@ class AbstractZoom(QObject):
def __init__(self, tab: 'AbstractTab', parent: QWidget = None) -> None:
super().__init__(parent)
self._tab = tab
self._widget = typing.cast(QWidget, None)
self._widget = cast(QWidget, None)
# Whether zoom was changed from the default.
self._default_zoom_changed = False
self._init_neighborlist()
@ -394,9 +393,8 @@ class AbstractZoom(QObject):
It is a NeighborList with the zoom levels."""
levels = config.val.zoom.levels
self._neighborlist = usertypes.NeighborList(
levels, mode=usertypes.NeighborList.Modes.edge
) # type: usertypes.NeighborList[float]
self._neighborlist: usertypes.NeighborList[float] = usertypes.NeighborList(
levels, mode=usertypes.NeighborList.Modes.edge)
self._neighborlist.fuzzyval = config.val.zoom.default
def apply_offset(self, offset: int) -> float:
@ -469,7 +467,7 @@ class AbstractCaret(QObject):
mode_manager: modeman.ModeManager,
parent: QWidget = None) -> None:
super().__init__(parent)
self._widget = typing.cast(QWidget, None)
self._widget = cast(QWidget, None)
self._mode_manager = mode_manager
mode_manager.entered.connect(self._on_mode_entered)
mode_manager.left.connect(self._on_mode_left)
@ -532,7 +530,7 @@ class AbstractCaret(QObject):
def drop_selection(self) -> None:
raise NotImplementedError
def selection(self, callback: typing.Callable[[str], None]) -> None:
def selection(self, callback: Callable[[str], None]) -> None:
raise NotImplementedError
def reverse_selection(self) -> None:
@ -562,7 +560,7 @@ class AbstractScroller(QObject):
def __init__(self, tab: 'AbstractTab', parent: QWidget = None):
super().__init__(parent)
self._tab = tab
self._widget = typing.cast(QWidget, None)
self._widget = cast(QWidget, None)
if 'log-scroll-pos' in objects.debug_flags:
self.perc_changed.connect(self._log_scroll_pos_change)
@ -638,7 +636,7 @@ class AbstractHistoryPrivate:
"""Deserialize from a format produced by self.serialize."""
raise NotImplementedError
def load_items(self, items: typing.Sequence) -> None:
def load_items(self, items: Sequence) -> None:
"""Deserialize from a list of WebHistoryItems."""
raise NotImplementedError
@ -649,14 +647,13 @@ class AbstractHistory:
def __init__(self, tab: 'AbstractTab') -> None:
self._tab = tab
self._history = typing.cast(
typing.Union['QWebHistory', 'QWebEngineHistory'], None)
self._history = cast(Union['QWebHistory', 'QWebEngineHistory'], None)
self.private_api = AbstractHistoryPrivate()
def __len__(self) -> int:
raise NotImplementedError
def __iter__(self) -> typing.Iterable:
def __iter__(self) -> Iterable:
raise NotImplementedError
def _check_count(self, count: int) -> None:
@ -693,16 +690,16 @@ class AbstractHistory:
def can_go_forward(self) -> bool:
raise NotImplementedError
def _item_at(self, i: int) -> typing.Any:
def _item_at(self, i: int) -> Any:
raise NotImplementedError
def _go_to_item(self, item: typing.Any) -> None:
def _go_to_item(self, item: Any) -> None:
raise NotImplementedError
def back_items(self) -> typing.List[typing.Any]:
def back_items(self) -> List[Any]:
raise NotImplementedError
def forward_items(self) -> typing.List[typing.Any]:
def forward_items(self) -> List[Any]:
raise NotImplementedError
@ -710,14 +707,12 @@ class AbstractElements:
"""Finding and handling of elements on the page."""
_MultiCallback = typing.Callable[
[typing.Sequence['webelem.AbstractWebElement']], None]
_SingleCallback = typing.Callable[
[typing.Optional['webelem.AbstractWebElement']], None]
_ErrorCallback = typing.Callable[[Exception], None]
_MultiCallback = Callable[[Sequence['webelem.AbstractWebElement']], None]
_SingleCallback = Callable[[Optional['webelem.AbstractWebElement']], None]
_ErrorCallback = Callable[[Exception], None]
def __init__(self, tab: 'AbstractTab') -> None:
self._widget = typing.cast(QWidget, None)
self._widget = cast(QWidget, None)
self._tab = tab
def find_css(self, selector: str,
@ -778,7 +773,7 @@ class AbstractAudio(QObject):
def __init__(self, tab: 'AbstractTab', parent: QWidget = None) -> None:
super().__init__(parent)
self._widget = typing.cast(QWidget, None)
self._widget = cast(QWidget, None)
self._tab = tab
def set_muted(self, muted: bool, override: bool = False) -> None:
@ -809,7 +804,7 @@ class AbstractTabPrivate:
def __init__(self, mode_manager: modeman.ModeManager,
tab: 'AbstractTab') -> None:
self._widget = typing.cast(QWidget, None)
self._widget = cast(QWidget, None)
self._tab = tab
self._mode_manager = mode_manager
@ -827,7 +822,7 @@ class AbstractTabPrivate:
return
def _auto_insert_mode_cb(
elem: typing.Optional['webelem.AbstractWebElement']
elem: Optional['webelem.AbstractWebElement']
) -> None:
"""Called from JS after finding the focused element."""
if elem is None:
@ -842,7 +837,7 @@ class AbstractTabPrivate:
def clear_ssl_errors(self) -> None:
raise NotImplementedError
def networkaccessmanager(self) -> typing.Optional[QNetworkAccessManager]:
def networkaccessmanager(self) -> Optional[QNetworkAccessManager]:
"""Get the QNetworkAccessManager for this tab.
This is only implemented for QtWebKit.
@ -934,7 +929,7 @@ class AbstractTab(QWidget):
# Note that we remember hosts here, without scheme/port:
# QtWebEngine/Chromium also only remembers hostnames, and certificates are
# for a given hostname anyways.
_insecure_hosts = set() # type: typing.Set[str]
_insecure_hosts: Set[str] = set()
def __init__(self, *, win_id: int,
mode_manager: modeman.ModeManager,
@ -954,12 +949,12 @@ class AbstractTab(QWidget):
self.data = TabData()
self._layout = miscwidgets.WrapperLayout(self)
self._widget = typing.cast(QWidget, None)
self._widget = cast(QWidget, None)
self._progress = 0
self._load_status = usertypes.LoadStatus.none
self._tab_event_filter = eventfilter.TabEventFilter(
self, parent=self)
self.backend = None # type: typing.Optional[usertypes.Backend]
self.backend: Optional[usertypes.Backend] = None
# If true, this tab has been requested to be removed (or is removed).
self.pending_removal = False
@ -1162,7 +1157,7 @@ class AbstractTab(QWidget):
self.send_event(release_evt)
def dump_async(self,
callback: typing.Callable[[str], None], *,
callback: Callable[[str], None], *,
plain: bool = False) -> None:
"""Dump the current page's html asynchronously.
@ -1174,8 +1169,8 @@ class AbstractTab(QWidget):
def run_js_async(
self,
code: str,
callback: typing.Callable[[typing.Any], None] = None, *,
world: typing.Union[usertypes.JsWorld, int] = None
callback: Callable[[Any], None] = None, *,
world: Union[usertypes.JsWorld, int] = None
) -> None:
"""Run javascript async.

View File

@ -22,7 +22,7 @@
import os.path
import shlex
import functools
import typing
from typing import cast, Callable, Dict, Union
from PyQt5.QtWidgets import QApplication, QTabBar
from PyQt5.QtCore import pyqtSlot, Qt, QUrl, QEvent, QUrlQuery
@ -600,16 +600,14 @@ class CommandDispatcher:
widget = self._current_widget()
url = self._current_url()
handlers = {
handlers: Dict[str, Callable] = {
'prev': functools.partial(navigate.prevnext, prev=True),
'next': functools.partial(navigate.prevnext, prev=False),
'up': navigate.path_up,
'strip': navigate.strip,
'decrement': functools.partial(navigate.incdec,
inc_or_dec='decrement'),
'increment': functools.partial(navigate.incdec,
inc_or_dec='increment'),
} # type: typing.Dict[str, typing.Callable]
'decrement': functools.partial(navigate.incdec, inc_or_dec='decrement'),
'increment': functools.partial(navigate.incdec, inc_or_dec='increment'),
}
try:
if where in ['prev', 'next']:
@ -950,7 +948,7 @@ class CommandDispatcher:
@cmdutils.argument('index', choices=['last', 'stack-next', 'stack-prev'],
completion=miscmodels.tab_focus)
@cmdutils.argument('count', value=cmdutils.Value.count)
def tab_focus(self, index: typing.Union[str, int] = None,
def tab_focus(self, index: Union[str, int] = None,
count: int = None, no_last: bool = False) -> None:
"""Select the tab given as argument/[count].
@ -994,7 +992,7 @@ class CommandDispatcher:
@cmdutils.register(instance='command-dispatcher', scope='window')
@cmdutils.argument('index', choices=['+', '-'])
@cmdutils.argument('count', value=cmdutils.Value.count)
def tab_move(self, index: typing.Union[str, int] = None,
def tab_move(self, index: Union[str, int] = None,
count: int = None) -> None:
"""Move the current tab according to the argument and [count].
@ -1432,7 +1430,7 @@ class CommandDispatcher:
query = QUrlQuery()
query.addQueryItem('level', level)
if plain:
query.addQueryItem('plain', typing.cast(str, None))
query.addQueryItem('plain', cast(str, None))
if logfilter:
try:
@ -1653,7 +1651,7 @@ class CommandDispatcher:
url: bool = False,
quiet: bool = False,
*,
world: typing.Union[usertypes.JsWorld, int] = None) -> None:
world: Union[usertypes.JsWorld, int] = None) -> None:
"""Evaluate a JavaScript string.
Args:

View File

@ -20,7 +20,7 @@
"""The ListView to display downloads in."""
import functools
import typing
from typing import Callable, MutableSequence, Tuple, Union
from PyQt5.QtCore import pyqtSlot, QSize, Qt, QTimer
from PyQt5.QtWidgets import QListView, QSizePolicy, QMenu, QStyleFactory
@ -54,10 +54,10 @@ def update_geometry(obj):
QTimer.singleShot(0, _update_geometry)
_ActionListType = typing.MutableSequence[
typing.Union[
typing.Tuple[None, None], # separator
typing.Tuple[str, typing.Callable[[], None]],
_ActionListType = MutableSequence[
Union[
Tuple[None, None], # separator
Tuple[str, Callable[[], None]],
]
]
@ -142,7 +142,7 @@ class DownloadView(QListView):
item: The DownloadItem to get the actions for, or None.
"""
model = self.model()
actions = [] # type: _ActionListType
actions: _ActionListType = []
if item is None:
pass
elif item.done:

View File

@ -26,7 +26,7 @@ import fnmatch
import functools
import glob
import textwrap
import typing
from typing import cast, List, Sequence
import attr
from PyQt5.QtCore import pyqtSignal, QObject, QUrl
@ -39,7 +39,7 @@ from qutebrowser.browser import downloads
from qutebrowser.misc import objects
gm_manager = typing.cast('GreasemonkeyManager', None)
gm_manager = cast('GreasemonkeyManager', None)
def _scripts_dir():
@ -54,10 +54,10 @@ class GreasemonkeyScript:
def __init__(self, properties, code, # noqa: C901 pragma: no mccabe
filename=None):
self._code = code
self.includes = [] # type: typing.Sequence[str]
self.matches = [] # type: typing.Sequence[str]
self.excludes = [] # type: typing.Sequence[str]
self.requires = [] # type: typing.Sequence[str]
self.includes: Sequence[str] = []
self.matches: Sequence[str] = []
self.excludes: Sequence[str] = []
self.requires: Sequence[str] = []
self.description = None
self.namespace = None
self.run_at = None
@ -259,11 +259,10 @@ class GreasemonkeyManager(QObject):
def __init__(self, parent=None):
super().__init__(parent)
self._run_start = [] # type: typing.List[GreasemonkeyScript]
self._run_end = [] # type: typing.List[GreasemonkeyScript]
self._run_idle = [] # type: typing.List[GreasemonkeyScript]
self._in_progress_dls = [
] # type: typing.List[downloads.AbstractDownloadItem]
self._run_start: List[GreasemonkeyScript] = []
self._run_end: List[GreasemonkeyScript] = []
self._run_idle: List[GreasemonkeyScript] = []
self._in_progress_dls: List[downloads.AbstractDownloadItem] = []
self.load_scripts()

View File

@ -20,13 +20,14 @@
"""A HintManager to draw hints over links."""
import collections
import typing
import functools
import os
import re
import html
import enum
from string import ascii_lowercase
from typing import (TYPE_CHECKING, Callable, Dict, Iterable, Iterator, List, Mapping,
MutableSequence, Optional, Sequence, Set)
import attr
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, Qt, QUrl
@ -38,7 +39,7 @@ from qutebrowser.browser import webelem, history
from qutebrowser.commands import userscripts, runners
from qutebrowser.api import cmdutils
from qutebrowser.utils import usertypes, log, qtutils, message, objreg, utils
if typing.TYPE_CHECKING:
if TYPE_CHECKING:
from qutebrowser.browser import browsertab
@ -180,22 +181,22 @@ class HintContext:
group: The group of web elements to hint.
"""
all_labels = attr.ib(attr.Factory(list)) # type: typing.List[HintLabel]
labels = attr.ib(attr.Factory(dict)) # type: typing.Dict[str, HintLabel]
target = attr.ib(None) # type: Target
baseurl = attr.ib(None) # type: QUrl
to_follow = attr.ib(None) # type: str
rapid = attr.ib(False) # type: bool
first_run = attr.ib(True) # type: bool
add_history = attr.ib(False) # type: bool
filterstr = attr.ib(None) # type: str
args = attr.ib(attr.Factory(list)) # type: typing.List[str]
tab = attr.ib(None) # type: browsertab.AbstractTab
group = attr.ib(None) # type: str
hint_mode = attr.ib(None) # type: str
first = attr.ib(False) # type: bool
all_labels: List[HintLabel] = attr.ib(attr.Factory(list))
labels: Dict[str, HintLabel] = attr.ib(attr.Factory(dict))
target: Target = attr.ib(None)
baseurl: QUrl = attr.ib(None)
to_follow: str = attr.ib(None)
rapid: bool = attr.ib(False)
first_run: bool = attr.ib(True)
add_history: bool = attr.ib(False)
filterstr: str = attr.ib(None)
args: List[str] = attr.ib(attr.Factory(list))
tab: 'browsertab.AbstractTab' = attr.ib(None)
group: str = attr.ib(None)
hint_mode: str = attr.ib(None)
first: bool = attr.ib(False)
def get_args(self, urlstr: str) -> typing.Sequence[str]:
def get_args(self, urlstr: str) -> Sequence[str]:
"""Get the arguments, with {hint-url} replaced by the given URL."""
args = []
for arg in self.args:
@ -352,8 +353,8 @@ class HintActions:
commandrunner.run_safely('spawn ' + ' '.join(args))
_ElemsType = typing.Sequence[webelem.AbstractWebElement]
_HintStringsType = typing.MutableSequence[str]
_ElemsType = Sequence[webelem.AbstractWebElement]
_HintStringsType = MutableSequence[str]
class HintManager(QObject):
@ -397,7 +398,7 @@ class HintManager(QObject):
"""Constructor."""
super().__init__(parent)
self._win_id = win_id
self._context = None # type: typing.Optional[HintContext]
self._context: Optional[HintContext] = None
self._word_hinter = WordHinter()
self._actions = HintActions(win_id)
@ -527,12 +528,10 @@ class HintManager(QObject):
Return:
A list of shuffled hint strings.
"""
buckets = [
[] for i in range(length)
] # type: typing.Sequence[_HintStringsType]
buckets: Sequence[_HintStringsType] = [[] for i in range(length)]
for i, hint in enumerate(hints):
buckets[i % len(buckets)].append(hint)
result = [] # type: _HintStringsType
result: _HintStringsType = []
for bucket in buckets:
result += bucket
return result
@ -557,7 +556,7 @@ class HintManager(QObject):
A hint string.
"""
base = len(chars)
hintstr = [] # type: typing.MutableSequence[str]
hintstr: MutableSequence[str] = []
remainder = 0
while True:
remainder = number % base
@ -785,7 +784,7 @@ class HintManager(QObject):
error_cb=lambda err: message.error(str(err)),
only_visible=True)
def _get_hint_mode(self, mode: typing.Optional[str]) -> str:
def _get_hint_mode(self, mode: Optional[str]) -> str:
"""Get the hinting mode to use based on a mode argument."""
if mode is None:
return config.val.hints.mode
@ -797,7 +796,7 @@ class HintManager(QObject):
raise cmdutils.CommandError("Invalid mode: {}".format(e))
return mode
def current_mode(self) -> typing.Optional[str]:
def current_mode(self) -> Optional[str]:
"""Return the currently active hinting mode (or None otherwise)."""
if self._context is None:
return None
@ -808,7 +807,7 @@ class HintManager(QObject):
self,
keystr: str = "",
filterstr: str = "",
visible: typing.Mapping[str, HintLabel] = None
visible: Mapping[str, HintLabel] = None
) -> None:
"""Handle the auto_follow option."""
assert self._context is not None
@ -870,7 +869,7 @@ class HintManager(QObject):
pass
self._handle_auto_follow(keystr=keystr)
def filter_hints(self, filterstr: typing.Optional[str]) -> None:
def filter_hints(self, filterstr: Optional[str]) -> None:
"""Filter displayed hints according to a text.
Args:
@ -1041,7 +1040,7 @@ class WordHinter:
def __init__(self) -> None:
# will be initialized on first use.
self.words = set() # type: typing.Set[str]
self.words: Set[str] = set()
self.dictionary = None
def ensure_initialized(self) -> None:
@ -1073,10 +1072,10 @@ class WordHinter:
def extract_tag_words(
self, elem: webelem.AbstractWebElement
) -> typing.Iterator[str]:
) -> Iterator[str]:
"""Extract tag words form the given element."""
_extractor_type = typing.Callable[[webelem.AbstractWebElement], str]
attr_extractors = {
_extractor_type = Callable[[webelem.AbstractWebElement], str]
attr_extractors: Mapping[str, _extractor_type] = {
"alt": lambda elem: elem["alt"],
"name": lambda elem: elem["name"],
"title": lambda elem: elem["title"],
@ -1084,7 +1083,7 @@ class WordHinter:
"src": lambda elem: elem["src"].split('/')[-1],
"href": lambda elem: elem["href"].split('/')[-1],
"text": str,
} # type: typing.Mapping[str, _extractor_type]
}
extractable_attrs = collections.defaultdict(list, {
"img": ["alt", "title", "src"],
@ -1100,8 +1099,8 @@ class WordHinter:
def tag_words_to_hints(
self,
words: typing.Iterable[str]
) -> typing.Iterator[str]:
words: Iterable[str]
) -> Iterator[str]:
"""Take words and transform them to proper hints if possible."""
for candidate in words:
if not candidate:
@ -1112,20 +1111,20 @@ class WordHinter:
if 4 < match.end() - match.start() < 8:
yield candidate[match.start():match.end()].lower()
def any_prefix(self, hint: str, existing: typing.Iterable[str]) -> bool:
def any_prefix(self, hint: str, existing: Iterable[str]) -> bool:
return any(hint.startswith(e) or e.startswith(hint) for e in existing)
def filter_prefixes(
self,
hints: typing.Iterable[str],
existing: typing.Iterable[str]
) -> typing.Iterator[str]:
hints: Iterable[str],
existing: Iterable[str]
) -> Iterator[str]:
"""Filter hints which don't start with the given prefix."""
return (h for h in hints if not self.any_prefix(h, existing))
def new_hint_for(self, elem: webelem.AbstractWebElement,
existing: typing.Iterable[str],
fallback: typing.Iterable[str]) -> typing.Optional[str]:
existing: Iterable[str],
fallback: Iterable[str]) -> Optional[str]:
"""Return a hint for elem, not conflicting with the existing."""
new = self.tag_words_to_hints(self.extract_tag_words(elem))
new_no_prefixes = self.filter_prefixes(new, existing)
@ -1149,7 +1148,7 @@ class WordHinter:
"""
self.ensure_initialized()
hints = []
used_hints = set() # type: typing.Set[str]
used_hints: Set[str] = set()
words = iter(self.words)
for elem in elems:
hint = self.new_hint_for(elem, used_hints, words)

View File

@ -22,7 +22,7 @@
import os
import time
import contextlib
import typing
from typing import cast, Mapping, MutableSequence
from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal
from PyQt5.QtWidgets import QProgressDialog, QApplication
@ -35,7 +35,7 @@ from qutebrowser.misc import objects, sql
# increment to indicate that HistoryCompletion must be regenerated
_USER_VERSION = 2
web_history = typing.cast('WebHistory', None)
web_history = cast('WebHistory', None)
class HistoryProgress:
@ -208,11 +208,11 @@ class WebHistory(sql.SqlTable):
return any(pattern.matches(url) for pattern in patterns)
def _rebuild_completion(self):
data = {
data: Mapping[str, MutableSequence[str]] = {
'url': [],
'title': [],
'last_atime': []
} # type: typing.Mapping[str, typing.MutableSequence[str]]
}
# select the latest entry for each url
q = sql.Query('SELECT url, title, max(atime) AS atime FROM History '
'WHERE NOT redirect and url NOT LIKE "qute://back%" '

View File

@ -21,8 +21,8 @@
import base64
import binascii
import typing
import enum
from typing import cast, Optional
from PyQt5.QtWidgets import QWidget
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QEvent
@ -119,10 +119,10 @@ class AbstractWebInspector(QWidget):
win_id: int,
parent: QWidget = None) -> None:
super().__init__(parent)
self._widget = typing.cast(QWidget, None)
self._widget = cast(QWidget, None)
self._layout = miscwidgets.WrapperLayout(self)
self._splitter = splitter
self._position = None # type: typing.Optional[Position]
self._position: Optional[Position] = None
self._win_id = win_id
self._event_filter = _EventFilter(parent=self)
@ -163,7 +163,7 @@ class AbstractWebInspector(QWidget):
modeman.enter(self._win_id, usertypes.KeyMode.insert,
reason='Inspector clicked', only_if_normal=True)
def set_position(self, position: typing.Optional[Position]) -> None:
def set_position(self, position: Optional[Position]) -> None:
"""Set the position of the inspector.
If the position is None, the last known position is used.

View File

@ -21,7 +21,7 @@
import sys
import functools
import typing
from typing import Optional
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, QUrl
from PyQt5.QtNetwork import (QNetworkProxy, QNetworkRequest, QHostInfo,
@ -251,8 +251,7 @@ class PACFetcher(QObject):
url.setScheme(url.scheme()[len(pac_prefix):])
self._pac_url = url
self._manager = QNetworkAccessManager(
) # type: typing.Optional[QNetworkAccessManager]
self._manager: Optional[QNetworkAccessManager] = QNetworkAccessManager()
self._manager.setProxy(QNetworkProxy(QNetworkProxy.NoProxy))
self._pac = None
self._error_message = None

View File

@ -31,7 +31,6 @@ import time
import textwrap
import urllib
import collections
import typing
import secrets
from typing import TypeVar, Callable, Dict, List, Optional, Union, Sequence, Tuple

View File

@ -19,7 +19,7 @@
"""Generic web element related code."""
import typing
from typing import cast, TYPE_CHECKING, Iterator, Optional, Set, Union
import collections.abc
from PyQt5.QtCore import QUrl, Qt, QEvent, QTimer, QRect, QPoint
@ -29,11 +29,11 @@ from qutebrowser.config import config
from qutebrowser.keyinput import modeman
from qutebrowser.utils import log, usertypes, utils, qtutils, objreg
if typing.TYPE_CHECKING:
if TYPE_CHECKING:
from qutebrowser.browser import browsertab
JsValueType = typing.Union[int, float, str, None]
JsValueType = Union[int, float, str, None]
class Error(Exception):
@ -80,7 +80,7 @@ class AbstractWebElement(collections.abc.MutableMapping):
def __delitem__(self, key: str) -> None:
raise NotImplementedError
def __iter__(self) -> typing.Iterator[str]:
def __iter__(self) -> Iterator[str]:
raise NotImplementedError
def __len__(self) -> int:
@ -88,8 +88,7 @@ class AbstractWebElement(collections.abc.MutableMapping):
def __repr__(self) -> str:
try:
html = utils.compact_text(
self.outer_xml(), 500) # type: typing.Optional[str]
html: Optional[str] = utils.compact_text(self.outer_xml(), 500)
except Error:
html = None
return utils.get_repr(self, html=html)
@ -102,7 +101,7 @@ class AbstractWebElement(collections.abc.MutableMapping):
"""Get the geometry for this element."""
raise NotImplementedError
def classes(self) -> typing.Set[str]:
def classes(self) -> Set[str]:
"""Get a set of classes assigned to this element."""
raise NotImplementedError
@ -282,7 +281,7 @@ class AbstractWebElement(collections.abc.MutableMapping):
"""Remove target from link."""
raise NotImplementedError
def resolve_url(self, baseurl: QUrl) -> typing.Optional[QUrl]:
def resolve_url(self, baseurl: QUrl) -> Optional[QUrl]:
"""Resolve the URL in the element's src/href attribute.
Args:
@ -357,16 +356,12 @@ class AbstractWebElement(collections.abc.MutableMapping):
else:
target_modifiers[usertypes.ClickTarget.tab_bg] |= Qt.ShiftModifier
modifiers = typing.cast(Qt.KeyboardModifiers,
target_modifiers[click_target])
modifiers = cast(Qt.KeyboardModifiers, target_modifiers[click_target])
events = [
QMouseEvent(QEvent.MouseMove, pos, Qt.NoButton, Qt.NoButton,
Qt.NoModifier),
QMouseEvent(QEvent.MouseButtonPress, pos, button, button,
modifiers),
QMouseEvent(QEvent.MouseButtonRelease, pos, button, Qt.NoButton,
modifiers),
QMouseEvent(QEvent.MouseMove, pos, Qt.NoButton, Qt.NoButton, Qt.NoModifier),
QMouseEvent(QEvent.MouseButtonPress, pos, button, button, modifiers),
QMouseEvent(QEvent.MouseButtonRelease, pos, button, Qt.NoButton, modifiers),
]
for evt in events:

View File

@ -74,7 +74,7 @@ Prefix changed to "forceDarkMode".
"""
import enum
import typing
from typing import Any, Iterable, Iterator, Mapping, Optional, Set, Tuple, Union
try:
from PyQt5.QtWebEngine import PYQT_WEBENGINE_VERSION
@ -135,17 +135,17 @@ _BOOLS = {
False: 'false',
}
_DarkModeSettingsType = typing.Iterable[
typing.Tuple[
_DarkModeSettingsType = Iterable[
Tuple[
str, # qutebrowser option name
str, # darkmode setting name
# Mapping from the config value to a string (or something convertable
# to a string) which gets passed to Chromium.
typing.Optional[typing.Mapping[typing.Any, typing.Union[str, int]]],
Optional[Mapping[Any, Union[str, int]]],
],
]
_DarkModeDefinitionType = typing.Tuple[_DarkModeSettingsType, typing.Set[str]]
_DarkModeDefinitionType = Tuple[_DarkModeSettingsType, Set[str]]
_QT_514_SETTINGS = [
('policy.images', 'darkModeImagePolicy', _IMAGE_POLICIES),
@ -162,7 +162,7 @@ _QT_514_SETTINGS = [
# mandatory setting - except on Qt 5.15.0 where we don't, so we don't get the
# workaround warning below if the setting wasn't explicitly customized.
_DARK_MODE_DEFINITIONS = {
_DARK_MODE_DEFINITIONS: Mapping[Variant, _DarkModeDefinitionType] = {
Variant.unavailable: ([], set()),
Variant.qt_515_2: ([
@ -242,7 +242,7 @@ _DARK_MODE_DEFINITIONS = {
('contrast', 'highContrastContrast', None),
('grayscale.all', 'highContrastGrayscale', _BOOLS),
], {'algorithm'}),
} # type: typing.Mapping[Variant, _DarkModeDefinitionType]
}
def _variant() -> Variant:
@ -274,7 +274,7 @@ def _variant() -> Variant:
return Variant.unavailable
def settings() -> typing.Iterator[typing.Tuple[str, str]]:
def settings() -> Iterator[Tuple[str, str]]:
"""Get necessary blink settings to configure dark mode for QtWebEngine."""
if not config.val.colors.webpage.darkmode.enabled:
return

View File

@ -19,7 +19,8 @@
"""QtWebEngine specific part of the web element API."""
import typing
from typing import (
TYPE_CHECKING, Any, Callable, Dict, Iterator, Optional, Set, Tuple, Union)
from PyQt5.QtCore import QRect, Qt, QPoint, QEventLoop
from PyQt5.QtGui import QMouseEvent
@ -29,7 +30,7 @@ from PyQt5.QtWebEngineWidgets import QWebEngineSettings
from qutebrowser.utils import log, javascript, urlutils, usertypes, utils
from qutebrowser.browser import webelem
if typing.TYPE_CHECKING:
if TYPE_CHECKING:
from qutebrowser.browser.webengine import webenginetab
@ -37,11 +38,11 @@ class WebEngineElement(webelem.AbstractWebElement):
"""A web element for QtWebEngine, using JS under the hood."""
def __init__(self, js_dict: typing.Dict[str, typing.Any],
def __init__(self, js_dict: Dict[str, Any],
tab: 'webenginetab.WebEngineTab') -> None:
super().__init__(tab)
# Do some sanity checks on the data we get from JS
js_dict_types = {
js_dict_types: Dict[str, Union[type, Tuple[type, ...]]] = {
'id': int,
'text': str,
'value': (str, int, float),
@ -52,7 +53,7 @@ class WebEngineElement(webelem.AbstractWebElement):
'attributes': dict,
'is_content_editable': bool,
'caret_position': (int, type(None)),
} # type: typing.Dict[str, typing.Union[type, typing.Tuple[type,...]]]
}
assert set(js_dict.keys()).issubset(js_dict_types.keys())
for name, typ in js_dict_types.items():
if name in js_dict and not isinstance(js_dict[name], typ):
@ -97,14 +98,14 @@ class WebEngineElement(webelem.AbstractWebElement):
utils.unused(key)
log.stub()
def __iter__(self) -> typing.Iterator[str]:
def __iter__(self) -> Iterator[str]:
return iter(self._js_dict['attributes'])
def __len__(self) -> int:
return len(self._js_dict['attributes'])
def _js_call(self, name: str, *args: webelem.JsValueType,
callback: typing.Callable[[typing.Any], None] = None) -> None:
callback: Callable[[Any], None] = None) -> None:
"""Wrapper to run stuff from webelem.js."""
if self._tab.is_deleted():
raise webelem.OrphanedError("Tab containing element vanished")
@ -118,7 +119,7 @@ class WebEngineElement(webelem.AbstractWebElement):
log.stub()
return QRect()
def classes(self) -> typing.Set[str]:
def classes(self) -> Set[str]:
"""Get a list of classes assigned to this element."""
return set(self._js_dict['class_name'].split())
@ -150,7 +151,7 @@ class WebEngineElement(webelem.AbstractWebElement):
composed: bool = False) -> None:
self._js_call('dispatch_event', event, bubbles, cancelable, composed)
def caret_position(self) -> typing.Optional[int]:
def caret_position(self) -> Optional[int]:
"""Get the text caret position for the current element.
If the element is not a text element, None is returned.
@ -256,7 +257,7 @@ class WebEngineElement(webelem.AbstractWebElement):
QEventLoop.ExcludeSocketNotifiers |
QEventLoop.ExcludeUserInputEvents)
def reset_setting(_arg: typing.Any) -> None:
def reset_setting(_arg: Any) -> None:
"""Set the JavascriptCanOpenWindows setting to its old value."""
assert view is not None
try:

View File

@ -26,7 +26,7 @@ Module attributes:
import os
import operator
import typing
from typing import cast, Any, List, Optional, Tuple, Union
from PyQt5.QtGui import QFont
from PyQt5.QtWebEngineWidgets import (QWebEngineSettings, QWebEngineProfile,
@ -39,11 +39,11 @@ from qutebrowser.utils import (utils, standarddir, qtutils, message, log,
urlmatch, usertypes)
# The default QWebEngineProfile
default_profile = typing.cast(QWebEngineProfile, None)
default_profile = cast(QWebEngineProfile, None)
# The QWebEngineProfile used for private (off-the-record) windows
private_profile = None # type: typing.Optional[QWebEngineProfile]
private_profile: Optional[QWebEngineProfile] = None
# The global WebEngineSettings object
global_settings = typing.cast('WebEngineSettings', None)
global_settings = cast('WebEngineSettings', None)
parsed_user_agent = None
@ -183,7 +183,7 @@ class WebEngineSettings(websettings.AbstractSettings):
}
def set_unknown_url_scheme_policy(
self, policy: typing.Union[str, usertypes.Unset]) -> bool:
self, policy: Union[str, usertypes.Unset]) -> bool:
"""Set the UnknownUrlSchemePolicy to use.
Return:
@ -448,10 +448,10 @@ def _init_site_specific_quirks():
def _init_devtools_settings():
"""Make sure the devtools always get images/JS permissions."""
settings = [
settings: List[Tuple[str, Any]] = [
('content.javascript.enabled', True),
('content.images', True)
] # type: typing.List[typing.Tuple[str, typing.Any]]
]
if qtutils.version_check('5.11'):
settings.append(('content.cookies.accept', 'all'))

View File

@ -23,7 +23,7 @@ import math
import functools
import re
import html as html_utils
import typing
from typing import cast, Optional, Union
from PyQt5.QtCore import (pyqtSignal, pyqtSlot, Qt, QPoint, QPointF, QUrl,
QTimer, QObject)
@ -670,7 +670,7 @@ class WebEngineHistoryPrivate(browsertab.AbstractHistoryPrivate):
def __init__(self, tab: 'WebEngineTab') -> None:
self._tab = tab
self._history = typing.cast(QWebEngineHistory, None)
self._history = cast(QWebEngineHistory, None)
def serialize(self):
if not qtutils.version_check('5.9', compiled=False):
@ -927,7 +927,7 @@ class _WebEnginePermissions(QObject):
def __init__(self, tab, parent=None):
super().__init__(parent)
self._tab = tab
self._widget = typing.cast(QWidget, None)
self._widget = cast(QWidget, None)
try:
self._options.update({
@ -1083,7 +1083,7 @@ class _WebEngineScripts(QObject):
def __init__(self, tab, parent=None):
super().__init__(parent)
self._tab = tab
self._widget = typing.cast(QWidget, None)
self._widget = cast(QWidget, None)
self._greasemonkey = greasemonkey.gm_manager
def connect_signals(self):
@ -1376,7 +1376,7 @@ class WebEngineTab(browsertab.AbstractTab):
self.backend = usertypes.Backend.QtWebEngine
self._child_event_filter = None
self._saved_zoom = None
self._reload_url = None # type: typing.Optional[QUrl]
self._reload_url: Optional[QUrl] = None
self._scripts.init()
def _set_widget(self, widget):
@ -1443,9 +1443,9 @@ class WebEngineTab(browsertab.AbstractTab):
self._widget.page().toHtml(callback)
def run_js_async(self, code, callback=None, *, world=None):
world_id_type = typing.Union[QWebEngineScript.ScriptWorldId, int]
world_id_type = Union[QWebEngineScript.ScriptWorldId, int]
if world is None:
world_id = QWebEngineScript.ApplicationWorld # type: world_id_type
world_id: world_id_type = QWebEngineScript.ApplicationWorld
elif isinstance(world, int):
world_id = world
if not 0 <= world_id <= qtutils.MAX_WORLD_ID:

View File

@ -19,7 +19,7 @@
"""The main browser widget for QtWebEngine."""
import typing
from typing import Optional
from PyQt5.QtCore import pyqtSignal, QUrl, PYQT_VERSION
from PyQt5.QtGui import QPalette
@ -70,7 +70,7 @@ class WebEngineView(QWebEngineView):
The above bug got introduced in Qt 5.11.0 and fixed in 5.12.0.
"""
proxy = self.focusProxy() # type: typing.Optional[QWidget]
proxy: Optional[QWidget] = self.focusProxy()
if 'lost-focusproxy' in objects.debug_flags:
proxy = None

View File

@ -19,7 +19,7 @@
"""HTTP network cache."""
import typing
from typing import cast
import os.path
from PyQt5.QtNetwork import QNetworkDiskCache
@ -28,7 +28,7 @@ from qutebrowser.config import config
from qutebrowser.utils import utils, qtutils, standarddir
diskcache = typing.cast('DiskCache', None)
diskcache = cast('DiskCache', None)
class DiskCache(QNetworkDiskCache):

View File

@ -19,7 +19,7 @@
"""Handling of HTTP cookies."""
import typing
from typing import Sequence
from PyQt5.QtNetwork import QNetworkCookie, QNetworkCookieJar
from PyQt5.QtCore import pyqtSignal, QDateTime
@ -93,7 +93,7 @@ class CookieJar(RAMCookieJar):
def parse_cookies(self):
"""Parse cookies from lineparser and store them."""
cookies = [] # type: typing.Sequence[QNetworkCookie]
cookies: Sequence[QNetworkCookie] = []
for line in self._lineparser:
line_cookies = QNetworkCookie.parseCookies(line)
cookies += line_cookies # type: ignore[operator]

View File

@ -33,7 +33,7 @@ import email.encoders
import email.mime.multipart
import email.message
import quopri
import typing
from typing import MutableMapping, Set, Tuple
import attr
from PyQt5.QtCore import QUrl
@ -186,7 +186,7 @@ class MHTMLWriter:
self.root_content = root_content
self.content_location = content_location
self.content_type = content_type
self._files = {} # type: typing.MutableMapping[QUrl, _File]
self._files: MutableMapping[QUrl, _File] = {}
def add_file(self, location, content, content_type=None,
transfer_encoding=E_QUOPRI):
@ -241,8 +241,7 @@ class MHTMLWriter:
return msg
_PendingDownloadType = typing.Set[
typing.Tuple[QUrl, downloads.AbstractDownloadItem]]
_PendingDownloadType = Set[Tuple[QUrl, downloads.AbstractDownloadItem]]
class _Downloader:
@ -265,7 +264,7 @@ class _Downloader:
self.target = target
self.writer = None
self.loaded_urls = {tab.url()}
self.pending_downloads = set() # type: _PendingDownloadType
self.pending_downloads: _PendingDownloadType = set()
self._finished_file = False
self._used = False

View File

@ -21,7 +21,7 @@
import collections
import html
import typing
from typing import TYPE_CHECKING, Dict, MutableMapping, Optional, Sequence
import attr
from PyQt5.QtCore import (pyqtSlot, pyqtSignal, QCoreApplication, QUrl,
@ -40,12 +40,12 @@ from qutebrowser.browser.webkit.network import (webkitqutescheme, networkreply,
filescheme)
from qutebrowser.misc import objects
if typing.TYPE_CHECKING:
if TYPE_CHECKING:
from qutebrowser.mainwindow import prompt
HOSTBLOCK_ERROR_STRING = '%HOSTBLOCK%'
_proxy_auth_cache = {} # type: typing.Dict[ProxyId, prompt.AuthInfo]
_proxy_auth_cache: Dict['ProxyId', 'prompt.AuthInfo'] = {}
@attr.s(frozen=True)
@ -123,8 +123,7 @@ def init():
QSslSocket.setDefaultCiphers(good_ciphers)
_SavedErrorsType = typing.MutableMapping[urlutils.HostTupleType,
typing.Sequence[QSslError]]
_SavedErrorsType = MutableMapping[urlutils.HostTupleType, Sequence[QSslError]]
class NetworkManager(QNetworkAccessManager):
@ -173,10 +172,8 @@ class NetworkManager(QNetworkAccessManager):
self._set_cache()
self.sslErrors.connect( # type: ignore[attr-defined]
self.on_ssl_errors)
self._rejected_ssl_errors = collections.defaultdict(
list) # type: _SavedErrorsType
self._accepted_ssl_errors = collections.defaultdict(
list) # type: _SavedErrorsType
self._rejected_ssl_errors: _SavedErrorsType = collections.defaultdict(list)
self._accepted_ssl_errors: _SavedErrorsType = collections.defaultdict(list)
self.authenticationRequired.connect( # type: ignore[attr-defined]
self.on_authentication_required)
self.proxyAuthenticationRequired.connect( # type: ignore[attr-defined]
@ -241,8 +238,8 @@ class NetworkManager(QNetworkAccessManager):
log.network.debug("Certificate errors: {!r}".format(
' / '.join(str(err) for err in errors)))
try:
host_tpl = urlutils.host_tuple(
reply.url()) # type: typing.Optional[urlutils.HostTupleType]
host_tpl: Optional[urlutils.HostTupleType] = urlutils.host_tuple(
reply.url())
except ValueError:
host_tpl = None
is_accepted = False

View File

@ -19,7 +19,7 @@
"""Utilities related to QWebHistory."""
import typing
from typing import Any, List, Mapping
from PyQt5.QtCore import QByteArray, QDataStream, QIODevice, QUrl
@ -81,7 +81,7 @@ def serialize(items):
"""
data = QByteArray()
stream = QDataStream(data, QIODevice.ReadWrite)
user_data = [] # type: typing.List[typing.Mapping[str, typing.Any]]
user_data: List[Mapping[str, Any]] = []
current_idx = None

View File

@ -19,7 +19,7 @@
"""QtWebKit specific part of the web element API."""
import typing
from typing import cast, TYPE_CHECKING, Iterator, List, Optional, Set
from PyQt5.QtCore import QRect, Qt
from PyQt5.QtWebKit import QWebElement, QWebSettings
@ -29,7 +29,7 @@ from qutebrowser.config import config
from qutebrowser.utils import log, utils, javascript, usertypes
from qutebrowser.browser import webelem
if typing.TYPE_CHECKING:
if TYPE_CHECKING:
from qutebrowser.browser.webkit import webkittab
@ -80,7 +80,7 @@ class WebKitElement(webelem.AbstractWebElement):
self._check_vanished()
return self._elem.hasAttribute(key)
def __iter__(self) -> typing.Iterator[str]:
def __iter__(self) -> Iterator[str]:
self._check_vanished()
yield from self._elem.attributeNames()
@ -101,7 +101,7 @@ class WebKitElement(webelem.AbstractWebElement):
self._check_vanished()
return self._elem.geometry()
def classes(self) -> typing.Set[str]:
def classes(self) -> Set[str]:
self._check_vanished()
return set(self._elem.classes())
@ -174,21 +174,20 @@ class WebKitElement(webelem.AbstractWebElement):
this.dispatchEvent(event);
""".format(javascript.to_js(text)))
def _parent(self) -> typing.Optional['WebKitElement']:
def _parent(self) -> Optional['WebKitElement']:
"""Get the parent element of this element."""
self._check_vanished()
elem = typing.cast(typing.Optional[QWebElement],
self._elem.parent())
elem = cast(Optional[QWebElement], self._elem.parent())
if elem is None or elem.isNull():
return None
if typing.TYPE_CHECKING:
if TYPE_CHECKING:
# pylint: disable=used-before-assignment
assert isinstance(self._tab, webkittab.WebKitTab)
return WebKitElement(elem, tab=self._tab)
def _rect_on_view_js(self) -> typing.Optional[QRect]:
def _rect_on_view_js(self) -> Optional[QRect]:
"""Javascript implementation for rect_on_view."""
# FIXME:qtwebengine maybe we can reuse this?
rects = self._elem.evaluateJavaScript("this.getClientRects()")
@ -218,7 +217,7 @@ class WebKitElement(webelem.AbstractWebElement):
rect = QRect(int(rect["left"]), int(rect["top"]),
int(width), int(height))
frame = typing.cast(typing.Optional[QWebFrame], self._elem.webFrame())
frame = cast(Optional[QWebFrame], self._elem.webFrame())
while frame is not None:
# Translate to parent frames' position (scroll position
# is taken care of inside getClientRects)
@ -229,8 +228,7 @@ class WebKitElement(webelem.AbstractWebElement):
return None
def _rect_on_view_python(self,
elem_geometry: typing.Optional[QRect]) -> QRect:
def _rect_on_view_python(self, elem_geometry: Optional[QRect]) -> QRect:
"""Python implementation for rect_on_view."""
if elem_geometry is None:
geometry = self._elem.geometry()
@ -238,11 +236,11 @@ class WebKitElement(webelem.AbstractWebElement):
geometry = elem_geometry
rect = QRect(geometry)
frame = typing.cast(typing.Optional[QWebFrame], self._elem.webFrame())
frame = cast(Optional[QWebFrame], self._elem.webFrame())
while frame is not None:
rect.translate(frame.geometry().topLeft())
rect.translate(frame.scrollPosition() * -1)
frame = typing.cast(typing.Optional[QWebFrame], frame.parentFrame())
frame = cast(Optional[QWebFrame], frame.parentFrame())
return rect
@ -336,7 +334,7 @@ class WebKitElement(webelem.AbstractWebElement):
return all([visible_on_screen, visible_in_frame])
def remove_blank_target(self) -> None:
elem = self # type: typing.Optional[WebKitElement]
elem: Optional[WebKitElement] = self
for _ in range(5):
if elem is None:
break
@ -381,7 +379,7 @@ class WebKitElement(webelem.AbstractWebElement):
super()._click_fake_event(click_target)
def get_child_frames(startframe: QWebFrame) -> typing.List[QWebFrame]:
def get_child_frames(startframe: QWebFrame) -> List[QWebFrame]:
"""Get all children recursively of a given QWebFrame.
Loosely based on http://blog.nextgenetics.net/?e=64
@ -395,7 +393,7 @@ def get_child_frames(startframe: QWebFrame) -> typing.List[QWebFrame]:
results = []
frames = [startframe]
while frames:
new_frames = [] # type: typing.List[QWebFrame]
new_frames: List[QWebFrame] = []
for frame in frames:
results.append(frame)
new_frames += frame.childFrames()

View File

@ -24,7 +24,7 @@ Module attributes:
constants.
"""
import typing
from typing import cast
import os.path
from PyQt5.QtCore import QUrl
@ -39,7 +39,7 @@ from qutebrowser.browser import shared
# The global WebKitSettings object
global_settings = typing.cast('WebKitSettings', None)
global_settings = cast('WebKitSettings', None)
parsed_user_agent = None

View File

@ -22,7 +22,7 @@
import re
import functools
import xml.etree.ElementTree
import typing
from typing import cast, Iterable
from PyQt5.QtCore import pyqtSlot, Qt, QUrl, QPoint, QTimer, QSizeF, QSize
from PyQt5.QtGui import QIcon
@ -624,7 +624,7 @@ class WebKitHistoryPrivate(browsertab.AbstractHistoryPrivate):
def __init__(self, tab: 'WebKitTab') -> None:
self._tab = tab
self._history = typing.cast(QWebHistory, None)
self._history = cast(QWebHistory, None)
def serialize(self):
return qtutils.serialize(self._history)
@ -703,8 +703,7 @@ class WebKitElements(browsertab.AbstractElements):
elems = []
frames = webkitelem.get_child_frames(mainframe)
for f in frames:
frame_elems = typing.cast(
typing.Iterable[QWebElement], f.findAllElements(selector))
frame_elems = cast(Iterable[QWebElement], f.findAllElements(selector))
for elem in frame_elems:
elems.append(webkitelem.WebKitElement(elem, tab=self._tab))

View File

@ -21,7 +21,7 @@
import html
import functools
import typing
from typing import cast
from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QUrl, QPoint
from PyQt5.QtGui import QDesktopServices
@ -353,11 +353,11 @@ class BrowserPage(QWebPage):
self.setFeaturePermission, frame, feature,
QWebPage.PermissionDeniedByUser)
url = frame.url().adjusted(typing.cast(QUrl.FormattingOptions,
QUrl.RemoveUserInfo |
QUrl.RemovePath |
QUrl.RemoveQuery |
QUrl.RemoveFragment))
url = frame.url().adjusted(cast(QUrl.FormattingOptions,
QUrl.RemoveUserInfo |
QUrl.RemovePath |
QUrl.RemoveQuery |
QUrl.RemoveFragment))
question = shared.feature_permission(
url=url,
option=options[feature], msg=messages[feature],