more typing updates

This commit is contained in:
Damien Elmes 2021-02-02 23:30:53 +10:00
parent 4b112950b8
commit 6426edb0ac
23 changed files with 151 additions and 122 deletions

View file

@ -136,7 +136,7 @@ class DialogManager:
def register_dialog( def register_dialog(
self, name: str, creator: Union[Callable, type], instance: Optional[Any] = None self, name: str, creator: Union[Callable, type], instance: Optional[Any] = None
): ) -> None:
"""Allows add-ons to register a custom dialog to be managed by Anki's dialog """Allows add-ons to register a custom dialog to be managed by Anki's dialog
manager, which ensures that only one copy of the window is open at once, manager, which ensures that only one copy of the window is open at once,
and that the dialog cleans up asynchronously when the collection closes and that the dialog cleans up asynchronously when the collection closes
@ -189,12 +189,12 @@ def setupLangAndBackend(
pass pass
# add _ and ngettext globals used by legacy code # add _ and ngettext globals used by legacy code
def fn__(arg) -> None: def fn__(arg) -> None: # type: ignore
print("".join(traceback.format_stack()[-2])) print("".join(traceback.format_stack()[-2]))
print("_ global will break in the future; please see anki/lang.py") print("_ global will break in the future; please see anki/lang.py")
return arg return arg
def fn_ngettext(a, b, c) -> None: def fn_ngettext(a, b, c) -> None: # type: ignore
print("".join(traceback.format_stack()[-2])) print("".join(traceback.format_stack()[-2]))
print("ngettext global will break in the future; please see anki/lang.py") print("ngettext global will break in the future; please see anki/lang.py")
return b return b
@ -244,7 +244,7 @@ class AnkiApp(QApplication):
KEY = "anki" + checksum(getpass.getuser()) KEY = "anki" + checksum(getpass.getuser())
TMOUT = 30000 TMOUT = 30000
def __init__(self, argv) -> None: def __init__(self, argv: List[str]) -> None:
QApplication.__init__(self, argv) QApplication.__init__(self, argv)
self._argv = argv self._argv = argv
@ -267,7 +267,7 @@ class AnkiApp(QApplication):
self._srv.listen(self.KEY) self._srv.listen(self.KEY)
return False return False
def sendMsg(self, txt) -> bool: def sendMsg(self, txt: str) -> bool:
sock = QLocalSocket(self) sock = QLocalSocket(self)
sock.connectToServer(self.KEY, QIODevice.WriteOnly) sock.connectToServer(self.KEY, QIODevice.WriteOnly)
if not sock.waitForConnected(self.TMOUT): if not sock.waitForConnected(self.TMOUT):
@ -298,14 +298,14 @@ class AnkiApp(QApplication):
# OS X file/url handler # OS X file/url handler
################################################## ##################################################
def event(self, evt) -> bool: def event(self, evt: QEvent) -> bool:
if evt.type() == QEvent.FileOpen: if evt.type() == QEvent.FileOpen:
self.appMsg.emit(evt.file() or "raise") # type: ignore self.appMsg.emit(evt.file() or "raise") # type: ignore
return True return True
return QApplication.event(self, evt) return QApplication.event(self, evt)
def parseArgs(argv) -> Tuple[argparse.Namespace, List[str]]: def parseArgs(argv: List[str]) -> Tuple[argparse.Namespace, List[str]]:
"Returns (opts, args)." "Returns (opts, args)."
# py2app fails to strip this in some instances, then anki dies # py2app fails to strip this in some instances, then anki dies
# as there's no such profile # as there's no such profile
@ -330,7 +330,7 @@ def parseArgs(argv) -> Tuple[argparse.Namespace, List[str]]:
return parser.parse_known_args(argv[1:]) return parser.parse_known_args(argv[1:])
def setupGL(pm) -> None: def setupGL(pm: aqt.profiles.ProfileManager) -> None:
if isMac: if isMac:
return return
@ -343,7 +343,7 @@ def setupGL(pm) -> None:
ctypes.CDLL("libGL.so.1", ctypes.RTLD_GLOBAL) ctypes.CDLL("libGL.so.1", ctypes.RTLD_GLOBAL)
# catch opengl errors # catch opengl errors
def msgHandler(category, ctx, msg) -> None: def msgHandler(category: Any, ctx: Any, msg: Any) -> None:
if category == QtDebugMsg: if category == QtDebugMsg:
category = "debug" category = "debug"
elif category == QtInfoMsg: elif category == QtInfoMsg:
@ -420,7 +420,7 @@ def run() -> None:
) )
def _run(argv=None, exec=True) -> Optional[AnkiApp]: def _run(argv: Optional[List[str]] = None, exec: bool = True) -> Optional[AnkiApp]:
"""Start AnkiQt application or reuse an existing instance if one exists. """Start AnkiQt application or reuse an existing instance if one exists.
If the function is invoked with exec=False, the AnkiQt will not enter If the function is invoked with exec=False, the AnkiQt will not enter

View file

@ -4,6 +4,7 @@
import copy import copy
import json import json
import re import re
from concurrent.futures import Future
from typing import Any, Dict, List, Match, Optional from typing import Any, Dict, List, Match, Optional
import aqt import aqt
@ -45,10 +46,10 @@ class CardLayout(QDialog):
self, self,
mw: AnkiQt, mw: AnkiQt,
note: Note, note: Note,
ord=0, ord: int = 0,
parent: Optional[QWidget] = None, parent: Optional[QWidget] = None,
fill_empty: bool = False, fill_empty: bool = False,
): ) -> None:
QDialog.__init__(self, parent or mw, Qt.Window) QDialog.__init__(self, parent or mw, Qt.Window)
mw.setupDialogGC(self) mw.setupDialogGC(self)
self.mw = aqt.mw self.mw = aqt.mw
@ -564,7 +565,7 @@ class CardLayout(QDialog):
def get_count() -> int: def get_count() -> int:
return self.mm.template_use_count(self.model["id"], self.ord) return self.mm.template_use_count(self.model["id"], self.ord)
def on_done(fut) -> None: def on_done(fut: Future) -> None:
card_cnt = fut.result() card_cnt = fut.result()
template = self.current_template() template = self.current_template()
@ -798,7 +799,7 @@ class CardLayout(QDialog):
def save() -> None: def save() -> None:
self.mm.save(self.model) self.mm.save(self.model)
def on_done(fut) -> None: def on_done(fut: Future) -> None:
try: try:
fut.result() fut.result()
except TemplateError as e: except TemplateError as e:

View file

@ -22,7 +22,7 @@ TYPE_ALL = 3
class CustomStudy(QDialog): class CustomStudy(QDialog):
def __init__(self, mw) -> None: def __init__(self, mw: aqt.AnkiQt) -> None:
QDialog.__init__(self, mw) QDialog.__init__(self, mw)
self.mw = mw self.mw = mw
self.deck = self.mw.col.decks.current() self.deck = self.mw.col.decks.current()
@ -57,7 +57,7 @@ class CustomStudy(QDialog):
typeShow = False typeShow = False
ok = tr(TR.CUSTOM_STUDY_OK) ok = tr(TR.CUSTOM_STUDY_OK)
def plus(num) -> str: def plus(num: Union[int, str]) -> str:
if num == 1000: if num == 1000:
num = "1000+" num = "1000+"
return "<b>" + str(num) + "</b>" return "<b>" + str(num) + "</b>"

View file

@ -3,6 +3,8 @@
from __future__ import annotations from __future__ import annotations
from concurrent.futures import Future
import aqt import aqt
from anki.collection import DatabaseCheckProgress, ProgressKind from anki.collection import DatabaseCheckProgress, ProgressKind
from aqt.qt import * from aqt.qt import *
@ -31,7 +33,7 @@ def check_db(mw: aqt.AnkiQt) -> None:
qconnect(timer.timeout, on_timer) qconnect(timer.timeout, on_timer)
timer.start(100) timer.start(100)
def on_future_done(fut) -> None: def on_future_done(fut: Future) -> None:
timer.stop() timer.stop()
ret, ok = fut.result() ret, ok = fut.result()

View file

@ -13,13 +13,13 @@ class DeckChooser(QHBoxLayout):
self, mw: AnkiQt, widget: QWidget, label: bool = True, start: Any = None self, mw: AnkiQt, widget: QWidget, label: bool = True, start: Any = None
) -> None: ) -> None:
QHBoxLayout.__init__(self) QHBoxLayout.__init__(self)
self.widget = widget # type: ignore self._widget = widget # type: ignore
self.mw = mw self.mw = mw
self.label = label self.label = label
self.setContentsMargins(0, 0, 0, 0) self.setContentsMargins(0, 0, 0, 0)
self.setSpacing(8) self.setSpacing(8)
self.setupDecks() self.setupDecks()
self.widget.setLayout(self) self._widget.setLayout(self)
gui_hooks.current_note_type_did_change.append(self.onModelChangeNew) gui_hooks.current_note_type_did_change.append(self.onModelChangeNew)
def setupDecks(self) -> None: def setupDecks(self) -> None:
@ -30,7 +30,7 @@ class DeckChooser(QHBoxLayout):
self.deck = QPushButton(clicked=self.onDeckChange) # type: ignore self.deck = QPushButton(clicked=self.onDeckChange) # type: ignore
self.deck.setAutoDefault(False) self.deck.setAutoDefault(False)
self.deck.setToolTip(shortcut(tr(TR.QT_MISC_TARGET_DECK_CTRLANDD))) self.deck.setToolTip(shortcut(tr(TR.QT_MISC_TARGET_DECK_CTRLANDD)))
QShortcut(QKeySequence("Ctrl+D"), self.widget, activated=self.onDeckChange) # type: ignore QShortcut(QKeySequence("Ctrl+D"), self._widget, activated=self.onDeckChange) # type: ignore
self.addWidget(self.deck) self.addWidget(self.deck)
# starting label # starting label
if self.mw.col.conf.get("addToCur", True): if self.mw.col.conf.get("addToCur", True):
@ -59,10 +59,10 @@ class DeckChooser(QHBoxLayout):
self.deck.setSizePolicy(sizePolicy) self.deck.setSizePolicy(sizePolicy)
def show(self) -> None: def show(self) -> None:
self.widget.show() # type: ignore self._widget.show() # type: ignore
def hide(self) -> None: def hide(self) -> None:
self.widget.hide() # type: ignore self._widget.hide() # type: ignore
def cleanup(self) -> None: def cleanup(self) -> None:
gui_hooks.current_note_type_did_change.remove(self.onModelChangeNew) gui_hooks.current_note_type_did_change.remove(self.onModelChangeNew)
@ -88,7 +88,7 @@ class DeckChooser(QHBoxLayout):
title=tr(TR.QT_MISC_CHOOSE_DECK), title=tr(TR.QT_MISC_CHOOSE_DECK),
help=HelpPage.EDITING, help=HelpPage.EDITING,
cancel=False, cancel=False,
parent=self.widget, parent=self._widget,
geomKey="selectDeck", geomKey="selectDeck",
) )
if ret.name: if ret.name:

View file

@ -4,6 +4,7 @@
from __future__ import annotations from __future__ import annotations
import re import re
from concurrent.futures import Future
import aqt import aqt
from anki.collection import EmptyCardsReport, NoteWithEmptyCards from anki.collection import EmptyCardsReport, NoteWithEmptyCards
@ -15,7 +16,7 @@ from aqt.utils import TR, disable_help_button, restoreGeom, saveGeom, tooltip, t
def show_empty_cards(mw: aqt.main.AnkiQt) -> None: def show_empty_cards(mw: aqt.main.AnkiQt) -> None:
mw.progress.start() mw.progress.start()
def on_done(fut) -> None: def on_done(fut: Future) -> None:
mw.progress.finish() mw.progress.finish()
report: EmptyCardsReport = fut.result() report: EmptyCardsReport = fut.result()
if not report.notes: if not report.notes:
@ -74,7 +75,7 @@ class EmptyCardsDialog(QDialog):
def delete() -> int: def delete() -> int:
return self._delete_cards(self.form.keep_notes.isChecked()) return self._delete_cards(self.form.keep_notes.isChecked())
def on_done(fut) -> None: def on_done(fut: Future) -> None:
self.mw.progress.finish() self.mw.progress.finish()
try: try:
count = fut.result() count = fut.result()

View file

