mypy: check_untyped_defs for qutebrowser.misc

This commit is contained in:
Florian Bruhin 2019-10-15 21:24:13 +02:00
parent d38752aa82
commit 3a9d0bd3ff
16 changed files with 108 additions and 72 deletions

View File

@ -141,8 +141,8 @@ check_untyped_defs = True
[mypy-qutebrowser.mainwindow.*]
check_untyped_defs = True
# [mypy-qutebrowser.misc.*]
# check_untyped_defs = True
[mypy-qutebrowser.misc.*]
check_untyped_defs = True
[mypy-qutebrowser.app]
check_untyped_defs = True

View File

@ -19,6 +19,8 @@
"""Command history for the status bar."""
import typing
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
from qutebrowser.utils import usertypes, log, standarddir, objreg
@ -58,7 +60,7 @@ class History(QObject):
super().__init__(parent)
self._tmphist = None
if history is None:
self.history = []
self.history = [] # type: typing.Sequence[str]
else:
self.history = history

View File

@ -173,7 +173,7 @@ class ConsoleWidget(QWidget):
'objreg': objreg,
}
self._more = False
self._buffer = []
self._buffer = [] # type: typing.MutableSequence[str]
self._lineedit = ConsoleLineEdit(namespace, self)
self._lineedit.execute.connect(self.push)
self._output = ConsoleTextEdit()

View File

