add remaining types and disable missing types on (almost) all aqt

This commit is contained in:
Damien Elmes 2021-02-03 00:00:29 +10:00
parent 6426edb0ac
commit 4a5ef69068
23 changed files with 97 additions and 89 deletions

View file

@ -21,12 +21,12 @@ class ClosableQDialog(QDialog):
aqt.dialogs.markClosed("About")
QDialog.accept(self)
def closeWithCallback(self, callback) -> None:
def closeWithCallback(self, callback: Callable[[], None]) -> None:
self.reject()
callback()
def show(mw) -> QDialog:
def show(mw: aqt.AnkiQt) -> QDialog:
dialog = ClosableQDialog(mw)
disable_help_button(dialog)
mw.setupDialogGC(dialog)

View file

@ -1,7 +1,7 @@
# Copyright: Ankitects Pty Ltd and contributors
# -*- coding: utf-8 -*-
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from typing import Callable, List, Optional
from typing import Any, Callable, List, Optional
import aqt.deckchooser
import aqt.editor
@ -48,7 +48,7 @@ class AddCards(QDialog):
self.setupButtons()
self.onReset()
self.history: List[int] = []
self.previousNote = None
self.previousNote: Optional[Note] = None
restoreGeom(self, "add")
gui_hooks.state_did_reset.append(self.onReset)
gui_hooks.current_note_type_did_change.append(self.onModelChange)
@ -102,7 +102,7 @@ class AddCards(QDialog):
def show_notetype_selector(self) -> None:
self.editor.saveNow(self.modelChooser.onModelChange)
def onModelChange(self, unused=None) -> None:
def onModelChange(self, unused: Any = None) -> None:
oldNote = self.editor.note
note = self.mw.col.newNote()
self.previousNote = None
@ -161,10 +161,10 @@ class AddCards(QDialog):
gui_hooks.add_cards_will_show_history_menu(self, m)
m.exec_(self.historyButton.mapToGlobal(QPoint(0, 0)))
def editHistory(self, nid) -> None:
def editHistory(self, nid: int) -> None:
aqt.dialogs.open("Browser", self.mw, search=(SearchTerm(nid=nid),))
def addNote(self, note) -> Optional[Note]:
def addNote(self, note: Note) -> Optional[Note]:
note.model()["did"] = self.deckChooser.selectedId()
ret = note.dupeOrEmpty()
problem = None
@ -234,7 +234,7 @@ class AddCards(QDialog):
self.editor.saveNow(afterSave)
def closeWithCallback(self, cb) -> None:
def closeWithCallback(self, cb: Callable[[], None]) -> None:
def doClose() -> None:
self._reject()
cb()

View file