@ -1,6 +1,8 @@
# Copyright: Ankitects Pty Ltd and contributors # Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from concurrent.futures import Future
import aqt import aqt
from anki.consts import * from anki.consts import *
from anki.errors import TemplateError from anki.errors import TemplateError
@ -235,7 +237,7 @@ class FieldDialog(QDialog):
def save() -> None: def save() -> None:
self.mm.save(self.model) self.mm.save(self.model)
def on_done(fut) -> None: def on_done(fut: Future) -> None:
try: try:
fut.result() fut.result()
except TemplateError as e: except TemplateError as e:

View file

@ -13,8 +13,9 @@ import time
import weakref import weakref
import zipfile import zipfile
from argparse import Namespace from argparse import Namespace
from concurrent.futures import Future
from threading import Thread from threading import Thread
from typing import Any, Callable, List, Optional, Sequence, TextIO, Tuple, cast from typing import Any, Callable, Dict, List, Optional, Sequence, TextIO, Tuple, cast
import anki import anki
import aqt import aqt
@ -337,13 +338,13 @@ class AnkiQt(QMainWindow):
): ):
return return
def doOpen(path) -> None: def doOpen(path: str) -> None:
self._openBackup(path) self._openBackup(path)
getFile( getFile(
self.profileDiag, self.profileDiag,
tr(TR.QT_MISC_REVERT_TO_BACKUP), tr(TR.QT_MISC_REVERT_TO_BACKUP),
cb=doOpen, cb=doOpen, # type: ignore
filter="*.colpkg", filter="*.colpkg",
dir=self.pm.backupFolder(), dir=self.pm.backupFolder(),
) )
@ -370,7 +371,7 @@ class AnkiQt(QMainWindow):
def downgrade() -> List[str]: def downgrade() -> List[str]:
return self.pm.downgrade(profiles) return self.pm.downgrade(profiles)
def on_done(future) -> None: def on_done(future: Future) -> None:
self.progress.finish() self.progress.finish()
problems = future.result() problems = future.result()
if not problems: if not problems:
@ -568,7 +569,7 @@ class AnkiQt(QMainWindow):
########################################################################## ##########################################################################
class BackupThread(Thread): class BackupThread(Thread):
def __init__(self, path, data) -> None: def __init__(self, path: str, data: bytes) -> None:
Thread.__init__(self) Thread.__init__(self)
self.path = path self.path = path
self.data = data self.data = data
@ -629,7 +630,7 @@ class AnkiQt(QMainWindow):
# State machine # State machine
########################################################################## ##########################################################################
def moveToState(self, state: str, *args) -> None: def moveToState(self, state: str, *args: Any) -> None:
# print("-> move from", self.state, "to", state) # print("-> move from", self.state, "to", state)
oldState = self.state or "dummy" oldState = self.state or "dummy"
cleanup = getattr(self, "_" + oldState + "Cleanup", None) cleanup = getattr(self, "_" + oldState + "Cleanup", None)
@ -804,7 +805,7 @@ title="%s" %s>%s</button>""" % (
signal.signal(signal.SIGINT, self.onUnixSignal) signal.signal(signal.SIGINT, self.onUnixSignal)
signal.signal(signal.SIGTERM, self.onUnixSignal) signal.signal(signal.SIGTERM, self.onUnixSignal)
def onUnixSignal(self, signum, frame) -> None: def onUnixSignal(self, signum: Any, frame: Any) -> None:
# schedule a rollback & quit # schedule a rollback & quit
def quit() -> None: def quit() -> None:
self.col.db.rollback() self.col.db.rollback()
@ -1184,14 +1185,14 @@ title="%s" %s>%s</button>""" % (
qconnect(self.autoUpdate.clockIsOff, self.clockIsOff) qconnect(self.autoUpdate.clockIsOff, self.clockIsOff)
self.autoUpdate.start() self.autoUpdate.start()
def newVerAvail(self, ver) -> None: def newVerAvail(self, ver: str) -> None:
if self.pm.meta.get("suppressUpdate", None) != ver: if self.pm.meta.get("suppressUpdate", None) != ver:
aqt.update.askAndUpdate(self, ver) aqt.update.askAndUpdate(self, ver)
def newMsg(self, data) -> None: def newMsg(self, data: Dict) -> None:
aqt.update.showMessages(self, data) aqt.update.showMessages(self, data)
def clockIsOff(self, diff) -> None: def clockIsOff(self, diff: int) -> None:
if devMode: if devMode:
print("clock is off; ignoring") print("clock is off; ignoring")
return return
@ -1374,11 +1375,11 @@ title="%s" %s>%s</button>""" % (
d.show() d.show()
def _captureOutput(self, on: bool) -> None: def _captureOutput(self, on: bool) -> None:
mw = self mw2 = self
class Stream: class Stream:
def write(self, data) -> None: def write(self, data: str) -> None:
mw._output += data mw2._output += data
if on: if on:
self._output = "" self._output = ""
@ -1428,7 +1429,7 @@ title="%s" %s>%s</button>""" % (
self._card_repr(card) self._card_repr(card)
return card return card
def onDebugPrint(self, frm) -> None: def onDebugPrint(self, frm: aqt.forms.debug.Ui_Dialog) -> None:
cursor = frm.text.textCursor() cursor = frm.text.textCursor()
position = cursor.position() position = cursor.position()
cursor.select(QTextCursor.LineUnderCursor) cursor.select(QTextCursor.LineUnderCursor)
@ -1441,7 +1442,7 @@ title="%s" %s>%s</button>""" % (
frm.text.setTextCursor(cursor) frm.text.setTextCursor(cursor)
self.onDebugRet(frm) self.onDebugRet(frm)
def onDebugRet(self, frm) -> None: def onDebugRet(self, frm: aqt.forms.debug.Ui_Dialog) -> None:
import pprint import pprint
import traceback import traceback

View file

@ -20,7 +20,7 @@ class ModelChooser(QHBoxLayout):
and the caller can call .onModelChange() to pull up the dialog when they and the caller can call .onModelChange() to pull up the dialog when they
are ready.""" are ready."""
QHBoxLayout.__init__(self) QHBoxLayout.__init__(self)
self.widget = widget # type: ignore self._widget = widget # type: ignore
self.mw = mw self.mw = mw
self.deck = mw.col self.deck = mw.col
self.label = label self.label = label
@ -32,7 +32,7 @@ class ModelChooser(QHBoxLayout):
self.setSpacing(8) self.setSpacing(8)
self.setupModels() self.setupModels()
gui_hooks.state_did_reset.append(self.onReset) gui_hooks.state_did_reset.append(self.onReset)
self.widget.setLayout(self) self._widget.setLayout(self)
def setupModels(self) -> None: def setupModels(self) -> None:
if self.label: if self.label:
@ -41,7 +41,7 @@ class ModelChooser(QHBoxLayout):
# models box # models box
self.models = QPushButton() self.models = QPushButton()
self.models.setToolTip(shortcut(tr(TR.QT_MISC_CHANGE_NOTE_TYPE_CTRLANDN))) self.models.setToolTip(shortcut(tr(TR.QT_MISC_CHANGE_NOTE_TYPE_CTRLANDN)))
QShortcut(QKeySequence("Ctrl+N"), self.widget, activated=self.on_activated) # type: ignore QShortcut(QKeySequence("Ctrl+N"), self._widget, activated=self.on_activated) # type: ignore
self.models.setAutoDefault(False) self.models.setAutoDefault(False)
self.addWidget(self.models) self.addWidget(self.models)
qconnect(self.models.clicked, self.onModelChange) qconnect(self.models.clicked, self.onModelChange)
@ -57,15 +57,15 @@ class ModelChooser(QHBoxLayout):
self.updateModels() self.updateModels()
def show(self) -> None: def show(self) -> None:
self.widget.show() # type: ignore self._widget.show() # type: ignore
def hide(self) -> None: def hide(self) -> None:
self.widget.hide() # type: ignore self._widget.hide() # type: ignore
def onEdit(self) -> None: def onEdit(self) -> None:
import aqt.models import aqt.models
aqt.models.Models(self.mw, self.widget) aqt.models.Models(self.mw, self._widget)
def onModelChange(self) -> None: def onModelChange(self) -> None:
from aqt.studydeck import StudyDeck from aqt.studydeck import StudyDeck
@ -84,7 +84,7 @@ class ModelChooser(QHBoxLayout):
title=tr(TR.QT_MISC_CHOOSE_NOTE_TYPE), title=tr(TR.QT_MISC_CHOOSE_NOTE_TYPE),
help=HelpPage.NOTE_TYPE, help=HelpPage.NOTE_TYPE,
current=current, current=current,
parent=self.widget, parent=self._widget,
buttons=[edit], buttons=[edit],
cancel=True, cancel=True,
geomKey="selectModel", geomKey="selectModel",

View file

@ -1,6 +1,7 @@
# Copyright: Ankitects Pty Ltd and contributors # Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from concurrent.futures import Future
from operator import itemgetter from operator import itemgetter
from typing import Any, List, Optional, Sequence from typing import Any, List, Optional, Sequence
@ -93,7 +94,7 @@ class Models(QDialog):
qconnect(f.modelsList.itemDoubleClicked, self.onRename) qconnect(f.modelsList.itemDoubleClicked, self.onRename)
def on_done(fut) -> None: def on_done(fut: Future) -> None:
self.updateModelsList(fut.result()) self.updateModelsList(fut.result())
self.maybe_select_provided_notetype() self.maybe_select_provided_notetype()
@ -113,7 +114,7 @@ class Models(QDialog):
self.mm.save(nt) self.mm.save(nt)
return self.col.models.all_use_counts() return self.col.models.all_use_counts()
def on_done(fut) -> None: def on_done(fut: Future) -> None:
self.updateModelsList(fut.result()) self.updateModelsList(fut.result())
self.mw.taskman.with_progress(save, on_done, self) self.mw.taskman.with_progress(save, on_done, self)
@ -163,7 +164,7 @@ class Models(QDialog):
self.mm.rem(nt) self.mm.rem(nt)
return self.col.models.all_use_counts() return self.col.models.all_use_counts()
def on_done(fut) -> None: def on_done(fut: Future) -> None:
self.updateModelsList(fut.result()) self.updateModelsList(fut.result())
self.mw.taskman.with_progress(save, on_done, self) self.mw.taskman.with_progress(save, on_done, self)

View file

@ -113,9 +113,9 @@ class LoadMetaResult:
class AnkiRestart(SystemExit): class AnkiRestart(SystemExit):
def __init__(self, *args, **kwargs) -> None: def __init__(self, exitcode: int = 0) -> None:
self.exitcode = kwargs.pop("exitcode", 0) self.exitcode = exitcode
super().__init__(*args, **kwargs) # type: ignore super().__init__()
class ProfileManager: class ProfileManager:
@ -136,7 +136,7 @@ class ProfileManager:
return res return res
# profile load on startup # profile load on startup
def openProfile(self, profile) -> None: def openProfile(self, profile: str) -> None:
if profile: if profile:
if profile not in self.profiles(): if profile not in self.profiles():
QMessageBox.critical( QMessageBox.critical(
@ -185,7 +185,7 @@ class ProfileManager:
self.base = newBase self.base = newBase
shutil.move(oldBase, self.base) shutil.move(oldBase, self.base)
def _tryToMigrateFolder(self, oldBase) -> None: def _tryToMigrateFolder(self, oldBase: str) -> None:
from PyQt5 import QtGui, QtWidgets from PyQt5 import QtGui, QtWidgets
app = QtWidgets.QApplication([]) app = QtWidgets.QApplication([])
@ -257,7 +257,7 @@ class ProfileManager:
return n return n
def _unpickle(self, data) -> Any: def _unpickle(self, data: bytes) -> Any:
class Unpickler(pickle.Unpickler): class Unpickler(pickle.Unpickler):
def find_class(self, module: str, name: str) -> Any: def find_class(self, module: str, name: str) -> Any:
if module == "PyQt5.sip": if module == "PyQt5.sip":
@ -282,7 +282,7 @@ class ProfileManager:
up = Unpickler(io.BytesIO(data), errors="ignore") up = Unpickler(io.BytesIO(data), errors="ignore")
return up.load() return up.load()
def _pickle(self, obj) -> bytes: def _pickle(self, obj: Any) -> bytes:
# pyqt needs to be updated to fix # pyqt needs to be updated to fix
# 'PY_SSIZE_T_CLEAN will be required for '#' formats' warning # 'PY_SSIZE_T_CLEAN will be required for '#' formats' warning
# check if this is still required for pyqt6 # check if this is still required for pyqt6
@ -290,7 +290,7 @@ class ProfileManager:
warnings.simplefilter("ignore") warnings.simplefilter("ignore")
return pickle.dumps(obj, protocol=4) return pickle.dumps(obj, protocol=4)
def load(self, name) -> bool: def load(self, name: str) -> bool:
assert name != "_global" assert name != "_global"
data = self.db.scalar( data = self.db.scalar(
"select cast(data as blob) from profiles where name = ?", name "select cast(data as blob) from profiles where name = ?", name
@ -316,14 +316,14 @@ class ProfileManager:
self.db.execute(sql, self._pickle(self.meta), "_global") self.db.execute(sql, self._pickle(self.meta), "_global")
self.db.commit() self.db.commit()
def create(self, name) -> None: def create(self, name: str) -> None:
prof = profileConf.copy() prof = profileConf.copy()
self.db.execute( self.db.execute(
"insert or ignore into profiles values (?, ?)", name, self._pickle(prof) "insert or ignore into profiles values (?, ?)", name, self._pickle(prof)
) )
self.db.commit() self.db.commit()
def remove(self, name) -> None: def remove(self, name: str) -> None:
p = self.profileFolder() p = self.profileFolder()
if os.path.exists(p): if os.path.exists(p):
send2trash(p) send2trash(p)
@ -335,7 +335,7 @@ class ProfileManager:
if os.path.exists(p): if os.path.exists(p):
send2trash(p) send2trash(p)
def rename(self, name) -> None: def rename(self, name: str) -> None:
oldName = self.name oldName = self.name
oldFolder = self.profileFolder() oldFolder = self.profileFolder()
self.name = name self.name = name
@ -379,7 +379,7 @@ class ProfileManager:
# Folder handling # Folder handling
###################################################################### ######################################################################
def profileFolder(self, create=True) -> str: def profileFolder(self, create: bool = True) -> str:
path = os.path.join(self.base, self.name) path = os.path.join(self.base, self.name)
if create: if create:
self._ensureExists(path) self._ensureExists(path)
@ -397,7 +397,7 @@ class ProfileManager:
# Downgrade # Downgrade
###################################################################### ######################################################################
def downgrade(self, profiles=List[str]) -> List[str]: def downgrade(self, profiles: List[str]) -> List[str]:
"Downgrade all profiles. Return a list of profiles that couldn't be opened." "Downgrade all profiles. Return a list of profiles that couldn't be opened."
problem_profiles = [] problem_profiles = []
for name in profiles: for name in profiles:
@ -449,7 +449,7 @@ class ProfileManager:
os.makedirs(dataDir) os.makedirs(dataDir)
return os.path.join(dataDir, "Anki2") return os.path.join(dataDir, "Anki2")
def _loadMeta(self, retrying=False) -> LoadMetaResult: def _loadMeta(self, retrying: bool = False) -> LoadMetaResult:
result = LoadMetaResult() result = LoadMetaResult()
result.firstTime = False result.firstTime = False
result.loadError = retrying result.loadError = retrying
@ -560,7 +560,7 @@ create table if not exists profiles
return self.setDefaultLang(f.lang.currentRow()) return self.setDefaultLang(f.lang.currentRow())
self.setLang(code) self.setLang(code)
def setLang(self, code) -> None: def setLang(self, code: str) -> None:
self.meta["defaultLang"] = code self.meta["defaultLang"] = code
sql = "update profiles set data = ? where name = ?" sql = "update profiles set data = ? where name = ?"
self.db.execute(sql, self._pickle(self.meta), "_global") self.db.execute(sql, self._pickle(self.meta), "_global")
@ -602,7 +602,7 @@ create table if not exists profiles
def last_addon_update_check(self) -> int: def last_addon_update_check(self) -> int:
return self.meta.get("last_addon_update_check", 0) return self.meta.get("last_addon_update_check", 0)
def set_last_addon_update_check(self, secs) -> None: def set_last_addon_update_check(self, secs: int) -> None:
self.meta["last_addon_update_check"] = secs self.meta["last_addon_update_check"] = secs
def night_mode(self) -> bool: def night_mode(self) -> bool:

View file

@ -39,7 +39,7 @@ def debug() -> None:
if os.environ.get("DEBUG"): if os.environ.get("DEBUG"):
def info(type, value, tb) -> None: def info(type, value, tb) -> None: # type: ignore
for line in traceback.format_exception(type, value, tb): for line in traceback.format_exception(type, value, tb):
sys.stdout.write(line) sys.stdout.write(line)
pyqtRemoveInputHook() pyqtRemoveInputHook()

View file

@ -595,7 +595,7 @@ class QtAudioInputRecorder(Recorder):
wf.writeframes(self._buffer) wf.writeframes(self._buffer)
wf.close() wf.close()
def and_then(fut) -> None: def and_then(fut: Future) -> None:
fut.result() fut.result()
Recorder.stop(self, on_done) Recorder.stop(self, on_done)
@ -686,7 +686,7 @@ class PyAudioRecorder(Recorder):
while self.duration() < 1: while self.duration() < 1:
time.sleep(0.1) time.sleep(0.1)
def func(fut) -> None: def func(fut: Future) -> None:
Recorder.stop(self, on_done) Recorder.stop(self, on_done)
self.thread.finish = True self.thread.finish = True
@ -789,7 +789,7 @@ class RecordDialog(QDialog):
def record_audio( def record_audio(
parent: QWidget, mw: aqt.AnkiQt, encode: bool, on_done: Callable[[str], None] parent: QWidget, mw: aqt.AnkiQt, encode: bool, on_done: Callable[[str], None]
): ) -> None:
def after_record(path: str) -> None: def after_record(path: str) -> None:
if not encode: if not encode:
on_done(path) on_done(path)
@ -812,7 +812,7 @@ def play(filename: str) -> None:
av_player.play_file(filename) av_player.play_file(filename)
def playFromText(text) -> None: def playFromText(text: Any) -> None:
print("playFromText() deprecated") print("playFromText() deprecated")

View file

@ -4,6 +4,7 @@
from __future__ import annotations from __future__ import annotations
import time import time
from typing import Any
import aqt import aqt
from aqt import gui_hooks from aqt import gui_hooks
@ -60,7 +61,7 @@ class NewDeckStats(QDialog):
aqt.dialogs.markClosed("NewDeckStats") aqt.dialogs.markClosed("NewDeckStats")
QDialog.reject(self) QDialog.reject(self)
def closeWithCallback(self, callback) -> None: def closeWithCallback(self, callback: Callable[[], None]) -> None:
self.reject() self.reject()
callback() callback()
@ -84,10 +85,11 @@ class NewDeckStats(QDialog):
self.form.web.page().printToPdf(path) self.form.web.page().printToPdf(path)
tooltip(tr(TR.STATISTICS_SAVED)) tooltip(tr(TR.STATISTICS_SAVED))
def changePeriod(self, n) -> None: # legacy add-ons
def changePeriod(self, n: Any) -> None:
pass pass
def changeScope(self, type) -> None: def changeScope(self, type: Any) -> None:
pass pass
def _on_bridge_cmd(self, cmd: str) -> bool: def _on_bridge_cmd(self, cmd: str) -> bool:
@ -149,7 +151,7 @@ class DeckStats(QDialog):
aqt.dialogs.markClosed("DeckStats") aqt.dialogs.markClosed("DeckStats")
QDialog.reject(self) QDialog.reject(self)
def closeWithCallback(self, callback) -> None: def closeWithCallback(self, callback: Callable[[], None]) -> None:
self.reject() self.reject()
callback() callback()

View file

@ -2,7 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from typing import Optional from typing import List, Optional
import aqt import aqt
from aqt import gui_hooks from aqt import gui_hooks
@ -25,17 +25,17 @@ from aqt.utils import (
class StudyDeck(QDialog): class StudyDeck(QDialog):
def __init__( def __init__(
self, self,
mw, mw: aqt.AnkiQt,
names=None, names: Callable = None,
accept=None, accept: str = None,
title=None, title: str = None,
help: HelpPageArgument = HelpPage.KEYBOARD_SHORTCUTS, help: HelpPageArgument = HelpPage.KEYBOARD_SHORTCUTS,
current=None, current: Optional[str] = None,
cancel=True, cancel: bool = True,
parent=None, parent: Optional[QDialog] = None,
dyn=False, dyn: bool = False,
buttons=None, buttons: Optional[List[str]] = None,
geomKey="default", geomKey: str = "default",
) -> None: ) -> None:
QDialog.__init__(self, parent or mw) QDialog.__init__(self, parent or mw)
if buttons is None: if buttons is None:
@ -65,18 +65,18 @@ class StudyDeck(QDialog):
if title: if title:
self.setWindowTitle(title) self.setWindowTitle(title)
if not names: if not names:
names = [ names_ = [
d.name d.name
for d in self.mw.col.decks.all_names_and_ids( for d in self.mw.col.decks.all_names_and_ids(
include_filtered=dyn, skip_empty_default=True include_filtered=dyn, skip_empty_default=True
) )
] ]
self.nameFunc = None self.nameFunc = None
self.origNames = names self.origNames = names_
else: else:
self.nameFunc = names self.nameFunc = names
self.origNames = names() self.origNames = names()
self.name = None self.name: Optional[str] = None
self.ok = self.form.buttonBox.addButton( self.ok = self.form.buttonBox.addButton(
accept or tr(TR.DECKS_STUDY), QDialogButtonBox.AcceptRole accept or tr(TR.DECKS_STUDY), QDialogButtonBox.AcceptRole
) )

View file

@ -5,6 +5,7 @@ from __future__ import annotations
import enum import enum
import os import os
from concurrent.futures import Future
from typing import Callable, Tuple from typing import Callable, Tuple
import aqt import aqt
@ -48,7 +49,7 @@ def get_sync_status(
callback(SyncStatus(required=SyncStatus.NO_CHANGES)) # pylint:disable=no-member callback(SyncStatus(required=SyncStatus.NO_CHANGES)) # pylint:disable=no-member
return return
def on_future_done(fut) -> None: def on_future_done(fut: Future) -> None:
try: try:
out = fut.result() out = fut.result()
except Exception as e: except Exception as e:
@ -97,7 +98,7 @@ def sync_collection(mw: aqt.main.AnkiQt, on_done: Callable[[], None]) -> None:
qconnect(timer.timeout, on_timer) qconnect(timer.timeout, on_timer)
timer.start(150) timer.start(150)
def on_future_done(fut) -> None: def on_future_done(fut: Future) -> None:
mw.col.db.begin() mw.col.db.begin()
timer.stop() timer.stop()
try: try:
@ -181,7 +182,7 @@ def full_download(mw: aqt.main.AnkiQt, on_done: Callable[[], None]) -> None:
qconnect(timer.timeout, on_timer) qconnect(timer.timeout, on_timer)
timer.start(150) timer.start(150)
def on_future_done(fut) -> None: def on_future_done(fut: Future) -> None:
timer.stop() timer.stop()
mw.col.reopen(after_full_sync=True) mw.col.reopen(after_full_sync=True)
mw.reset() mw.reset()
@ -209,7 +210,7 @@ def full_upload(mw: aqt.main.AnkiQt, on_done: Callable[[], None]) -> None:
qconnect(timer.timeout, on_timer) qconnect(timer.timeout, on_timer)
timer.start(150) timer.start(150)
def on_future_done(fut) -> None: def on_future_done(fut: Future) -> None:
timer.stop() timer.stop()
mw.col.reopen(after_full_sync=True) mw.col.reopen(after_full_sync=True)
mw.reset() mw.reset()
@ -229,7 +230,10 @@ def full_upload(mw: aqt.main.AnkiQt, on_done: Callable[[], None]) -> None:
def sync_login( def sync_login(
mw: aqt.main.AnkiQt, on_success: Callable[[], None], username="", password="" mw: aqt.main.AnkiQt,
on_success: Callable[[], None],
username: str = "",
password: str = "",
) -> None: ) -> None:
while True: while True:
(username, password) = get_id_and_pass_from_user(mw, username, password) (username, password) = get_id_and_pass_from_user(mw, username, password)
@ -238,7 +242,7 @@ def sync_login(
if username and password: if username and password:
break break
def on_future_done(fut) -> None: def on_future_done(fut: Future) -> None:
try: try:
auth = fut.result() auth = fut.result()
except SyncError as e: except SyncError as e:
@ -282,7 +286,7 @@ def ask_user_to_decide_direction() -> FullSyncChoice:
def get_id_and_pass_from_user( def get_id_and_pass_from_user(
mw: aqt.main.AnkiQt, username="", password="" mw: aqt.main.AnkiQt, username: str = "", password: str = ""
) -> Tuple[str, str]: ) -> Tuple[str, str]:
diag = QDialog(mw) diag = QDialog(mw)
diag.setWindowTitle("Anki") diag.setWindowTitle("Anki")

View file

@ -92,7 +92,7 @@ class TagEdit(QLineEdit):
self.completer.setCompletionPrefix(self.text()) self.completer.setCompletionPrefix(self.text())
self.completer.complete() self.completer.complete()
def focusOutEvent(self, evt) -> None: def focusOutEvent(self, evt: QFocusEvent) -> None:
QLineEdit.focusOutEvent(self, evt) QLineEdit.focusOutEvent(self, evt)
self.lostFocus.emit() # type: ignore self.lostFocus.emit() # type: ignore
self.completer.popup().hide() self.completer.popup().hide()
@ -109,7 +109,6 @@ class TagCompleter(QCompleter):
model: QStringListModel, model: QStringListModel,
parent: QWidget, parent: QWidget,
edit: TagEdit, edit: TagEdit,
*args,
) -> None: ) -> None:
QCompleter.__init__(self, model, parent) QCompleter.__init__(self, model, parent)
self.tags: List[str] = [] self.tags: List[str] = []

View file

@ -68,10 +68,10 @@ class TaskManager(QObject):
parent: Optional[QWidget] = None, parent: Optional[QWidget] = None,
label: Optional[str] = None, label: Optional[str] = None,
immediate: bool = False, immediate: bool = False,
): ) -> None:
self.mw.progress.start(parent=parent, label=label, immediate=immediate) self.mw.progress.start(parent=parent, label=label, immediate=immediate)
def wrapped_done(fut) -> None: def wrapped_done(fut: Future) -> None:
self.mw.progress.finish() self.mw.progress.finish()
if on_done: if on_done:
on_done(fut) on_done(fut)

View file

@ -35,6 +35,7 @@ from dataclasses import dataclass
from operator import attrgetter from operator import attrgetter
from typing import Any, List, Optional, cast from typing import Any, List, Optional, cast
import anki
from anki import hooks from anki import hooks
from anki.sound import AVTag, TTSTag from anki.sound import AVTag, TTSTag
from anki.utils import checksum, isWin, tmpdir from anki.utils import checksum, isWin, tmpdir
@ -125,7 +126,9 @@ def all_tts_voices() -> List[TTSVoice]:
return all_voices return all_voices
def on_tts_voices(text: str, field, filter: str, ctx) -> str: def on_tts_voices(
text: str, field: str, filter: str, ctx: anki.template.TemplateRenderContext
) -> str:
if filter != "tts-voices": if filter != "tts-voices":
return text return text
voices = all_tts_voices() voices = all_tts_voices()
@ -572,7 +575,7 @@ if isWin:
# then tell player to advance, which will cause the file to be played # then tell player to advance, which will cause the file to be played
cb() cb()
async def speakText(self, tag: TTSTag, voice_id) -> None: async def speakText(self, tag: TTSTag, voice_id: Any) -> None:
import winrt.windows.media.speechsynthesis as speechsynthesis # type: ignore import winrt.windows.media.speechsynthesis as speechsynthesis # type: ignore
import winrt.windows.storage.streams as streams # type: ignore import winrt.windows.storage.streams as streams # type: ignore

View file

@ -56,7 +56,7 @@ class LatestVersionFinder(QThread):
self.clockIsOff.emit(diff) # type: ignore self.clockIsOff.emit(diff) # type: ignore
def askAndUpdate(mw, ver) -> None: def askAndUpdate(mw: aqt.AnkiQt, ver: str) -> None:
baseStr = tr(TR.QT_MISC_ANKI_UPDATEDANKI_HAS_BEEN_RELEASED, val=ver) baseStr = tr(TR.QT_MISC_ANKI_UPDATEDANKI_HAS_BEEN_RELEASED, val=ver)
msg = QMessageBox(mw) msg = QMessageBox(mw)
msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) # type: ignore msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) # type: ignore
@ -73,6 +73,6 @@ def askAndUpdate(mw, ver) -> None:
openLink(aqt.appWebsite) openLink(aqt.appWebsite)
def showMessages(mw, data) -> None: def showMessages(mw: aqt.AnkiQt, data: Dict) -> None:
showText(data["msg"], parent=mw, type="html") showText(data["msg"], parent=mw, type="html")
mw.pm.meta["lastMsg"] = data["msgId"] mw.pm.meta["lastMsg"] = data["msgId"]

View file

@ -468,6 +468,7 @@ def disable_help_button(widget: QWidget) -> None:
def getFile( def getFile(
parent: QDialog, parent: QDialog,
title: str, title: str,
# single file returned unless multi=True
cb: Optional[Callable[[Union[str, Sequence[str]]], None]], cb: Optional[Callable[[Union[str, Sequence[str]]], None]],
filter: str = "*.*", filter: str = "*.*",
dir: Optional[str] = None, dir: Optional[str] = None,

View file

@ -5,7 +5,7 @@ import dataclasses
import json import json
import re import re
import sys import sys
from typing import Any, Callable, List, Optional, Sequence, Tuple from typing import Any, Callable, List, Optional, Sequence, Tuple, cast
import anki import anki
from anki.lang import is_rtl from anki.lang import is_rtl
@ -20,9 +20,11 @@ serverbaseurl = re.compile(r"^.+:\/\/[^\/]+")
# Page for debug messages # Page for debug messages
########################################################################## ##########################################################################
BridgeCommandHandler = Callable[[str], Any]
class AnkiWebPage(QWebEnginePage): class AnkiWebPage(QWebEnginePage):
def __init__(self, onBridgeCmd) -> None: def __init__(self, onBridgeCmd: BridgeCommandHandler) -> None:
QWebEnginePage.__init__(self) QWebEnginePage.__init__(self)
self._onBridgeCmd = onBridgeCmd self._onBridgeCmd = onBridgeCmd
self._setupBridge() self._setupBridge()
@ -31,7 +33,7 @@ class AnkiWebPage(QWebEnginePage):
def _setupBridge(self) -> None: def _setupBridge(self) -> None:
class Bridge(QObject): class Bridge(QObject):
@pyqtSlot(str, result=str) # type: ignore @pyqtSlot(str, result=str) # type: ignore
def cmd(self, str) -> Any: def cmd(self, str: str) -> Any:
return json.dumps(self.onCmd(str)) return json.dumps(self.onCmd(str))
self._bridge = Bridge() self._bridge = Bridge()
@ -74,7 +76,13 @@ class AnkiWebPage(QWebEnginePage):
script.setRunsOnSubFrames(False) script.setRunsOnSubFrames(False)
self.profile().scripts().insert(script) self.profile().scripts().insert(script)
def javaScriptConsoleMessage(self, level, msg, line, srcID) -> None: def javaScriptConsoleMessage(
self,
level: QWebEnginePage.JavaScriptConsoleMessageLevel,
msg: str,
line: int,
srcID: str,
) -> None:
# not translated because console usually not visible, # not translated because console usually not visible,
# and may only accept ascii text # and may only accept ascii text
if srcID.startswith("data"): if srcID.startswith("data"):
@ -82,13 +90,15 @@ class AnkiWebPage(QWebEnginePage):
else: else:
srcID = serverbaseurl.sub("", srcID[:80], 1) srcID = serverbaseurl.sub("", srcID[:80], 1)
if level == QWebEnginePage.InfoMessageLevel: if level == QWebEnginePage.InfoMessageLevel:
level = "info" level_str = "info"
elif level == QWebEnginePage.WarningMessageLevel: elif level == QWebEnginePage.WarningMessageLevel:
level = "warning" level_str = "warning"
elif level == QWebEnginePage.ErrorMessageLevel: elif level == QWebEnginePage.ErrorMessageLevel:
level = "error" level_str = "error"
else:
level_str = str(level)
buf = "JS %(t)s %(f)s:%(a)d %(b)s" % dict( buf = "JS %(t)s %(f)s:%(a)d %(b)s" % dict(
t=level, a=line, f=srcID, b=msg + "\n" t=level_str, a=line, f=srcID, b=msg + "\n"
) )
if "MathJax localStorage" in buf: if "MathJax localStorage" in buf:
# silence localStorage noise # silence localStorage noise
@ -101,7 +111,9 @@ class AnkiWebPage(QWebEnginePage):
# https://github.com/ankitects/anki/pull/560 # https://github.com/ankitects/anki/pull/560
sys.stdout.write(buf) sys.stdout.write(buf)
def acceptNavigationRequest(self, url, navType, isMainFrame) -> bool: def acceptNavigationRequest(
self, url: QUrl, navType: Any, isMainFrame: bool
) -> bool:
if not self.open_links_externally: if not self.open_links_externally:
return super().acceptNavigationRequest(url, navType, isMainFrame) return super().acceptNavigationRequest(url, navType, isMainFrame)
@ -113,14 +125,14 @@ class AnkiWebPage(QWebEnginePage):
# catch buggy <a href='#' onclick='func()'> links # catch buggy <a href='#' onclick='func()'> links
from aqt import mw from aqt import mw
if url.matches(QUrl(mw.serverURL()), QUrl.RemoveFragment): if url.matches(QUrl(mw.serverURL()), cast(Any, QUrl.RemoveFragment)):
print("onclick handler needs to return false") print("onclick handler needs to return false")
return False return False
# load all other links in browser # load all other links in browser
openLink(url) openLink(url)
return False return False
def _onCmd(self, str) -> None: def _onCmd(self, str: str) -> None:
return self._onBridgeCmd(str) return self._onBridgeCmd(str)
def javaScriptAlert(self, url: QUrl, text: str) -> None: def javaScriptAlert(self, url: QUrl, text: str) -> None:
@ -293,7 +305,7 @@ class AnkiWebView(QWebEngineView):
gui_hooks.webview_will_show_context_menu(self, m) gui_hooks.webview_will_show_context_menu(self, m)
m.popup(QCursor.pos()) m.popup(QCursor.pos())
def dropEvent(self, evt) -> None: def dropEvent(self, evt: QDropEvent) -> None:
pass pass
def setHtml(self, html: str) -> None: # type: ignore def setHtml(self, html: str) -> None: # type: ignore
@ -348,7 +360,7 @@ class AnkiWebView(QWebEngineView):
QWebEngineSettings.PlaybackRequiresUserGesture, value QWebEngineSettings.PlaybackRequiresUserGesture, value
) )
def _getQtIntScale(self, screen) -> int: def _getQtIntScale(self, screen: QWidget) -> int:
# try to detect if Qt has scaled the screen # try to detect if Qt has scaled the screen
# - qt will round the scale factor to a whole number, so a dpi of 125% = 1x, # - qt will round the scale factor to a whole number, so a dpi of 125% = 1x,
# and a dpi of 150% = 2x # and a dpi of 150% = 2x
@ -434,7 +446,7 @@ body {{ zoom: {zoom}; background: {background}; direction: {lang_dir}; {font} }}
js: Optional[List[str]] = None, js: Optional[List[str]] = None,
head: str = "", head: str = "",
context: Optional[Any] = None, context: Optional[Any] = None,
): ) -> None:
web_content = WebContent( web_content = WebContent(
body=body, body=body,
@ -508,7 +520,7 @@ body {{ zoom: {zoom}; background: {background}; direction: {lang_dir}; {font} }}
def _evalWithCallback(self, js: str, cb: Callable[[Any], Any]) -> None: def _evalWithCallback(self, js: str, cb: Callable[[Any], Any]) -> None:
if cb: if cb:
def handler(val) -> None: def handler(val: Any) -> None:
if self._shouldIgnoreWebEvent(): if self._shouldIgnoreWebEvent():
print("ignored late js callback", cb) print("ignored late js callback", cb)
return return
@ -608,7 +620,7 @@ body {{ zoom: {zoom}; background: {background}; direction: {lang_dir}; {font} }}
"Add dynamic styling, and reveal." "Add dynamic styling, and reveal."
css = self.standard_css() css = self.standard_css()
def after_style(arg) -> None: def after_style(arg: Any) -> None:
gui_hooks.webview_did_inject_style_into_page(self) gui_hooks.webview_did_inject_style_into_page(self)
self.show() self.show()

View file

@ -165,7 +165,7 @@ hooks = [
), ),
Hook( Hook(
name="debug_console_did_evaluate_python", name="debug_console_did_evaluate_python",
args=["output: str", "query: str", "debug_window: QDialog"], args=["output: str", "query: str", "debug_window: aqt.forms.debug.Ui_Dialog"],
return_type="str", return_type="str",
doc="""Allows processing the debug result. E.g. logging queries and doc="""Allows processing the debug result. E.g. logging queries and
result, saving last query to display it later...""", result, saving last query to display it later...""",