mypy: check_untyped_defs for most of qutebrowser.browser
This commit is contained in:
parent
3a9d0bd3ff
commit
7ada7082aa
10
mypy.ini
10
mypy.ini
|
|
@ -126,8 +126,14 @@ disallow_incomplete_defs = True
|
|||
disallow_untyped_defs = True
|
||||
disallow_incomplete_defs = True
|
||||
|
||||
# [mypy-qutebrowser.browser.*]
|
||||
# check_untyped_defs = True
|
||||
[mypy-qutebrowser.browser.*]
|
||||
check_untyped_defs = True
|
||||
|
||||
[mypy-qutebrowser.browser.webengine.*]
|
||||
check_untyped_defs = False
|
||||
|
||||
[mypy-qutebrowser.browser.webkit.*]
|
||||
check_untyped_defs = False
|
||||
|
||||
[mypy-qutebrowser.commands.*]
|
||||
check_untyped_defs = True
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ from qutebrowser.browser import downloads, qtnetworkdownloads
|
|||
from qutebrowser.utils import objreg
|
||||
|
||||
|
||||
UnsupportedAttribute = downloads.UnsupportedAttribute
|
||||
|
||||
|
||||
class TempDownload(QObject):
|
||||
|
||||
"""A download of some data into a file object."""
|
||||
|
|
|
|||
|
|
@ -640,9 +640,9 @@ class CommandDispatcher:
|
|||
assert what in ['url', 'pretty-url', 'markdown'], what
|
||||
flags = QUrl.RemovePassword
|
||||
if what == 'pretty-url':
|
||||
flags |= QUrl.DecodeReserved
|
||||
flags |= QUrl.DecodeReserved # type: ignore
|
||||
else:
|
||||
flags |= QUrl.FullyEncoded
|
||||
flags |= QUrl.FullyEncoded # type: ignore
|
||||
url = QUrl(self._current_url())
|
||||
url_query = QUrlQuery()
|
||||
url_query_str = urlutils.query_string(url)
|
||||
|
|
@ -653,7 +653,7 @@ class CommandDispatcher:
|
|||
if key in config.val.url.yank_ignored_parameters:
|
||||
url_query.removeQueryItem(key)
|
||||
url.setQuery(url_query)
|
||||
return url.toString(flags)
|
||||
return url.toString(flags) # type: ignore
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
@cmdutils.argument('what', choices=['selection', 'url', 'pretty-url',
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import functools
|
|||
import pathlib
|
||||
import tempfile
|
||||
import enum
|
||||
import typing
|
||||
|
||||
from PyQt5.QtCore import (pyqtSlot, pyqtSignal, Qt, QObject, QModelIndex,
|
||||
QTimer, QAbstractListModel, QUrl)
|
||||
|
|
@ -48,7 +49,7 @@ class ModelRole(enum.IntEnum):
|
|||
|
||||
|
||||
# Remember the last used directory
|
||||
last_used_directory = None
|
||||
last_used_directory = None # type: typing.Optional[str]
|
||||
|
||||
# All REFRESH_INTERVAL milliseconds, speeds will be recalculated and downloads
|
||||
# redrawn.
|
||||
|
|
@ -226,12 +227,13 @@ def suggested_fn_from_title(url_path, title=None):
|
|||
"""
|
||||
ext_whitelist = [".html", ".htm", ".php", ""]
|
||||
_, ext = os.path.splitext(url_path)
|
||||
|
||||
suggested_fn = None # type: typing.Optional[str]
|
||||
if ext.lower() in ext_whitelist and title:
|
||||
suggested_fn = utils.sanitize_filename(title)
|
||||
if not suggested_fn.lower().endswith((".html", ".htm")):
|
||||
suggested_fn += ".html"
|
||||
else:
|
||||
suggested_fn = None
|
||||
|
||||
return suggested_fn
|
||||
|
||||
|
||||
|
|
@ -352,7 +354,8 @@ class DownloadItemStats(QObject):
|
|||
self.speed = 0
|
||||
self._last_done = 0
|
||||
samples = int(self.SPEED_AVG_WINDOW * (1000 / _REFRESH_INTERVAL))
|
||||
self._speed_avg = collections.deque(maxlen=samples)
|
||||
self._speed_avg = collections.deque(
|
||||
maxlen=samples) # type: typing.Sequence[float]
|
||||
|
||||
def update_speed(self):
|
||||
"""Recalculate the current download speed.
|
||||
|
|
@ -451,7 +454,8 @@ class AbstractDownloadItem(QObject):
|
|||
self.basename = '???'
|
||||
self.successful = False
|
||||
|
||||
self.fileobj = UnsupportedAttribute()
|
||||
self.fileobj = UnsupportedAttribute(
|
||||
) # type: typing.Union[UnsupportedAttribute, typing.IO[bytes]]
|
||||
self.raw_headers = UnsupportedAttribute()
|
||||
|
||||
self._filename = None
|
||||
|
|
@ -830,7 +834,7 @@ class AbstractDownloadManager(QObject):
|
|||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.downloads = []
|
||||
self.downloads = [] # type: typing.Sequence[AbstractDownloadItem]
|
||||
self._update_timer = usertypes.Timer(self, 'download-update')
|
||||
self._update_timer.timeout.connect(self._update_gui)
|
||||
self._update_timer.setInterval(_REFRESH_INTERVAL)
|
||||
|
|
@ -1195,7 +1199,7 @@ class DownloadModel(QAbstractListModel):
|
|||
|
||||
item = self[index.row()]
|
||||
if role == Qt.DisplayRole:
|
||||
data = str(item)
|
||||
data = str(item) # type: typing.Any
|
||||
elif role == Qt.ForegroundRole:
|
||||
data = item.get_status_color('fg')
|
||||
elif role == Qt.BackgroundRole:
|
||||
|
|
@ -1241,7 +1245,7 @@ class TempDownloadManager:
|
|||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.files = []
|
||||
self.files = [] # type: typing.Sequence[typing.IO[str]]
|
||||
self._tmpdir = None
|
||||
|
||||
def cleanup(self):
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
"""The ListView to display downloads in."""
|
||||
|
||||
import functools
|
||||
import typing
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, QSize, Qt, QTimer
|
||||
from PyQt5.QtWidgets import QListView, QSizePolicy, QMenu, QStyleFactory
|
||||
|
|
@ -53,6 +54,14 @@ 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]],
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
class DownloadView(QListView):
|
||||
|
||||
"""QListView which shows currently running downloads as a bar.
|
||||
|
|
@ -123,19 +132,14 @@ class DownloadView(QListView):
|
|||
item.open_file()
|
||||
item.remove()
|
||||
|
||||
def _get_menu_actions(self, item):
|
||||
def _get_menu_actions(self, item) -> _ActionListType:
|
||||
"""Get the available context menu actions for a given DownloadItem.
|
||||
|
||||
Args:
|
||||
item: The DownloadItem to get the actions for, or None.
|
||||
|
||||
Return:
|
||||
A list of either:
|
||||
- (QAction, callable) tuples.
|
||||
- (None, None) for a separator
|
||||
"""
|
||||
model = self.model()
|
||||
actions = []
|
||||
actions = [] # type: _ActionListType
|
||||
if item is None:
|
||||
pass
|
||||
elif item.done:
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import fnmatch
|
|||
import functools
|
||||
import glob
|
||||
import textwrap
|
||||
import typing
|
||||
|
||||
import attr
|
||||
from PyQt5.QtCore import pyqtSignal, QObject, QUrl
|
||||
|
|
@ -50,10 +51,10 @@ class GreasemonkeyScript:
|
|||
def __init__(self, properties, code, # noqa: C901 pragma: no mccabe
|
||||
filename=None):
|
||||
self._code = code
|
||||
self.includes = []
|
||||
self.matches = []
|
||||
self.excludes = []
|
||||
self.requires = []
|
||||
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.description = None
|
||||
self.name = None
|
||||
self.namespace = None
|
||||
|
|
@ -253,10 +254,11 @@ class GreasemonkeyManager(QObject):
|
|||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self._run_start = []
|
||||
self._run_end = []
|
||||
self._run_idle = []
|
||||
self._in_progress_dls = []
|
||||
self._run_start = [] # type: typing.Sequence[GreasemonkeyScript]
|
||||
self._run_end = [] # type: typing.Sequence[GreasemonkeyScript]
|
||||
self._run_idle = [] # type: typing.Sequence[GreasemonkeyScript]
|
||||
self._in_progress_dls = [
|
||||
] # type: typing.Sequence[downloads.AbstractDownloadItem]
|
||||
|
||||
self.load_scripts()
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
import os
|
||||
import time
|
||||
import contextlib
|
||||
import typing
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal
|
||||
from PyQt5.QtWidgets import QProgressDialog, QApplication
|
||||
|
|
@ -55,7 +56,7 @@ class HistoryProgress:
|
|||
self._progress.setMinimumDuration(500)
|
||||
self._progress.setLabelText(text)
|
||||
self._progress.setMaximum(maximum)
|
||||
self._progress.setCancelButton(None)
|
||||
self._progress.setCancelButton(None) # type: ignore
|
||||
self._progress.show()
|
||||
QApplication.processEvents()
|
||||
|
||||
|
|
@ -206,7 +207,11 @@ class WebHistory(sql.SqlTable):
|
|||
return any(pattern.matches(url) for pattern in patterns)
|
||||
|
||||
def _rebuild_completion(self):
|
||||
data = {'url': [], 'title': [], 'last_atime': []}
|
||||
data = {
|
||||
'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%" '
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
import re
|
||||
import posixpath
|
||||
import typing
|
||||
|
||||
from PyQt5.QtCore import QUrl
|
||||
|
||||
|
|
@ -96,7 +97,9 @@ def incdec(url, count, inc_or_dec):
|
|||
window: Open the link in a new window.
|
||||
"""
|
||||
urlutils.ensure_valid(url)
|
||||
segments = set(config.val.url.incdec_segments)
|
||||
segments = (
|
||||
set(config.val.url.incdec_segments)
|
||||
) # type: typing.Optional[typing.Set[str]]
|
||||
|
||||
if segments is None:
|
||||
segments = {'path', 'query'}
|
||||
|
|
@ -159,7 +162,8 @@ def _find_prevnext(prev, elems):
|
|||
# pylint: disable=bad-config-option
|
||||
for regex in getattr(config.val.hints, option):
|
||||
# pylint: enable=bad-config-option
|
||||
log.hints.vdebug("== Checking regex '{}'.".format(regex.pattern))
|
||||
log.hints.vdebug("== Checking regex '{}'." # type: ignore
|
||||
.format(regex.pattern))
|
||||
for e in elems:
|
||||
text = str(e)
|
||||
if not text:
|
||||
|
|
@ -169,7 +173,8 @@ def _find_prevnext(prev, elems):
|
|||
regex.pattern, text))
|
||||
return e
|
||||
else:
|
||||
log.hints.vdebug("No match on '{}'!".format(text))
|
||||
log.hints.vdebug("No match on '{}'!" # type: ignore
|
||||
.format(text))
|
||||
return None
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -214,9 +214,10 @@ class PACResolver:
|
|||
if from_file:
|
||||
string_flags = QUrl.PrettyDecoded
|
||||
else:
|
||||
string_flags = QUrl.RemoveUserInfo
|
||||
string_flags = QUrl.RemoveUserInfo # type: ignore
|
||||
if query.url().scheme() == 'https':
|
||||
string_flags |= QUrl.RemovePath | QUrl.RemoveQuery
|
||||
string_flags |= QUrl.RemovePath # type: ignore
|
||||
string_flags |= QUrl.RemoveQuery # type: ignore
|
||||
|
||||
result = self._resolver.call([query.url().toString(string_flags),
|
||||
query.peerHostName()])
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ def _warn_for_pac():
|
|||
|
||||
@pyqtSlot()
|
||||
def shutdown():
|
||||
QNetworkProxyFactory.setApplicationProxyFactory(None)
|
||||
QNetworkProxyFactory.setApplicationProxyFactory(None) # type: ignore
|
||||
|
||||
|
||||
class ProxyFactory(QNetworkProxyFactory):
|
||||
|
|
@ -99,9 +99,10 @@ class ProxyFactory(QNetworkProxyFactory):
|
|||
for p in proxies:
|
||||
if p.type() != QNetworkProxy.NoProxy:
|
||||
capabilities = p.capabilities()
|
||||
lookup_cap = QNetworkProxy.HostNameLookupCapability
|
||||
if config.val.content.proxy_dns_requests:
|
||||
capabilities |= QNetworkProxy.HostNameLookupCapability
|
||||
capabilities |= lookup_cap # type: ignore
|
||||
else:
|
||||
capabilities &= ~QNetworkProxy.HostNameLookupCapability
|
||||
capabilities &= ~lookup_cap # type: ignore
|
||||
p.setCapabilities(capabilities)
|
||||
return proxies
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ def _generate_pdfjs_script(filename):
|
|||
viewer.open({{ url }});
|
||||
});
|
||||
""").render(
|
||||
url=javascript.to_js(url.toString(QUrl.FullyEncoded)),
|
||||
url=javascript.to_js(url.toString(QUrl.FullyEncoded)), # type: ignore
|
||||
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-70420
|
||||
disable_create_object_url=(
|
||||
not qtutils.version_check('5.12') and
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import textwrap
|
|||
import urllib
|
||||
import collections
|
||||
import base64
|
||||
import typing
|
||||
|
||||
try:
|
||||
import secrets
|
||||
|
|
@ -190,7 +191,8 @@ def qute_bookmarks(_url):
|
|||
@add_handler('tabs')
|
||||
def qute_tabs(_url):
|
||||
"""Handler for qute://tabs. Display information about all open tabs."""
|
||||
tabs = collections.defaultdict(list)
|
||||
tabs = collections.defaultdict(
|
||||
list) # type: typing.Dict[str, typing.List[typing.Tuple[str, str]]]
|
||||
for win_id, window in objreg.window_registry.items():
|
||||
if sip.isdeleted(window):
|
||||
continue
|
||||
|
|
@ -234,15 +236,16 @@ def history_data(start_time, offset=None):
|
|||
def qute_history(url):
|
||||
"""Handler for qute://history. Display and serve history."""
|
||||
if url.path() == '/data':
|
||||
q_offset = QUrlQuery(url).queryItemValue("offset")
|
||||
try:
|
||||
offset = QUrlQuery(url).queryItemValue("offset")
|
||||
offset = int(offset) if offset else None
|
||||
offset = int(q_offset) if q_offset else None
|
||||
except ValueError:
|
||||
raise UrlInvalidError("Query parameter offset is invalid")
|
||||
|
||||
# Use start_time in query or current time.
|
||||
q_start_time = QUrlQuery(url).queryItemValue("start_time")
|
||||
try:
|
||||
start_time = QUrlQuery(url).queryItemValue("start_time")
|
||||
start_time = float(start_time) if start_time else time.time()
|
||||
start_time = float(q_start_time) if q_start_time else time.time()
|
||||
except ValueError:
|
||||
raise UrlInvalidError("Query parameter start_time is invalid")
|
||||
|
||||
|
|
@ -451,9 +454,11 @@ def qute_bindings(_url):
|
|||
"""Handler for qute://bindings. View keybindings."""
|
||||
bindings = {}
|
||||
defaults = config.val.bindings.default
|
||||
modes = set(defaults.keys()).union(config.val.bindings.commands)
|
||||
modes.remove('normal')
|
||||
modes = ['normal'] + sorted(list(modes))
|
||||
|
||||
config_modes = set(defaults.keys()).union(config.val.bindings.commands)
|
||||
config_modes.remove('normal')
|
||||
|
||||
modes = ['normal'] + sorted(list(config_modes))
|
||||
for mode in modes:
|
||||
bindings[mode] = config.key_instance.get_bindings_for(mode)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
import os
|
||||
import html
|
||||
import netrc
|
||||
import typing
|
||||
|
||||
from PyQt5.QtCore import QUrl
|
||||
|
||||
|
|
@ -138,7 +139,7 @@ _JS_LOGMAP = {
|
|||
'info': log.js.info,
|
||||
'warning': log.js.warning,
|
||||
'error': log.js.error,
|
||||
}
|
||||
} # type: typing.Mapping[str, typing.Callable[[str], None]]
|
||||
|
||||
|
||||
def javascript_log_message(level, source, line, msg):
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import os.path
|
|||
import html
|
||||
import functools
|
||||
import collections
|
||||
import typing
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, QUrl, QObject
|
||||
|
||||
|
|
@ -77,7 +78,8 @@ class UrlMarkManager(QObject):
|
|||
"""Initialize and read quickmarks."""
|
||||
super().__init__(parent)
|
||||
|
||||
self.marks = collections.OrderedDict()
|
||||
self.marks = collections.OrderedDict(
|
||||
) # type: typing.MutableMapping[str, QUrl]
|
||||
|
||||
self._init_lineparser()
|
||||
for line in self._lineparser:
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ class HostBlocker:
|
|||
self._in_progress.append(download)
|
||||
self._on_download_finished(download)
|
||||
|
||||
def _merge_file(self, byte_io: io.BytesIO) -> None:
|
||||
def _merge_file(self, byte_io: typing.IO[bytes]) -> None:
|
||||
"""Read and merge host files.
|
||||
|
||||
Args:
|
||||
|
|
@ -303,6 +303,8 @@ class HostBlocker:
|
|||
self._in_progress.remove(download)
|
||||
if download.successful:
|
||||
self._done_count += 1
|
||||
assert not isinstance(download.fileobj,
|
||||
downloads.UnsupportedAttribute)
|
||||
try:
|
||||
self._merge_file(download.fileobj)
|
||||
finally:
|
||||
|
|
|
|||
Loading…
Reference in New Issue