@ -194,7 +194,7 @@ class AddonManager:
def all_addon_meta(self) -> Iterable[AddonMeta]:
return map(self.addon_meta, self.allAddons())
def addonsFolder(self, dir=None) -> str:
def addonsFolder(self, dir: Optional[str] = None) -> str:
root = self.mw.pm.addonFolder()
if not dir:
return root
@ -677,8 +677,7 @@ class AddonManager:
addon = self.addonFromModule(module)
self._webExports[addon] = pattern
# CHECK
def getWebExports(self, addon) -> str:
def getWebExports(self, addon: str) -> str:
return self._webExports.get(addon)
@ -908,7 +907,7 @@ class AddonsDialog(QDialog):
class GetAddons(QDialog):
def __init__(self, dlg) -> None:
def __init__(self, dlg: QDialog) -> None:
QDialog.__init__(self, dlg)
self.addonsDlg = dlg
self.mgr = dlg.mgr
@ -1061,7 +1060,7 @@ class DownloaderInstaller(QObject):
self.client = client
qconnect(self.progressSignal, self._progress_callback)
def bg_thread_progress(up, down) -> None:
def bg_thread_progress(up: int, down: int) -> None:
self.progressSignal.emit(up, down) # type: ignore
self.client.progress_hook = bg_thread_progress
@ -1276,7 +1275,7 @@ def prompt_to_update(
class ConfigEditor(QDialog):
def __init__(self, dlg, addon, conf) -> None:
def __init__(self, dlg: QDialog, addon: str, conf: Dict) -> None:
super().__init__(dlg)
self.addon = addon
self.conf = conf

View file

@ -585,7 +585,7 @@ class CardLayout(QDialog):
self.mw.taskman.with_progress(get_count, on_done)
def onRemoveInner(self, template) -> None:
def onRemoveInner(self, template: Dict) -> None:
self.mm.remove_template(self.model, template)
# ensure current ordinal is within bounds
@ -661,7 +661,7 @@ class CardLayout(QDialog):
self._flipQA(old, old)
self.redraw_everything()
def _flipQA(self, src, dst) -> None:
def _flipQA(self, src: Dict, dst: Dict) -> None:
m = re.match("(?s)(.+)<hr id=answer>(.+)", src["afmt"])
if not m:
showInfo(tr(TR.CARD_TEMPLATES_ANKI_COULDNT_FIND_THE_LINE_BETWEEN))
@ -781,7 +781,7 @@ class CardLayout(QDialog):
form.size.value(),
)
def _addField(self, field, font, size) -> None:
def _addField(self, field: str, font: str, size: int) -> None:
text = self.tform.edit_area.toPlainText()
text += "\n<div style='font-family: %s; font-size: %spx;'>{{%s}}</div>\n" % (
font,

View file

@ -90,8 +90,8 @@ class DeckBrowser:
self._collapse(int(arg))
return False
def _selDeck(self, did) -> None:
self.mw.col.decks.select(did)
def _selDeck(self, did: str) -> None:
self.mw.col.decks.select(int(did))
self.mw.onOverview()
# HTML generation
@ -108,14 +108,14 @@ class DeckBrowser:
</center>
"""
def _renderPage(self, reuse=False) -> None:
def _renderPage(self, reuse: bool = False) -> None:
if not reuse:
self._dueTree = self.mw.col.sched.deck_due_tree()
self.__renderPage(None)
return
self.web.evalWithCallback("window.pageYOffset", self.__renderPage)
def __renderPage(self, offset) -> None:
def __renderPage(self, offset: int) -> None:
content = DeckBrowserContent(
tree=self._renderDeckTree(self._dueTree),
stats=self._renderStats(),
@ -137,7 +137,7 @@ class DeckBrowser:
self._scrollToOffset(offset)
gui_hooks.deck_browser_did_render(self)
def _scrollToOffset(self, offset) -> None:
def _scrollToOffset(self, offset: int) -> None:
self.web.eval("$(function() { window.scrollTo(0, %d, 'instant'); });" % offset)
def _renderStats(self) -> str:
@ -260,10 +260,10 @@ class DeckBrowser:
return
self.show()
def _options(self, did) -> None:
def _options(self, did: str) -> None:
# select the deck first, because the dyn deck conf assumes the deck
# we're editing is the current one
self.mw.col.decks.select(did)
self.mw.col.decks.select(int(did))
self.mw.onDeckConf()
def _collapse(self, did: int) -> None:

View file

@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from operator import itemgetter
from typing import Any, Dict, Optional
from typing import Any, Dict, List, Optional
from PyQt5.QtWidgets import QLineEdit
@ -107,7 +107,7 @@ class DeckConf(QDialog):
a.setEnabled(False)
m.exec_(QCursor.pos())
def onConfChange(self, idx) -> None:
def onConfChange(self, idx: int) -> None:
if self.ignoreConfChange:
return
if self.conf:
@ -174,7 +174,7 @@ class DeckConf(QDialog):
# Loading
##################################################
def listToUser(self, l) -> str:
def listToUser(self, l: List[Union[int, float]]) -> str:
def num_to_user(n: Union[int, float]) -> str:
if n == round(n):
return str(int(n))
@ -183,7 +183,7 @@ class DeckConf(QDialog):
return " ".join(map(num_to_user, l))
def parentLimText(self, type="new") -> str:
def parentLimText(self, type: str = "new") -> str:
# top level?
if "::" not in self.deck["name"]:
return ""
@ -248,7 +248,7 @@ class DeckConf(QDialog):
# New order
##################################################
def onNewOrderChanged(self, new) -> None:
def onNewOrderChanged(self, new: bool) -> None:
old = self.conf["new"]["order"]
if old == new:
return

View file

@ -9,7 +9,7 @@ from aqt.utils import TR, disable_help_button, restoreGeom, saveGeom, tooltip, t
class EditCurrent(QDialog):
def __init__(self, mw) -> None:
def __init__(self, mw: aqt.AnkiQt) -> None:
QDialog.__init__(self, None, Qt.Window)
mw.setupDialogGC(self)
self.mw = mw
@ -48,7 +48,7 @@ class EditCurrent(QDialog):
return
self.editor.setNote(n)
def reopen(self, mw) -> None:
def reopen(self, mw: aqt.AnkiQt) -> None:
tooltip("Please finish editing the existing card first.")
self.onReset()
@ -74,7 +74,7 @@ class EditCurrent(QDialog):
aqt.dialogs.markClosed("EditCurrent")
QDialog.reject(self)
def closeWithCallback(self, onsuccess) -> None:
def closeWithCallback(self, onsuccess: Callable[[], None]) -> None:
def callback() -> None:
self._saveAndClose()
onsuccess()

View file

@ -5,6 +5,7 @@ from __future__ import annotations
import re
from concurrent.futures import Future
from typing import Any
import aqt
from anki.collection import EmptyCardsReport, NoteWithEmptyCards
@ -55,7 +56,7 @@ class EmptyCardsDialog(QDialog):
style = "<style>.allempty { color: red; }</style>"
self.form.webview.stdHtml(style + html, context=self)
def on_finished(code) -> None:
def on_finished(code: Any) -> None:
saveGeom(self, "emptycards")
qconnect(self.finished, on_finished)
@ -66,7 +67,7 @@ class EmptyCardsDialog(QDialog):
self._delete_button.setAutoDefault(False)
self._delete_button.clicked.connect(self._on_delete)
def _on_note_link_clicked(self, link) -> None:
def _on_note_link_clicked(self, link: str) -> None:
aqt.dialogs.open("Browser", self.mw, search=(link,))
def _on_delete(self) -> None:

View file

@ -16,7 +16,7 @@ from aqt.utils import TR, showText, showWarning, supportText, tr
if not os.environ.get("DEBUG"):
def excepthook(etype, val, tb) -> None:
def excepthook(etype, val, tb) -> None: # type: ignore
sys.stderr.write(
"Caught exception:\n%s\n"
% ("".join(traceback.format_exception(etype, val, tb)))

View file

@ -155,7 +155,7 @@ class ExportDialog(QDialog):
os.unlink(file)
# progress handler
def exported_media(cnt) -> None:
def exported_media(cnt: int) -> None:
self.mw.taskman.run_on_main(
lambda: self.mw.progress.update(
label=tr(TR.EXPORTING_EXPORTED_MEDIA_FILE, count=cnt)

View file

@ -25,7 +25,9 @@ from aqt.utils import (
class FieldDialog(QDialog):
def __init__(self, mw: AnkiQt, nt: NoteType, parent=None) -> None:
def __init__(
self, mw: AnkiQt, nt: NoteType, parent: Optional[QDialog] = None
) -> None:
QDialog.__init__(self, parent or mw)
self.mw = mw
self.col = self.mw.col
@ -70,7 +72,7 @@ class FieldDialog(QDialog):
qconnect(f.sortField.clicked, self.onSortField)
qconnect(f.buttonBox.helpRequested, self.onHelp)
def onDrop(self, ev) -> None:
def onDrop(self, ev: QDropEvent) -> None:
fieldList = self.form.fieldList
indicatorPos = fieldList.dropIndicatorPosition()
dropPos = fieldList.indexAt(ev.pos()).row()
@ -160,7 +162,7 @@ class FieldDialog(QDialog):
self.fillFields()
self.form.fieldList.setCurrentRow(0)
def onPosition(self, delta=-1) -> None:
def onPosition(self, delta: int = -1) -> None:
idx = self.currentIdx
l = len(self.model["flds"])
txt = getOnlyText(tr(TR.FIELDS_NEW_POSITION_1, val=l), default=str(idx + 1))
@ -181,7 +183,7 @@ class FieldDialog(QDialog):
self.form.sortField.setChecked(True)
self.mm.set_sort_index(self.model, self.form.fieldList.currentRow())
def moveField(self, pos) -> None:
def moveField(self, pos: int) -> None:
if not self.change_tracker.mark_schema():
return
self.saveField()

View file

@ -9,7 +9,7 @@ import traceback
import unicodedata
import zipfile
from concurrent.futures import Future
from typing import Any, Optional
from typing import Any, Dict, Optional
import anki.importing as importing
import aqt.deckchooser
@ -35,7 +35,7 @@ from aqt.utils import (
class ChangeMap(QDialog):
def __init__(self, mw: AnkiQt, model, current) -> None:
def __init__(self, mw: AnkiQt, model: Dict, current: str) -> None:
QDialog.__init__(self, mw, Qt.Window)
self.mw = mw
self.model = model
@ -79,8 +79,11 @@ class ChangeMap(QDialog):
# called by importFile() when importing a mappable file like .csv
# ImportType = Union[Importer,AnkiPackageImporter, TextImporter]
class ImportDialog(QDialog):
def __init__(self, mw: AnkiQt, importer) -> None:
def __init__(self, mw: AnkiQt, importer: Any) -> None:
QDialog.__init__(self, mw, Qt.Window)
self.mw = mw
self.importer = importer
@ -258,7 +261,7 @@ class ImportDialog(QDialog):
self.grid.addWidget(button, num, 2)
qconnect(button.clicked, lambda _, s=self, n=num: s.changeMappingNum(n))
def changeMappingNum(self, n) -> None:
def changeMappingNum(self, n: int) -> None:
f = ChangeMap(self.mw, self.importer.model, self.mapping[n]).getField()
try:
# make sure we don't have it twice
@ -286,7 +289,7 @@ class ImportDialog(QDialog):
def helpRequested(self) -> None:
openHelp(HelpPage.IMPORTING)
def importModeChanged(self, newImportMode) -> None:
def importModeChanged(self, newImportMode: int) -> None:
if newImportMode == 0:
self.frm.tagModified.setEnabled(True)
else:
@ -430,11 +433,11 @@ def setupApkgImport(mw: AnkiQt, importer: AnkiPackageImporter) -> bool:
return False
def replaceWithApkg(mw, file, backup) -> None:
def replaceWithApkg(mw: aqt.AnkiQt, file: str, backup: bool) -> None:
mw.unloadCollection(lambda: _replaceWithApkg(mw, file, backup))
def _replaceWithApkg(mw, filename, backup) -> None:
def _replaceWithApkg(mw: aqt.AnkiQt, filename: str, backup: bool) -> None:
mw.progress.start(immediate=True)
def do_import() -> None:
@ -457,7 +460,7 @@ def _replaceWithApkg(mw, filename, backup) -> None:
json.loads(z.read("media").decode("utf8")).items()
):
mw.taskman.run_on_main(
lambda n=n: mw.progress.update(
lambda n=n: mw.progress.update( # type: ignore
tr(TR.IMPORTING_PROCESSED_MEDIA_FILE, count=n)
)
)

View file

@ -16,17 +16,17 @@ from aqt.theme import theme_manager
##########################################################################
def bodyClass(col, card) -> str:
def bodyClass(col, card) -> str: # type: ignore
print("bodyClass() deprecated")
return theme_manager.body_classes_for_card_ord(card.ord)
def allSounds(text) -> List:
def allSounds(text) -> List: # type: ignore
print("allSounds() deprecated")
return aqt.mw.col.media._extract_filenames(text)
def stripSounds(text) -> str:
def stripSounds(text) -> str: # type: ignore
print("stripSounds() deprecated")
return aqt.mw.col.media.strip_av_tags(text)

View file

@ -349,7 +349,7 @@ class AnkiQt(QMainWindow):
dir=self.pm.backupFolder(),
)
def _openBackup(self, path) -> None:
def _openBackup(self, path: str) -> None:
try:
# move the existing collection to the trash, as it may not open
self.pm.trashCollection()

View file

@ -66,6 +66,7 @@ class MediaChecker:
return
assert isinstance(progress.val, str)
val = progress.val
try:
if self.progress_dialog.wantCancel:
@ -74,7 +75,7 @@ class MediaChecker:
# dialog may not be active
pass
self.mw.taskman.run_on_main(lambda: self.mw.progress.update(progress.val))
self.mw.taskman.run_on_main(lambda: self.mw.progress.update(val))
def _check(self) -> CheckMediaOut:
"Run the check on a background thread."

View file

@ -53,8 +53,8 @@ class MediaServer(threading.Thread):
_ready = threading.Event()
daemon = True
def __init__(self, mw: aqt.main.AnkiQt, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
def __init__(self, mw: aqt.main.AnkiQt) -> None:
super().__init__()
self.is_shutdown = False
def run(self) -> None:
@ -98,7 +98,7 @@ class MediaServer(threading.Thread):
@app.route("/<path:pathin>", methods=["GET", "POST"])
def allroutes(pathin) -> Response:
def allroutes(pathin: str) -> Response:
try:
directory, path = _redirectWebExports(pathin)
except TypeError:
@ -172,7 +172,7 @@ def allroutes(pathin) -> Response:
)
def _redirectWebExports(path) -> Tuple[str, str]:
def _redirectWebExports(path: str) -> Tuple[str, str]:
# catch /_anki references and rewrite them to web export folder
targetPath = "_anki/"
if path.startswith(targetPath):

View file

@ -6,7 +6,7 @@ from __future__ import annotations
import time
from concurrent.futures import Future
from dataclasses import dataclass
from typing import Callable, List, Optional, Union
from typing import Any, Callable, List, Optional, Union
import aqt
from anki.collection import MediaSyncProgress, ProgressKind
@ -185,11 +185,13 @@ class MediaSyncDialog(QDialog):
aqt.dialogs.markClosed("sync_log")
QDialog.reject(self)
def reopen(self, mw, syncer, close_when_done: bool = False) -> None:
def reopen(
self, mw: aqt.AnkiQt, syncer: Any, close_when_done: bool = False
) -> None:
self._close_when_done = close_when_done
self.show()
def _on_abort(self, *args) -> None:
def _on_abort(self, *_args: Any) -> None:
self._syncer.abort()
self.abort_button.setHidden(True)

View file

@ -31,8 +31,8 @@ class Models(QDialog):
def __init__(
self,
mw: AnkiQt,
parent=None,
fromMain=False,
parent: Optional[QDialog] = None,
fromMain: bool = False,
selected_notetype_id: Optional[int] = None,
):
self.mw = mw

View file

@ -92,7 +92,7 @@ class Preferences(QDialog):
except:
return codes.index("en_US")
def onLangIdxChanged(self, idx) -> None:
def onLangIdxChanged(self, idx: int) -> None:
code = anki.lang.langs[idx][1]
self.mw.pm.setLang(code)
showInfo(
@ -176,7 +176,7 @@ class Preferences(QDialog):
# Scheduler version
######################################################################
def _updateSchedVer(self, wantNew) -> None:
def _updateSchedVer(self, wantNew: bool) -> None:
haveNew = self.mw.col.schedVer() == 2
# nothing to do?

View file

@ -269,7 +269,7 @@ class ProfileManager:
fn = super().find_class(module, name)
if module == "sip" and name == "_unpickle_type":
def wrapper(mod, obj, args) -> Any:
def wrapper(mod, obj, args) -> Any: # type: ignore
if mod.startswith("PyQt4") and obj == "QByteArray":
# can't trust str objects from python 2
return QByteArray()

View file

@ -71,7 +71,12 @@ class ProgressManager:
##########################################################################
def start(
self, max=0, min=0, label=None, parent=None, immediate=False
self,
max: int = 0,
min: int = 0,
label: Optional[str] = None,
parent: Optional[QDialog] = None,
immediate: bool = False,
) -> Optional[ProgressDialog]:
self._levels += 1
if self._levels > 1:
@ -106,10 +111,10 @@ class ProgressManager:
def update(
self,
label=None,
value=None,
process=True,
maybeShow=True,
label: Optional[str] = None,
value: Optional[int] = None,
process: bool = True,
maybeShow: bool = True,
max: Optional[int] = None,
) -> None:
# print self._min, self._counter, self._max, label, time.time() - self._lastTime
@ -225,14 +230,14 @@ class ProgressDialog(QDialog):
self._closingDown = True
self.hide()
def closeEvent(self, evt) -> None:
def closeEvent(self, evt: QCloseEvent) -> None:
if self._closingDown:
evt.accept()
else:
self.wantCancel = True
evt.ignore()
def keyPressEvent(self, evt) -> None:
def keyPressEvent(self, evt: QKeyEvent) -> None:
if evt.key() == Qt.Key_Escape:
evt.ignore()
self.wantCancel = True

View file

@ -8,7 +8,7 @@ import html
import json
import re
import unicodedata as ucd
from typing import Any, Callable, List, Match, Optional, Tuple, Union
from typing import Any, Callable, List, Match, Optional, Sequence, Tuple, Union
from PyQt5.QtCore import Qt
@ -443,12 +443,12 @@ class Reviewer:
return re.sub(self.typeAnsPat, repl, buf)
def _contentForCloze(self, txt: str, idx) -> str:
def _contentForCloze(self, txt: str, idx: int) -> str:
matches = re.findall(r"\{\{c%s::(.+?)\}\}" % idx, txt, re.DOTALL)
if not matches:
return None
def noHint(txt) -> str:
def noHint(txt: str) -> str:
if "::" in txt:
return txt.split("::")[0]
return txt
@ -652,7 +652,7 @@ time = %(time)d;
def _answerButtons(self) -> str:
default = self._defaultEase()
def but(i, label) -> str:
def but(i: int, label: str) -> str:
if i == default:
extra = """id="defease" class="focus" """
else:
@ -755,7 +755,7 @@ time = %(time)d;
qtMenuShortcutWorkaround(m)
m.exec_(QCursor.pos())
def _addMenuItems(self, m, rows) -> None:
def _addMenuItems(self, m: QMenu, rows: Sequence) -> None:
for row in rows:
if not row:
m.addSeparator()

View file

@ -6,21 +6,13 @@ disallow_untyped_decorators = True
warn_redundant_casts = True
warn_unused_configs = True
check_untyped_defs = true
disallow_untyped_defs = True
strict_equality = true
[mypy-aqt.browser]
disallow_untyped_defs=true
[mypy-aqt.sidebar]
disallow_untyped_defs=true
[mypy-aqt.editor]
disallow_untyped_defs=true
[mypy-aqt.utils]
disallow_untyped_defs=true
[mypy-aqt.dyndeckconf]
disallow_untyped_defs=true
[mypy-aqt.winpaths]
disallow_untyped_defs=false
[mypy-aqt.mpv]
disallow_untyped_defs=false
ignore_errors=true
[mypy-pyaudio]
@ -68,3 +60,6 @@ ignore_missing_imports = True
[mypy-aqt.forms.*]
check_untyped_defs=false
disallow_untyped_defs=false
[mypy-anki.*]
disallow_untyped_defs=false