@ -28,6 +28,7 @@ import fnmatch
import traceback
import datetime
import enum
import typing
import pkg_resources
from PyQt5.QtCore import pyqtSlot, Qt, QSize
@ -117,7 +118,7 @@ class _CrashDialog(QDialog):
super().__init__(parent)
# We don't set WA_DeleteOnClose here as on an exception, we'll get
# closed anyways, and it only could have unintended side-effects.
self._crash_info = []
self._crash_info = [] # type: typing.Sequence[typing.Tuple[str, str]]
self._btn_box = None
self._btn_report = None
self._btn_cancel = None
@ -135,18 +136,23 @@ class _CrashDialog(QDialog):
info = QLabel("What were you doing when this crash/bug happened?")
self._vbox.addWidget(info)
self._info = QTextEdit(tabChangesFocus=True, acceptRichText=False)
self._info = QTextEdit()
self._info.setTabChangesFocus(True)
self._info.setAcceptRichText(False)
self._info.setPlaceholderText("- Opened http://www.example.com/\n"
"- Switched tabs\n"
"- etc...")
self._vbox.addWidget(self._info, 5)
self._vbox.addSpacing(15)
self._debug_log = QTextEdit(tabChangesFocus=True, acceptRichText=False,
lineWrapMode=QTextEdit.NoWrap)
self._debug_log = QTextEdit()
self._debug_log.setTabChangesFocus(True)
self._debug_log.setAcceptRichText(False)
self._debug_log.setLineWrapMode(QTextEdit.NoWrap)
self._debug_log.hide()
info = QLabel("<i>You can edit the log below to remove sensitive "
"information.</i>", wordWrap=True)
"information.</i>")
info.setWordWrap(True)
info.hide()
self._fold = miscwidgets.DetailFold("Show log", self)
self._fold.toggled.connect(self._debug_log.setVisible)
@ -174,10 +180,12 @@ class _CrashDialog(QDialog):
"""Initialize the widget asking for contact info."""
contact = QLabel("I'd like to be able to follow up with you, to keep "
"you posted on the status of this crash and get more "
"information if I need it - how can I contact you?",
wordWrap=True)
"information if I need it - how can I contact you?")
contact.setWordWrap(True)
self._vbox.addWidget(contact)
self._contact = QTextEdit(tabChangesFocus=True, acceptRichText=False)
self._contact = QTextEdit()
self._contact.setTabChangesFocus(True)
self._contact.setAcceptRichText(False)
try:
try:
info = configfiles.state['general']['contact-info']
@ -195,8 +203,10 @@ class _CrashDialog(QDialog):
Should be extended by subclasses to set the actual text.
"""
self._lbl = QLabel(wordWrap=True, openExternalLinks=True,
textInteractionFlags=Qt.LinksAccessibleByMouse)
self._lbl = QLabel()
self._lbl.setWordWrap(True)
self._lbl.setOpenExternalLinks(True)
self._lbl.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
self._vbox.addWidget(self._lbl)
def _init_checkboxes(self):
@ -207,19 +217,21 @@ class _CrashDialog(QDialog):
self._btn_box = QDialogButtonBox()
self._vbox.addWidget(self._btn_box)
self._btn_report = QPushButton("Report", default=True)
self._btn_report = QPushButton("Report")
self._btn_report.setDefault(True)
self._btn_report.clicked.connect(self.on_report_clicked)
self._btn_box.addButton(self._btn_report, QDialogButtonBox.AcceptRole)
self._btn_cancel = QPushButton("Don't report", autoDefault=False)
self._btn_cancel = QPushButton("Don't report")
self._btn_cancel.setAutoDefault(False)
self._btn_cancel.clicked.connect(self.finish)
self._btn_box.addButton(self._btn_cancel, QDialogButtonBox.RejectRole)
def _init_info_text(self):
"""Add an info text encouraging the user to report crashes."""
info_label = QLabel("<br/><b>Note that without your help, I can't fix "
"the bug you encountered.</b>",
wordWrap=True)
"the bug you encountered.</b>")
info_label.setWordWrap(True)
self._vbox.addWidget(info_label)
def _gather_crash_info(self):
@ -338,7 +350,7 @@ class _CrashDialog(QDialog):
text: The paste text to show.
"""
error_dlg = ReportErrorDialog(text, self._paste_text, self)
error_dlg.finished.connect(self.finish)
error_dlg.finished.connect(self.finish) # type: ignore
error_dlg.show()
@pyqtSlot(str)
@ -415,8 +427,8 @@ class ExceptionCrashDialog(_CrashDialog):
self._chk_restore = QCheckBox("Restore open pages")
self._chk_restore.setChecked(True)
self._vbox.addWidget(self._chk_restore)
self._chk_log = QCheckBox("Include a debug log in the report",
checked=True)
self._chk_log = QCheckBox("Include a debug log in the report")
self._chk_log.setChecked(True)
try:
if config.val.content.private_browsing:
self._chk_log.setChecked(False)
@ -427,7 +439,8 @@ class ExceptionCrashDialog(_CrashDialog):
info_label = QLabel("<i>This makes it a lot easier to diagnose the "
"crash, but it might contain sensitive "
"information such as which pages you visited "
"or keyboard input.</i>", wordWrap=True)
"or keyboard input.</i>")
info_label.setWordWrap(True)
self._vbox.addWidget(info_label)
def _get_error_type(self):
@ -450,8 +463,10 @@ class ExceptionCrashDialog(_CrashDialog):
("Objects", self._qobjects),
]
try:
self._crash_info.append(
("Debug log", log.ram_handler.dump_log()))
text = "Log output was disabled."
if log.ram_handler is not None:
text = log.ram_handler.dump_log()
self._crash_info.append(("Debug log", text))
except Exception:
self._crash_info.append(("Debug log", traceback.format_exc()))
@ -508,8 +523,8 @@ class FatalCrashDialog(_CrashDialog):
"""Add checkboxes to the dialog."""
super()._init_checkboxes()
self._chk_history = QCheckBox("Include a history of the last "
"accessed pages in the report.",
checked=True)
"accessed pages in the report.")
self._chk_history.setChecked(True)
try:
if config.val.content.private_browsing:
self._chk_history.setChecked(False)
@ -607,8 +622,10 @@ class ReportErrorDialog(QDialog):
"crash@qutebrowser.org</a> - Thanks!".format(
html.escape(exc_text)))
vbox.addWidget(label)
txt = QTextEdit(readOnly=True, tabChangesFocus=True,
acceptRichText=False)
txt = QTextEdit()
txt.setReadOnly(True)
txt.setTabChangesFocus(True)
txt.setAcceptRichText(False)
txt.setText(text)
txt.selectAll()
vbox.addWidget(txt)

View File

