enable type checking of aqt/forms, and fix the new typing issues

Referencing an invalid translation should now break the build
This commit is contained in:
Damien Elmes 2021-03-26 16:06:02 +10:00
parent 3079eaa460
commit 5a094e78fa
12 changed files with 83 additions and 40 deletions

View file

@ -381,7 +381,11 @@ class DataModel(QAbstractTableModel):
if count < 500:
# discard large selections; they're too slow
sm.select(
items, QItemSelectionModel.SelectCurrent | QItemSelectionModel.Rows
items,
cast(
QItemSelectionModel.SelectionFlags,
QItemSelectionModel.SelectCurrent | QItemSelectionModel.Rows,
),
)
else:
tv.selectRow(0)
@ -1361,7 +1365,13 @@ where id in %s"""
sm = self.form.tableView.selectionModel()
items = sm.selection()
self.form.tableView.selectAll()
sm.select(items, QItemSelectionModel.Deselect | QItemSelectionModel.Rows)
sm.select(
items,
cast(
QItemSelectionModel.SelectionFlags,
QItemSelectionModel.Deselect | QItemSelectionModel.Rows,
),
)
# Hooks
######################################################################
@ -1432,10 +1442,10 @@ where id in %s"""
)
frm.fields.addItems(fields)
restore_combo_index_for_session(frm.fields, fields, "findDupesFields")
self._dupesButton = None
self._dupesButton: Optional[QPushButton] = None
# links
frm.webView.title = "find duplicates"
frm.webView.set_title("find duplicates")
web_context = FindDupesDialog(dialog=d, browser=self)
frm.webView.set_bridge_command(self.dupeLinkClicked, web_context)
frm.webView.stdHtml("", context=web_context)
@ -1522,17 +1532,22 @@ where id in %s"""
# Jumping
######################################################################
def _moveCur(self, dir: int, idx: QModelIndex = None) -> None:
def _moveCur(
self, dir: Optional[QTableView.CursorAction], idx: QModelIndex = None
) -> None:
if not self.model.cards:
return
tv = self.form.tableView
if idx is None:
if dir is not None:
idx = tv.moveCursor(dir, self.mw.app.keyboardModifiers())
tv.selectionModel().setCurrentIndex(
idx,
QItemSelectionModel.Clear
| QItemSelectionModel.Select
| QItemSelectionModel.Rows,
cast(
QItemSelectionModel.SelectionFlags,
QItemSelectionModel.Clear
| QItemSelectionModel.Select
| QItemSelectionModel.Rows,
),
)
def onPreviousCard(self) -> None:
@ -1557,7 +1572,13 @@ where id in %s"""
return
idx2 = sm.currentIndex()
item = QItemSelection(idx2, idx)
sm.select(item, QItemSelectionModel.SelectCurrent | QItemSelectionModel.Rows)
sm.select(
item,
cast(
QItemSelectionModel.SelectionFlags,
QItemSelectionModel.SelectCurrent | QItemSelectionModel.Rows,
),
)
def onLastCard(self) -> None:
sm = self.form.tableView.selectionModel()
@ -1567,7 +1588,13 @@ where id in %s"""
return
idx2 = sm.currentIndex()
item = QItemSelection(idx, idx2)
sm.select(item, QItemSelectionModel.SelectCurrent | QItemSelectionModel.Rows)
sm.select(
item,
cast(
QItemSelectionModel.SelectionFlags,
QItemSelectionModel.SelectCurrent | QItemSelectionModel.Rows,
),
)
def onFind(self) -> None:
# workaround for PyQt focus bug

View file

@ -43,7 +43,7 @@ class EmptyCardsDialog(QDialog):
self.setWindowTitle(tr.empty_cards_window_title())
disable_help_button(self)
self.form.keep_notes.setText(tr.empty_cards_preserve_notes_checkbox())
self.form.webview.title = "empty cards"
self.form.webview.set_title("empty cards")
self.form.webview.set_bridge_command(self._on_note_link_clicked, self)
gui_hooks.empty_cards_will_show(self)
@ -66,7 +66,7 @@ class EmptyCardsDialog(QDialog):
tr.empty_cards_delete_button(), QDialogButtonBox.ActionRole
)
self._delete_button.setAutoDefault(False)
self._delete_button.clicked.connect(self._on_delete)
qconnect(self._delete_button.clicked, self._on_delete)
def _on_note_link_clicked(self, link: str) -> None:
aqt.dialogs.open("Browser", self.mw, search=(link,))

View file

@ -49,7 +49,7 @@ class FieldDialog(QDialog):
self.fillFields()
self.setupSignals()
self.form.fieldList.setDragDropMode(QAbstractItemView.InternalMove)
self.form.fieldList.dropEvent = self.onDrop
self.form.fieldList.dropEvent = self.onDrop # type: ignore[assignment]
self.form.fieldList.setCurrentRow(0)
self.exec_()

View file

@ -273,7 +273,7 @@ class FilteredDeckConfigDialog(QDialog):
FilteredDeckConfig.SearchTerm(
search=form.search.text(),
limit=form.limit.value(),
order=form.order.currentIndex(),
order=form.order.currentIndex(), # type: ignore[arg-type]
)
]
@ -282,7 +282,7 @@ class FilteredDeckConfigDialog(QDialog):
FilteredDeckConfig.SearchTerm(
search=form.search_2.text(),
limit=form.limit_2.value(),
order=form.order_2.currentIndex(),
order=form.order_2.currentIndex(), # type: ignore[arg-type]
)
)

View file

@ -111,11 +111,11 @@ class FindAndReplaceDialog(QDialog):
self._find_history = restore_combo_history(
self.form.find, self.COMBO_NAME + "Find"
)
self.form.find.completer().setCaseSensitivity(True)
self.form.find.completer().setCaseSensitivity(Qt.CaseSensitive)
self._replace_history = restore_combo_history(
self.form.replace, self.COMBO_NAME + "Replace"
)
self.form.replace.completer().setCaseSensitivity(True)
self.form.replace.completer().setCaseSensitivity(Qt.CaseSensitive)
restore_is_checked(self.form.re, self.COMBO_NAME + "Regex")
restore_is_checked(self.form.ignoreCase, self.COMBO_NAME + "ignoreCase")

View file

@ -16,5 +16,15 @@ outdata = re.sub(
r'(?:QtGui\.QApplication\.)?_?translate\(".*?", "(.*?)"', "tr.\\1(", outdata
)
outlines = []
qt_bad_types = [".connect(", "setStandardButtons", "setTextInteractionFlags", "setAlignment"]
for line in outdata.splitlines():
for substr in qt_bad_types:
if substr in line:
line = line + " # type: ignore"
break
outlines.append(line)
with open(py_file, "w") as file:
file.write(outdata)
file.write("\n".join(outlines))

View file

@ -1622,22 +1622,24 @@ title="%s" %s>%s</button>""" % (
s = self.debugDiagShort = QShortcut(QKeySequence("ctrl+shift+l"), d)
qconnect(s.activated, frm.text.clear)
def addContextMenu(ev: QCloseEvent, name: str) -> None:
def addContextMenu(
ev: Union[QCloseEvent, QContextMenuEvent], name: str
) -> None:
ev.accept()
menu = frm.log.createStandardContextMenu(QCursor.pos())
menu.addSeparator()
if name == "log":
a = menu.addAction("Clear Log")
a.setShortcuts(QKeySequence("ctrl+l"))
a.setShortcut(QKeySequence("ctrl+l"))
qconnect(a.triggered, frm.log.clear)
elif name == "text":
a = menu.addAction("Clear Code")
a.setShortcuts(QKeySequence("ctrl+shift+l"))
a.setShortcut(QKeySequence("ctrl+shift+l"))
qconnect(a.triggered, frm.text.clear)
menu.exec_(QCursor.pos())
frm.log.contextMenuEvent = lambda ev: addContextMenu(ev, "log")
frm.text.contextMenuEvent = lambda ev: addContextMenu(ev, "text")
frm.log.contextMenuEvent = lambda ev: addContextMenu(ev, "log") # type: ignore[assignment]
frm.text.contextMenuEvent = lambda ev: addContextMenu(ev, "text") # type: ignore[assignment]
gui_hooks.debug_console_will_show(d)
d.show()

View file

@ -3,10 +3,10 @@
from concurrent.futures import Future
from operator import itemgetter
from typing import Any, List, Optional, Sequence
from typing import List, Optional, Sequence
import aqt.clayout
from anki import stdmodels
from anki import Collection, stdmodels
from anki.lang import without_unicode_isolation
from anki.models import NoteType, NoteTypeID, NoteTypeNameIDUseCount
from anki.notes import Note
@ -133,7 +133,7 @@ class Models(QDialog):
def current_notetype(self) -> NoteType:
row = self.form.modelsList.currentRow()
return self.mm.get(self.models[row].id)
return self.mm.get(NoteTypeID(self.models[row].id))
def onAdd(self) -> None:
m = AddModel(self.mw, self).get()
@ -229,16 +229,16 @@ class AddModel(QDialog):
self.dialog.setupUi(self)
disable_help_button(self)
# standard models
self.models = []
self.notetypes: List[Union[NoteType, Callable[[Collection], NoteType]]] = []
for (name, func) in stdmodels.get_stock_notetypes(self.col):
item = QListWidgetItem(tr.notetypes_add(val=name))
self.dialog.models.addItem(item)
self.models.append((True, func))
self.notetypes.append(func)
# add copies
for m in sorted(self.col.models.all(), key=itemgetter("name")):
item = QListWidgetItem(tr.notetypes_clone(val=m["name"]))
self.dialog.models.addItem(item)
self.models.append((False, m)) # type: ignore
self.notetypes.append(m)
self.dialog.models.setCurrentRow(0)
# the list widget will swallow the enter key
s = QShortcut(QKeySequence("Return"), self)
@ -246,7 +246,7 @@ class AddModel(QDialog):
# help
qconnect(self.dialog.buttonBox.helpRequested, self.onHelp)
def get(self) -> Any:
def get(self) -> Optional[NoteType]:
self.exec_()
return self.model
@ -254,14 +254,14 @@ class AddModel(QDialog):
QDialog.reject(self)
def accept(self) -> None:
(isStd, model) = self.models[self.dialog.models.currentRow()]
if isStd:
# create
self.model = model(self.col)
else:
model = self.notetypes[self.dialog.models.currentRow()]
if isinstance(model, dict):
# add copy to deck
self.model = self.mw.col.models.copy(model)
self.mw.col.models.setCurrent(self.model)
else:
# create
self.model = model(self.col)
QDialog.accept(self)
def onHelp(self) -> None:

View file

@ -1,6 +1,8 @@
# Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from typing import Any, cast
import anki.lang
import aqt
from anki.consts import newCardSchedulingLabels
@ -82,7 +84,7 @@ class Preferences(QDialog):
form = self.form
scheduling = self.prefs.scheduling
scheduling.new_review_mix = form.newSpread.currentIndex()
scheduling.new_review_mix = cast(Any, form.newSpread.currentIndex())
scheduling.learn_ahead_secs = form.lrnCutoff.value() * 60
scheduling.day_learn_first = form.dayLearnFirst.isChecked()
scheduling.rollover = form.dayOffset.value()

View file

@ -182,7 +182,7 @@ class DeckStats(QDialog):
stats = self.mw.col.stats()
stats.wholeCollection = self.wholeCollection
self.report = stats.report(type=self.period)
self.form.web.title = "deck stats"
self.form.web.set_title("deck stats")
self.form.web.stdHtml(
f"<html><body>{self.report}</body></html>",
js=["js/vendor/jquery.min.js", "js/vendor/plot.js"],

View file

@ -213,7 +213,7 @@ class AnkiWebView(QWebEngineView):
self, parent: Optional[QWidget] = None, title: str = "default"
) -> None:
QWebEngineView.__init__(self, parent=parent)
self.title = title # type: ignore
self.set_title(title)
self._page = AnkiWebPage(self._onBridgeCmd)
self._page.setBackgroundColor(self._getWindowColor()) # reduce flicker
@ -252,6 +252,9 @@ class AnkiWebView(QWebEngineView):
activated=self.onPaste,
)
def set_title(self, title: str) -> None:
self.title = title # type: ignore[assignment]
def eventFilter(self, obj: QObject, evt: QEvent) -> bool:
# disable pinch to zoom gesture
if isinstance(evt, QNativeGestureEvent):

View file

@ -72,7 +72,6 @@ ignore_missing_imports = True
ignore_missing_imports = True
[mypy-aqt.forms.*]
check_untyped_defs=false
disallow_untyped_defs=false
[mypy-anki.*]
disallow_untyped_defs=false