@ -27,6 +27,7 @@ import pdb # noqa: T002
import signal
import functools
import faulthandler
import typing
try:
# WORKAROUND for segfaults when using pdb in pytest for some reason...
import readline # pylint: disable=unused-import
@ -36,6 +37,7 @@ except ImportError:
import attr
from PyQt5.QtCore import (pyqtSlot, qInstallMessageHandler, QObject,
QSocketNotifier, QTimer, QUrl)
from PyQt5.QtCore import pyqtSignal # pylint: disable=unused-import
from qutebrowser.api import cmdutils
from qutebrowser.misc import earlyinit, crashdialog, ipc, objects
@ -236,10 +238,11 @@ class CrashHandler(QObject):
self._quitter.quit_status['crash'] = False
info = self._get_exception_info()
try:
ipc.server.ignored = True
except Exception:
log.destroy.exception("Error while ignoring ipc")
if ipc.server is not None:
try:
ipc.server.ignored = True
except Exception:
log.destroy.exception("Error while ignoring ipc")
try:
self._app.lastWindowClosed.disconnect(
@ -295,7 +298,8 @@ class SignalHandler(QObject):
self._quitter = quitter
self._notifier = None
self._timer = usertypes.Timer(self, 'python_hacks')
self._orig_handlers = {}
self._orig_handlers = {
} # type: typing.Mapping[pyqtSignal, typing.Callable[..., None]]
self._activated = False
self._orig_wakeup_fd = None
@ -322,7 +326,8 @@ class SignalHandler(QObject):
fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
self._notifier = QSocketNotifier(read_fd, QSocketNotifier.Read,
self)
self._notifier.activated.connect(self.handle_signal_wakeup)
self._notifier.activated.connect( # type: ignore
self.handle_signal_wakeup)
self._orig_wakeup_fd = signal.set_wakeup_fd(write_fd)
# pylint: enable=import-error,no-member,useless-suppression
else:

View File

@ -141,7 +141,7 @@ def pyinstaller_qt_workaround():
hasattr(sys, '_MEIPASS') and
sys.platform == 'win32'):
# pylint: disable=no-member,protected-access
os.environ['PATH'] += os.pathsep + sys._MEIPASS
os.environ['PATH'] += os.pathsep + sys._MEIPASS # type: ignore
def check_pyqt():
@ -265,7 +265,7 @@ def configure_pyqt():
from qutebrowser.qt import sip
try:
# Added in sip 4.19.4
sip.enableoverflowchecking(True)
sip.enableoverflowchecking(True) # type: ignore
except AttributeError:
pass

View File

@ -19,6 +19,7 @@
"""An HTTP client based on QNetworkAccessManager."""
import typing
import functools
import urllib.request
import urllib.parse
@ -66,7 +67,7 @@ class HTTPClient(QObject):
def __init__(self, parent=None):
super().__init__(parent)
self._nam = QNetworkAccessManager(self)
self._timers = {}
self._timers = {} # type: typing.Mapping[QNetworkReply, QTimer]
def post(self, url, data=None):
"""Create a new POST request.

View File

@ -89,7 +89,10 @@ class KeyHintView(QLabel):
Args:
prefix: The current partial keystring.
"""
countstr, prefix = re.fullmatch(r'(\d*)(.*)', prefix).groups()
match = re.fullmatch(r'(\d*)(.*)', prefix)
assert match is not None, prefix
countstr, prefix = match.groups()
if not prefix:
self._show_timer.stop()
self.hide()

View File

@ -22,6 +22,7 @@
import os
import os.path
import contextlib
import typing
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
@ -149,7 +150,7 @@ class LineParser(BaseLineParser):
"""
super().__init__(configdir, fname, binary=binary, parent=parent)
if not os.path.isfile(self._configfile):
self.data = []
self.data = [] # type: typing.Sequence[str]
else:
log.init.debug("Reading {}".format(self._configfile))
self._read()

View File

@ -54,7 +54,7 @@ class MinimalLineEditMixin:
e.accept()
self.insert(text)
return
super().keyPressEvent(e)
super().keyPressEvent(e) # type: ignore
def __repr__(self):
return utils.get_repr(self)

View File

@ -60,7 +60,7 @@ def msgbox(parent, title, text, *, icon, buttons=QMessageBox.Ok,
box.setIcon(icon)
box.setStandardButtons(buttons)
if on_finished is not None:
box.finished.connect(on_finished)
box.finished.connect(on_finished) # type: ignore
if plain_text:
box.setTextFormat(Qt.PlainText)
elif plain_text is not None:

View File

@ -19,6 +19,8 @@
"""Bridge to provide readline-like shortcuts for QLineEdits."""
import typing
from PyQt5.QtWidgets import QApplication, QLineEdit
from qutebrowser.api import cmdutils
@ -34,13 +36,13 @@ class ReadlineBridge:
_deleted: Mapping from widgets to their last deleted text.
"""
def __init__(self):
self._deleted = {}
def __init__(self) -> None:
self._deleted = {} # type: typing.MutableMapping[QLineEdit, str]
def __repr__(self):
def __repr__(self) -> str:
return utils.get_repr(self)
def _widget(self):
def _widget(self) -> typing.Optional[QLineEdit]:
"""Get the currently active QLineEdit."""
w = QApplication.instance().focusWidget()
if isinstance(w, QLineEdit):
@ -50,7 +52,7 @@ class ReadlineBridge:
@cmdutils.register(instance='readline-bridge',
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_backward_char(self):
def rl_backward_char(self) -> None:
"""Move back a character.
This acts like readline's backward-char.
@ -62,7 +64,7 @@ class ReadlineBridge:
@cmdutils.register(instance='readline-bridge',
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_forward_char(self):
def rl_forward_char(self) -> None:
"""Move forward a character.
This acts like readline's forward-char.
@ -74,7 +76,7 @@ class ReadlineBridge:
@cmdutils.register(instance='readline-bridge',
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_backward_word(self):
def rl_backward_word(self) -> None:
"""Move back to the start of the current or previous word.
This acts like readline's backward-word.
@ -86,7 +88,7 @@ class ReadlineBridge:
@cmdutils.register(instance='readline-bridge',
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_forward_word(self):
def rl_forward_word(self) -> None:
"""Move forward to the end of the next word.
This acts like readline's forward-word.
@ -98,7 +100,7 @@ class ReadlineBridge:
@cmdutils.register(instance='readline-bridge',
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_beginning_of_line(self):
def rl_beginning_of_line(self) -> None:
"""Move to the start of the line.
This acts like readline's beginning-of-line.
@ -110,7 +112,7 @@ class ReadlineBridge:
@cmdutils.register(instance='readline-bridge',
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_end_of_line(self):
def rl_end_of_line(self) -> None:
"""Move to the end of the line.
This acts like readline's end-of-line.
@ -122,7 +124,7 @@ class ReadlineBridge:
@cmdutils.register(instance='readline-bridge',
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_unix_line_discard(self):
def rl_unix_line_discard(self) -> None:
"""Remove chars backward from the cursor to the beginning of the line.
This acts like readline's unix-line-discard.
@ -136,7 +138,7 @@ class ReadlineBridge:
@cmdutils.register(instance='readline-bridge',
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_kill_line(self):
def rl_kill_line(self) -> None:
"""Remove chars from the cursor to the end of the line.
This acts like readline's kill-line.
@ -148,7 +150,7 @@ class ReadlineBridge:
self._deleted[widget] = widget.selectedText()
widget.del_()
def _rubout(self, delim):
def _rubout(self, delim: typing.Iterable[str]) -> None:
"""Delete backwards using the characters in delim as boundaries."""
widget = self._widget()
if widget is None:
@ -175,7 +177,7 @@ class ReadlineBridge:
@cmdutils.register(instance='readline-bridge',
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_unix_word_rubout(self):
def rl_unix_word_rubout(self) -> None:
"""Remove chars from the cursor to the beginning of the word.
This acts like readline's unix-word-rubout. Whitespace is used as a
@ -185,7 +187,7 @@ class ReadlineBridge:
@cmdutils.register(instance='readline-bridge',
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_unix_filename_rubout(self):
def rl_unix_filename_rubout(self) -> None:
"""Remove chars from the cursor to the previous path separator.
This acts like readline's unix-filename-rubout.
@ -194,7 +196,7 @@ class ReadlineBridge:
@cmdutils.register(instance='readline-bridge',
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_backward_kill_word(self):
def rl_backward_kill_word(self) -> None:
"""Remove chars from the cursor to the beginning of the word.
This acts like readline's backward-kill-word. Any non-alphanumeric
@ -209,7 +211,7 @@ class ReadlineBridge:
@cmdutils.register(instance='readline-bridge',
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_kill_word(self):
def rl_kill_word(self) -> None:
"""Remove chars from the cursor to the end of the current word.
This acts like readline's kill-word.
@ -223,7 +225,7 @@ class ReadlineBridge:
@cmdutils.register(instance='readline-bridge',
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_yank(self):
def rl_yank(self) -> None:
"""Paste the most recently deleted text.
This acts like readline's yank.
@ -235,7 +237,7 @@ class ReadlineBridge:
@cmdutils.register(instance='readline-bridge',
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_delete_char(self):
def rl_delete_char(self) -> None:
"""Delete the character after the cursor.
This acts like readline's delete-char.
@ -247,7 +249,7 @@ class ReadlineBridge:
@cmdutils.register(instance='readline-bridge',
modes=[typ.KeyMode.command, typ.KeyMode.prompt])
def rl_backward_delete_char(self):
def rl_backward_delete_char(self) -> None:
"""Delete the character before the cursor.
This acts like readline's backward-delete-char.

View File

@ -21,6 +21,7 @@
import os.path
import collections
import typing
from PyQt5.QtCore import pyqtSlot, QObject, QTimer
@ -110,7 +111,8 @@ class SaveManager(QObject):
def __init__(self, parent=None):
super().__init__(parent)
self.saveables = collections.OrderedDict()
self.saveables = collections.OrderedDict(
) # type: typing.MutableMapping[str, Saveable]
self._save_timer = usertypes.Timer(self, name='save-timer')
self._save_timer.timeout.connect(self.autosave)
self._set_autosave_interval()

View File

@ -38,6 +38,9 @@ from qutebrowser.mainwindow import mainwindow
from qutebrowser.qt import sip
_JsonType = typing.MutableMapping[str, typing.Any]
class Sentinel:
"""Sentinel value for default argument."""
@ -169,7 +172,7 @@ class SessionManager(QObject):
"""
data = {
'url': bytes(item.url().toEncoded()).decode('ascii'),
}
} # type: _JsonType
if item.title():
data['title'] = item.title()
@ -215,7 +218,7 @@ class SessionManager(QObject):
tab: The WebView to save.
active: Whether the tab is currently active.
"""
data = {'history': []}
data = {'history': []} # type: _JsonType
if active:
data['active'] = True
for idx, item in enumerate(tab.history):
@ -232,9 +235,9 @@ class SessionManager(QObject):
def _save_all(self, *, only_window=None, with_private=False):
"""Get a dict with data for all windows/tabs."""
data = {'windows': []}
data = {'windows': []} # type: _JsonType
if only_window is not None:
winlist = [only_window]
winlist = [only_window] # type: typing.Iterable[int]
else:
winlist = objreg.window_registry
@ -251,7 +254,7 @@ class SessionManager(QObject):
if tabbed_browser.is_private and not with_private:
continue
win_data = {}
win_data = {} # type: _JsonType
active_window = QApplication.instance().activeWindow()
if getattr(active_window, 'win_id', None) == win_id:
win_data['active'] = True
@ -309,10 +312,10 @@ class SessionManager(QObject):
else:
data = self._save_all(only_window=only_window,
with_private=with_private)
log.sessions.vdebug("Saving data: {}".format(data))
log.sessions.vdebug("Saving data: {}".format(data)) # type: ignore
try:
with qtutils.savefile_open(path) as f:
utils.yaml_dump(data, f)
utils.yaml_dump(data, f) # type: ignore
except (OSError, UnicodeEncodeError, yaml.YAMLError) as e:
raise SessionError(e)
@ -345,7 +348,7 @@ class SessionManager(QObject):
def _load_tab(self, new_tab, data):
"""Load yaml data into a newly opened tab."""
entries = []
lazy_load = []
lazy_load = [] # type: typing.MutableSequence[_JsonType]
# use len(data['history'])
# -> dropwhile empty if not session.lazy_session
lazy_index = len(data['history'])

View File

@ -139,7 +139,7 @@ def split(s, keep=False):
out = []
spaces = ""
log.shlexer.vdebug("{!r} -> {!r}".format(s, tokens))
log.shlexer.vdebug("{!r} -> {!r}".format(s, tokens)) # type: ignore
for t in tokens:
if t.isspace():

View File

@ -188,7 +188,7 @@ class Query:
raise BugError("Cannot iterate inactive query")
rec = self.query.record()
fields = [rec.fieldName(i) for i in range(rec.count())]
rowtype = collections.namedtuple('ResultRow', fields)
rowtype = collections.namedtuple('ResultRow', fields) # type: ignore
while self.query.next():
rec = self.query.record()