Update type annotation syntax (#3283)

* chore: add myself to CONTRIBUTORS file

* refactor: use newer type hints for Union/Optional

* refactor: fix deprecated type annotations

use collections.abc rather than typing

* refactor: use lower letter type annotations

* style: reformat with black

* refactor: remove unused imports

* refactor: add missing imports for type hints

* fixup! refactor: use newer type hints for Union/Optional

* fix: add missing imports for type annotations

* fixup! refactor: use newer type hints for Union/Optional

* fixup! style: reformat with black

* refactor: fix remaining imports re: type hints
This commit is contained in:
David Culley 2024-07-21 09:00:52 +02:00 committed by GitHub
parent 412e67db3e
commit 63afb0f8c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
71 changed files with 171 additions and 134 deletions

View file

@ -6,8 +6,9 @@ from __future__ import annotations
import sys import sys
import time import time
import traceback import traceback
from collections.abc import Iterable, Sequence
from threading import current_thread, main_thread from threading import current_thread, main_thread
from typing import TYPE_CHECKING, Any, Iterable, Sequence from typing import TYPE_CHECKING, Any
from weakref import ref from weakref import ref
from markdown import markdown from markdown import markdown

View file

@ -3,7 +3,8 @@
from __future__ import annotations from __future__ import annotations
from typing import Any, Generator, Iterable, Literal, Sequence, Union, cast from collections.abc import Generator, Iterable, Sequence
from typing import Any, Literal, Union, cast
from anki import ( from anki import (
ankiweb_pb2, ankiweb_pb2,

View file

@ -4,8 +4,9 @@
from __future__ import annotations from __future__ import annotations
import re import re
from collections.abc import Iterable, Sequence
from re import Match from re import Match
from typing import TYPE_CHECKING, Any, Callable, Iterable, Sequence, Union from typing import TYPE_CHECKING, Any, Callable, Union
if TYPE_CHECKING: if TYPE_CHECKING:
import anki._backend import anki._backend

View file

@ -4,7 +4,8 @@
from __future__ import annotations from __future__ import annotations
import copy import copy
from typing import TYPE_CHECKING, Any, Iterable, NewType, Sequence from collections.abc import Iterable, Sequence
from typing import TYPE_CHECKING, Any, NewType
if TYPE_CHECKING: if TYPE_CHECKING:
import anki import anki

View file

@ -13,8 +13,9 @@ import threading
import time import time
import unicodedata import unicodedata
import zipfile import zipfile
from collections.abc import Sequence
from io import BufferedWriter from io import BufferedWriter
from typing import Any, Optional, Sequence from typing import Any
from zipfile import ZipFile from zipfile import ZipFile
from anki import hooks from anki import hooks
@ -26,16 +27,16 @@ from anki.utils import ids2str, namedtmp, split_fields, strip_html
class Exporter: class Exporter:
includeHTML: bool | None = None includeHTML: bool | None = None
ext: Optional[str] = None ext: str | None = None
includeTags: Optional[bool] = None includeTags: bool | None = None
includeSched: Optional[bool] = None includeSched: bool | None = None
includeMedia: Optional[bool] = None includeMedia: bool | None = None
def __init__( def __init__(
self, self,
col: Collection, col: Collection,
did: Optional[DeckId] = None, did: DeckId | None = None,
cids: Optional[list[CardId]] = None, cids: list[CardId] | None = None,
) -> None: ) -> None:
self.col = col.weakref() self.col = col.weakref()
self.did = did self.did = did

View file

@ -94,8 +94,8 @@ class ForeignCard:
class ForeignNote: class ForeignNote:
fields: list[str] = field(default_factory=list) fields: list[str] = field(default_factory=list)
tags: list[str] = field(default_factory=list) tags: list[str] = field(default_factory=list)
notetype: Union[str, NotetypeId] = "" notetype: str | NotetypeId = ""
deck: Union[str, DeckId] = "" deck: str | DeckId = ""
cards: list[ForeignCard] = field(default_factory=list) cards: list[ForeignCard] = field(default_factory=list)
@ -103,7 +103,7 @@ class ForeignNote:
class ForeignData: class ForeignData:
notes: list[ForeignNote] = field(default_factory=list) notes: list[ForeignNote] = field(default_factory=list)
notetypes: list[ForeignNotetype] = field(default_factory=list) notetypes: list[ForeignNotetype] = field(default_factory=list)
default_deck: Union[str, DeckId] = "" default_deck: str | DeckId = ""
def serialize(self) -> str: def serialize(self) -> str:
return json.dumps(self, cls=ForeignDataEncoder, separators=(",", ":")) return json.dumps(self, cls=ForeignDataEncoder, separators=(",", ":"))

View file

@ -17,7 +17,6 @@ Notetype | Card Type
import re import re
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Tuple, Type
from anki.db import DB from anki.db import DB
from anki.decks import DeckId from anki.decks import DeckId
@ -38,7 +37,7 @@ def serialize(db_path: str, deck_id: DeckId) -> str:
def gather_data(db: DB, deck_id: DeckId) -> ForeignData: def gather_data(db: DB, deck_id: DeckId) -> ForeignData:
facts = gather_facts(db) facts = gather_facts(db)
gather_cards_into_facts(db, facts) gather_cards_into_facts(db, facts)
used_fact_views: dict[Type[MnemoFactView], bool] = {} used_fact_views: dict[type[MnemoFactView], bool] = {}
notes = [fact.foreign_note(used_fact_views) for fact in facts.values()] notes = [fact.foreign_note(used_fact_views) for fact in facts.values()]
notetypes = [fact_view.foreign_notetype() for fact_view in used_fact_views] notetypes = [fact_view.foreign_notetype() for fact_view in used_fact_views]
return ForeignData(notes, notetypes, deck_id) return ForeignData(notes, notetypes, deck_id)
@ -54,7 +53,7 @@ def open_mnemosyne_db(db_path: str) -> DB:
class MnemoFactView(ABC): class MnemoFactView(ABC):
notetype: str notetype: str
field_keys: Tuple[str, ...] field_keys: tuple[str, ...]
@classmethod @classmethod
@abstractmethod @abstractmethod
@ -162,7 +161,7 @@ class MnemoFact:
cards: list[MnemoCard] = field(default_factory=list) cards: list[MnemoCard] = field(default_factory=list)
def foreign_note( def foreign_note(
self, used_fact_views: dict[Type[MnemoFactView], bool] self, used_fact_views: dict[type[MnemoFactView], bool]
) -> ForeignNote: ) -> ForeignNote:
fact_view = self.fact_view() fact_view = self.fact_view()
used_fact_views[fact_view] = True used_fact_views[fact_view] = True
@ -173,7 +172,7 @@ class MnemoFact:
cards=self.foreign_cards(), cards=self.foreign_cards(),
) )
def fact_view(self) -> Type[MnemoFactView]: def fact_view(self) -> type[MnemoFactView]:
try: try:
fact_view = self.cards[0].fact_view_id fact_view = self.cards[0].fact_view_id
except IndexError as err: except IndexError as err:
@ -190,7 +189,7 @@ class MnemoFact:
raise Exception(f"Fact {id} has unknown fact view: {fact_view}") raise Exception(f"Fact {id} has unknown fact view: {fact_view}")
def anki_fields(self, fact_view: Type[MnemoFactView]) -> list[str]: def anki_fields(self, fact_view: type[MnemoFactView]) -> list[str]:
return [munge_field(self.fields.get(k, "")) for k in fact_view.field_keys] return [munge_field(self.fields.get(k, "")) for k in fact_view.field_keys]
def anki_tags(self) -> list[str]: def anki_tags(self) -> list[str]:

View file

@ -14,6 +14,9 @@ modifying it.
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable
from typing import Any
import decorator import decorator
# You can find the definitions in ../tools/genhooks.py # You can find the definitions in ../tools/genhooks.py

View file

@ -1,7 +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 typing import Any, Callable, Sequence, Type, Union from collections.abc import Sequence
from typing import Any, Callable, Type, Union
import anki import anki
from anki.collection import Collection from anki.collection import Collection

View file

@ -5,7 +5,7 @@
import os import os
import unicodedata import unicodedata
from typing import Optional from typing import Any, Optional
from anki.cards import CardId from anki.cards import CardId
from anki.collection import Collection from anki.collection import Collection

View file

@ -7,7 +7,7 @@ from __future__ import annotations
import csv import csv
import re import re
from typing import Any, Optional, TextIO from typing import Any, TextIO
from anki.collection import Collection from anki.collection import Collection
from anki.importing.noteimp import ForeignNote, NoteImporter from anki.importing.noteimp import ForeignNote, NoteImporter
@ -20,12 +20,12 @@ class TextImporter(NoteImporter):
def __init__(self, col: Collection, file: str) -> None: def __init__(self, col: Collection, file: str) -> None:
NoteImporter.__init__(self, col, file) NoteImporter.__init__(self, col, file)
self.lines = None self.lines = None
self.fileobj: Optional[TextIO] = None self.fileobj: TextIO | None = None
self.delimiter: Optional[str] = None self.delimiter: str | None = None
self.tagsToAdd: list[str] = [] self.tagsToAdd: list[str] = []
self.numFields = 0 self.numFields = 0
self.dialect: Optional[Any] self.dialect: Any | None
self.data: Optional[str | list[str]] self.data: str | list[str] | None
def foreignNotes(self) -> list[ForeignNote]: def foreignNotes(self) -> list[ForeignNote]:
self.open() self.open()

View file

@ -7,7 +7,7 @@ from __future__ import annotations
import html import html
import unicodedata import unicodedata
from typing import Optional, Union from typing import Union
from anki.collection import Collection from anki.collection import Collection
from anki.config import Config from anki.config import Config
@ -76,8 +76,8 @@ class NoteImporter(Importer):
needDelimiter = False needDelimiter = False
allowHTML = False allowHTML = False
importMode = UPDATE_MODE importMode = UPDATE_MODE
mapping: Optional[list[str]] mapping: list[str] | None
tagModified: Optional[str] tagModified: str | None
def __init__(self, col: Collection, file: str) -> None: def __init__(self, col: Collection, file: str) -> None:
Importer.__init__(self, col, file) Importer.__init__(self, col, file)
@ -268,7 +268,7 @@ class NoteImporter(Importer):
def updateData( def updateData(
self, n: ForeignNote, id: NoteId, sflds: list[str] self, n: ForeignNote, id: NoteId, sflds: list[str]
) -> Optional[Updates]: ) -> Updates | None:
self._ids.append(id) self._ids.append(id)
self.processFields(n, sflds) self.processFields(n, sflds)
if self._tagsMapped: if self._tagsMapped:
@ -316,9 +316,7 @@ where id = ? and flds != ?""",
changes2 = self.col.db.scalar("select total_changes()") changes2 = self.col.db.scalar("select total_changes()")
self.updateCount = changes2 - changes self.updateCount = changes2 - changes
def processFields( def processFields(self, note: ForeignNote, fields: list[str] | None = None) -> None:
self, note: ForeignNote, fields: Optional[list[str]] = None
) -> None:
if not fields: if not fields:
fields = [""] * len(self.model["flds"]) fields = [""] * len(self.model["flds"])
for c, f in enumerate(self.mapping): for c, f in enumerate(self.mapping):

View file

@ -8,7 +8,8 @@ import pprint
import re import re
import sys import sys
import time import time
from typing import Callable, Sequence from collections.abc import Sequence
from typing import Callable
from anki import media_pb2 from anki import media_pb2
from anki._legacy import DeprecatedNamesMixin, deprecated_keywords from anki._legacy import DeprecatedNamesMixin, deprecated_keywords

View file

@ -7,7 +7,8 @@ import copy
import pprint import pprint
import sys import sys
import time import time
from typing import Any, NewType, Sequence, Union from collections.abc import Sequence
from typing import Any, NewType, Union
import anki # pylint: disable=unused-import import anki # pylint: disable=unused-import
import anki.collection import anki.collection

View file

@ -4,7 +4,8 @@
from __future__ import annotations from __future__ import annotations
import copy import copy
from typing import NewType, Sequence from collections.abc import Sequence
from typing import NewType
import anki # pylint: disable=unused-import import anki # pylint: disable=unused-import
import anki.cards import anki.cards

View file

@ -22,7 +22,8 @@ ScheduleCardsAsNewDefaults = scheduler_pb2.ScheduleCardsAsNewDefaultsResponse
FilteredDeckForUpdate = decks_pb2.FilteredDeckForUpdate FilteredDeckForUpdate = decks_pb2.FilteredDeckForUpdate
RepositionDefaults = scheduler_pb2.RepositionDefaultsResponse RepositionDefaults = scheduler_pb2.RepositionDefaultsResponse
from typing import Sequence, overload from collections.abc import Sequence
from typing import overload
from anki import config_pb2 from anki import config_pb2
from anki.cards import CardId from anki.cards import CardId

View file

@ -5,8 +5,6 @@
from __future__ import annotations from __future__ import annotations
from typing import Optional
from anki._legacy import deprecated from anki._legacy import deprecated
from anki.cards import Card, CardId from anki.cards import Card, CardId
from anki.consts import ( from anki.consts import (
@ -54,7 +52,7 @@ class SchedulerBaseWithLegacy(SchedulerBase):
print("_nextDueMsg() is obsolete") print("_nextDueMsg() is obsolete")
return "" return ""
def rebuildDyn(self, did: Optional[DeckId] = None) -> Optional[int]: def rebuildDyn(self, did: DeckId | None = None) -> int | None:
did = did or self.col.decks.selected() did = did or self.col.decks.selected()
count = self.rebuild_filtered_deck(did).count or None count = self.rebuild_filtered_deck(did).count or None
if not count: if not count:
@ -63,7 +61,7 @@ class SchedulerBaseWithLegacy(SchedulerBase):
self.col.decks.select(did) self.col.decks.select(did)
return count return count
def emptyDyn(self, did: Optional[DeckId], lim: Optional[str] = None) -> None: def emptyDyn(self, did: DeckId | None, lim: str | None = None) -> None:
if lim is None: if lim is None:
self.empty_filtered_deck(did) self.empty_filtered_deck(did)
return return

View file

@ -14,7 +14,8 @@ as '2' internally.
from __future__ import annotations from __future__ import annotations
from typing import Literal, Optional, Sequence from collections.abc import Sequence
from typing import Any, Literal
from anki import frontend_pb2, scheduler_pb2 from anki import frontend_pb2, scheduler_pb2
from anki._legacy import deprecated from anki._legacy import deprecated
@ -109,7 +110,7 @@ class Scheduler(SchedulerBaseWithLegacy):
# backend automatically resets queues as operations are performed # backend automatically resets queues as operations are performed
pass pass
def getCard(self) -> Optional[Card]: def getCard(self) -> Card | None:
"""Fetch the next card from the queue. None if finished.""" """Fetch the next card from the queue. None if finished."""
try: try:
queued_card = self.get_queued_cards().cards[0] queued_card = self.get_queued_cards().cards[0]
@ -125,7 +126,7 @@ class Scheduler(SchedulerBaseWithLegacy):
"Don't use this, it is a stop-gap until this code is refactored." "Don't use this, it is a stop-gap until this code is refactored."
return not self.get_queued_cards().cards return not self.get_queued_cards().cards
def counts(self, card: Optional[Card] = None) -> tuple[int, int, int]: def counts(self, card: Card | None = None) -> tuple[int, int, int]:
info = self.get_queued_cards() info = self.get_queued_cards()
return (info.new_count, info.learning_count, info.review_count) return (info.new_count, info.learning_count, info.review_count)

View file

@ -8,7 +8,8 @@ from __future__ import annotations
import json import json
import random import random
import time import time
from typing import Sequence from collections.abc import Sequence
from typing import Any
import anki.cards import anki.cards
import anki.collection import anki.collection

View file

@ -13,7 +13,8 @@ from __future__ import annotations
import pprint import pprint
import re import re
from typing import Collection, Match, Sequence from collections.abc import Collection, Sequence
from typing import Match
import anki # pylint: disable=unused-import import anki # pylint: disable=unused-import
import anki.collection import anki.collection

View file

@ -28,8 +28,9 @@ template_legacy.py file, using the legacy addHook() system.
from __future__ import annotations from __future__ import annotations
from collections.abc import Sequence
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, Sequence, Union from typing import Any, Union
import anki import anki
import anki.cards import anki.cards

View file

@ -13,9 +13,10 @@ import subprocess
import sys import sys
import tempfile import tempfile
import time import time
from collections.abc import Iterable, Iterator
from contextlib import contextmanager from contextlib import contextmanager
from hashlib import sha1 from hashlib import sha1
from typing import TYPE_CHECKING, Any, Callable, Iterable, Iterator from typing import TYPE_CHECKING, Any, Callable
from anki._legacy import DeprecatedNamesMixinForModule from anki._legacy import DeprecatedNamesMixinForModule
from anki.dbproxy import DBProxy from anki.dbproxy import DBProxy

View file

@ -385,7 +385,7 @@ def test_reviews():
assert "leech" in c.note().tags assert "leech" in c.note().tags
def review_limits_setup() -> tuple[anki.collection.Collection, Dict]: def review_limits_setup() -> tuple[anki.collection.Collection, dict]:
col = getEmptyCol() col = getEmptyCol()
parent = col.decks.get(col.decks.id("parent")) parent = col.decks.get(col.decks.id("parent"))

View file

@ -5,6 +5,8 @@ from __future__ import annotations
import logging import logging
import sys import sys
from collections.abc import Callable
from typing import TYPE_CHECKING, Any, Union, cast
try: try:
import pip_system_certs.wrapt_requests import pip_system_certs.wrapt_requests
@ -50,7 +52,6 @@ import os
import tempfile import tempfile
import traceback import traceback
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Any, Callable, Optional, cast
import anki.lang import anki.lang
from anki._backend import RustBackend from anki._backend import RustBackend
@ -92,8 +93,8 @@ appHelpSite = HELP_SITE
from aqt.main import AnkiQt # isort:skip from aqt.main import AnkiQt # isort:skip
from aqt.profiles import ProfileManager, VideoDriver # isort:skip from aqt.profiles import ProfileManager, VideoDriver # isort:skip
profiler: Optional[cProfile.Profile] = None profiler: cProfile.Profile | None = None
mw: Optional[AnkiQt] = None # set on init mw: AnkiQt | None = None # set on init
import aqt.forms import aqt.forms
@ -154,7 +155,7 @@ class DialogManager:
def allClosed(self) -> bool: def allClosed(self) -> bool:
return not any(x[1] for x in self._dialogs.values()) return not any(x[1] for x in self._dialogs.values())
def closeAll(self, onsuccess: Callable[[], None]) -> Optional[bool]: def closeAll(self, onsuccess: Callable[[], None]) -> bool | None:
# can we close immediately? # can we close immediately?
if self.allClosed(): if self.allClosed():
onsuccess() onsuccess()
@ -181,7 +182,7 @@ class DialogManager:
return True return True
def register_dialog( def register_dialog(
self, name: str, creator: Union[Callable, type], instance: Optional[Any] = None self, name: str, creator: Callable | type, instance: Any | None = None
) -> 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,
@ -219,13 +220,13 @@ dialogs = DialogManager()
# A reference to the Qt translator needs to be held to prevent it from # A reference to the Qt translator needs to be held to prevent it from
# being immediately deallocated. # being immediately deallocated.
_qtrans: Optional[QTranslator] = None _qtrans: QTranslator | None = None
def setupLangAndBackend( def setupLangAndBackend(
pm: ProfileManager, pm: ProfileManager,
app: QApplication, app: QApplication,
force: Optional[str] = None, force: str | None = None,
firstTime: bool = False, firstTime: bool = False,
) -> RustBackend: ) -> RustBackend:
global _qtrans global _qtrans
@ -288,7 +289,7 @@ def setupLangAndBackend(
class NativeEventFilter(QAbstractNativeEventFilter): class NativeEventFilter(QAbstractNativeEventFilter):
def nativeEventFilter( def nativeEventFilter(
self, eventType: Any, message: Any self, eventType: Any, message: Any
) -> tuple[bool, Optional[sip.voidptr]]: ) -> tuple[bool, sip.voidptr | None]:
if eventType == "windows_generic_MSG": if eventType == "windows_generic_MSG":
import ctypes import ctypes
@ -563,7 +564,7 @@ def run() -> None:
) )
def _run(argv: Optional[list[str]] = None, exec: bool = True) -> Optional[AnkiApp]: def _run(argv: list[str] | None = None, exec: bool = True) -> AnkiApp | None:
"""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

@ -2,6 +2,7 @@
# 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
import platform import platform
from collections.abc import Callable
import aqt.forms import aqt.forms
from anki.lang import without_unicode_isolation from anki.lang import without_unicode_isolation

View file

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
from typing import Callable, Optional from typing import Callable
import aqt.editor import aqt.editor
import aqt.forms import aqt.forms
@ -54,7 +54,7 @@ class AddCards(QMainWindow):
self.setupButtons() self.setupButtons()
self.col.add_image_occlusion_notetype() self.col.add_image_occlusion_notetype()
self.history: list[NoteId] = [] self.history: list[NoteId] = []
self._last_added_note: Optional[Note] = None self._last_added_note: Note | None = None
gui_hooks.operation_did_execute.append(self.on_operation_did_execute) gui_hooks.operation_did_execute.append(self.on_operation_did_execute)
restoreGeom(self, "add") restoreGeom(self, "add")
gui_hooks.add_cards_did_init(self) gui_hooks.add_cards_did_init(self)
@ -195,7 +195,7 @@ class AddCards(QMainWindow):
self, old_note.note_type(), new_note.note_type() self, old_note.note_type(), new_note.note_type()
) )
def _load_new_note(self, sticky_fields_from: Optional[Note] = None) -> None: def _load_new_note(self, sticky_fields_from: Note | None = None) -> None:
note = self._new_note() note = self._new_note()
if old_note := sticky_fields_from: if old_note := sticky_fields_from:
flds = note.note_type()["flds"] flds = note.note_type()["flds"]
@ -209,7 +209,7 @@ class AddCards(QMainWindow):
self.setAndFocusNote(note) self.setAndFocusNote(note)
def on_operation_did_execute( def on_operation_did_execute(
self, changes: OpChanges, handler: Optional[object] self, changes: OpChanges, handler: object | None
) -> None: ) -> None:
if (changes.notetype or changes.deck) and handler is not self.editor: if (changes.notetype or changes.deck) and handler is not self.editor:
self.on_notetype_change( self.on_notetype_change(

View file

@ -11,11 +11,12 @@ import os
import re import re
import zipfile import zipfile
from collections import defaultdict from collections import defaultdict
from collections.abc import Iterable, Sequence
from concurrent.futures import Future from concurrent.futures import Future
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from typing import IO, Any, Callable, Iterable, Sequence, Union from typing import IO, Any, Callable, Union
from urllib.parse import parse_qs, urlparse from urllib.parse import parse_qs, urlparse
from zipfile import ZipFile from zipfile import ZipFile

View file

@ -6,7 +6,8 @@ from __future__ import annotations
import json import json
import math import math
import re import re
from typing import Callable, Sequence from collections.abc import Sequence
from typing import Any, Callable
import aqt import aqt
import aqt.browser import aqt.browser

View file

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
from typing import Sequence from collections.abc import Sequence
import aqt import aqt
import aqt.forms import aqt.forms

View file

@ -2,8 +2,9 @@
# 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 __future__ import annotations from __future__ import annotations
from collections.abc import Iterable
from enum import Enum, auto from enum import Enum, auto
from typing import Callable, Iterable from typing import Callable
from anki.collection import SearchNode from anki.collection import SearchNode
from aqt.theme import ColoredIcon from aqt.theme import ColoredIcon

View file

@ -3,6 +3,7 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable
from enum import Enum, auto from enum import Enum, auto
import aqt import aqt

View file

@ -2,8 +2,9 @@
# 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 __future__ import annotations from __future__ import annotations
from collections.abc import Callable, Iterable
from enum import Enum, auto from enum import Enum, auto
from typing import Iterable, cast from typing import cast
import aqt import aqt
import aqt.browser import aqt.browser
@ -266,7 +267,7 @@ class SidebarTreeView(QTreeView):
def update_search( def update_search(
self, self,
*terms: Union[str, SearchNode], *terms: str | SearchNode,
joiner: SearchJoiner = "AND", joiner: SearchJoiner = "AND",
) -> None: ) -> None:
"""Modify the current search string based on modifier keys, then refresh.""" """Modify the current search string based on modifier keys, then refresh."""
@ -524,7 +525,7 @@ class SidebarTreeView(QTreeView):
*, *,
root: SidebarItem, root: SidebarItem,
name: str, name: str,
icon: Union[str, ColoredIcon], icon: str | ColoredIcon,
collapse_key: Config.Bool.V, collapse_key: Config.Bool.V,
type: SidebarItemType | None = None, type: SidebarItemType | None = None,
) -> SidebarItem: ) -> SidebarItem:

View file

@ -4,8 +4,9 @@ from __future__ import annotations
import copy import copy
import time import time
from collections.abc import Generator, Sequence
from dataclasses import dataclass from dataclasses import dataclass
from typing import TYPE_CHECKING, Generator, Sequence, Union from typing import TYPE_CHECKING, Union
import aqt import aqt
import aqt.browser import aqt.browser

View file

@ -3,7 +3,8 @@
from __future__ import annotations from __future__ import annotations
import time import time
from typing import Any, Callable, Sequence from collections.abc import Sequence
from typing import Any, Callable
import aqt import aqt
import aqt.browser import aqt.browser

View file

@ -3,7 +3,8 @@
from __future__ import annotations from __future__ import annotations
from abc import ABC, abstractmethod, abstractproperty from abc import ABC, abstractmethod, abstractproperty
from typing import Sequence, cast from collections.abc import Sequence
from typing import cast
from anki.browser import BrowserConfig from anki.browser import BrowserConfig
from anki.cards import Card, CardId from anki.cards import Card, CardId

View file

@ -2,7 +2,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 __future__ import annotations from __future__ import annotations
from typing import Any, Callable, Sequence from collections.abc import Sequence
from typing import Any, Callable
import aqt import aqt
import aqt.browser import aqt.browser

View file

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
from typing import Sequence from collections.abc import Sequence
import aqt import aqt
import aqt.deckconf import aqt.deckconf

View file

@ -5,8 +5,9 @@ from __future__ import annotations
import json import json
import re import re
from collections.abc import Callable
from concurrent.futures import Future from concurrent.futures import Future
from typing import Any, Match, Optional, cast from typing import Any, Match, cast
import aqt import aqt
import aqt.forms import aqt.forms
@ -50,7 +51,7 @@ class CardLayout(QDialog):
mw: AnkiQt, mw: AnkiQt,
note: Note, note: Note,
ord: int = 0, ord: int = 0,
parent: Optional[QWidget] = None, parent: QWidget | None = None,
fill_empty: bool = False, fill_empty: bool = False,
) -> None: ) -> None:
QDialog.__init__(self, parent or mw, Qt.WindowType.Window) QDialog.__init__(self, parent or mw, Qt.WindowType.Window)
@ -509,7 +510,7 @@ class CardLayout(QDialog):
# Preview # Preview
########################################################################## ##########################################################################
_previewTimer: Optional[QTimer] = None _previewTimer: QTimer | None = None
def renderPreview(self) -> None: def renderPreview(self) -> None:
# schedule a preview when timing stops # schedule a preview when timing stops
@ -590,7 +591,7 @@ class CardLayout(QDialog):
return res return res
type_filter = r"\[\[type:.+?\]\]" type_filter = r"\[\[type:.+?\]\]"
repl: Union[str, Callable] repl: str | Callable
if type == "q": if type == "q":
repl = "<input id='typeans' type=text value='example' readonly='readonly'>" repl = "<input id='typeans' type=text value='example' readonly='readonly'>"

View file

@ -3,8 +3,6 @@
from __future__ import annotations from __future__ import annotations
from typing import Tuple
import aqt import aqt
import aqt.forms import aqt.forms
import aqt.operations import aqt.operations
@ -37,12 +35,12 @@ class CustomStudy(QDialog):
def fetch_data_and_show(mw: aqt.AnkiQt) -> None: def fetch_data_and_show(mw: aqt.AnkiQt) -> None:
def fetch_data( def fetch_data(
col: Collection, col: Collection,
) -> Tuple[DeckId, CustomStudyDefaults]: ) -> tuple[DeckId, CustomStudyDefaults]:
deck_id = mw.col.decks.get_current_id() deck_id = mw.col.decks.get_current_id()
defaults = col.sched.custom_study_defaults(deck_id) defaults = col.sched.custom_study_defaults(deck_id)
return (deck_id, defaults) return (deck_id, defaults)
def show_dialog(data: Tuple[DeckId, CustomStudyDefaults]) -> None: def show_dialog(data: tuple[DeckId, CustomStudyDefaults]) -> None:
deck_id, defaults = data deck_id, defaults = data
CustomStudy(mw=mw, deck_id=deck_id, defaults=defaults) CustomStudy(mw=mw, deck_id=deck_id, defaults=defaults)

View file

@ -4,6 +4,7 @@
from __future__ import annotations from __future__ import annotations
import os import os
from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from functools import partial from functools import partial
from pathlib import Path from pathlib import Path

View file

@ -3,6 +3,8 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable
from anki.collection import OpChanges from anki.collection import OpChanges
from anki.decks import DEFAULT_DECK_ID, DeckId from anki.decks import DEFAULT_DECK_ID, DeckId
from aqt import AnkiQt, gui_hooks from aqt import AnkiQt, gui_hooks

View file

@ -173,8 +173,8 @@ class DeckConf(QDialog):
# Loading # Loading
################################################## ##################################################
def listToUser(self, l: list[Union[int, float]]) -> str: def listToUser(self, l: list[int | float]) -> str:
def num_to_user(n: Union[int, float]) -> str: def num_to_user(n: int | float) -> str:
if n == round(n): if n == round(n):
return str(int(n)) return str(int(n))
else: else:

View file

@ -1,5 +1,6 @@
# 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 collections.abc import Callable
from typing import Optional from typing import Optional
import aqt.editor import aqt.editor

View file

@ -5,7 +5,7 @@ from __future__ import annotations
import re import re
import time import time
from typing import TYPE_CHECKING, Optional, TextIO, cast from typing import TYPE_CHECKING, TextIO, cast
from markdown import markdown from markdown import markdown
@ -169,7 +169,7 @@ class ErrorHandler(QObject):
def __init__(self, mw: AnkiQt) -> None: def __init__(self, mw: AnkiQt) -> None:
QObject.__init__(self, mw) QObject.__init__(self, mw)
self.mw = mw self.mw = mw
self.timer: Optional[QTimer] = None self.timer: QTimer | None = None
qconnect(self.errorTimer, self._setTimer) qconnect(self.errorTimer, self._setTimer)
self.pool = "" self.pool = ""
self._oldstderr = sys.stderr self._oldstderr = sys.stderr

View file

@ -7,7 +7,6 @@ import os
import re import re
import time import time
from concurrent.futures import Future from concurrent.futures import Future
from typing import Optional
import aqt import aqt
import aqt.forms import aqt.forms
@ -35,7 +34,7 @@ class ExportDialog(QDialog):
mw: aqt.main.AnkiQt, mw: aqt.main.AnkiQt,
did: DeckId | None = None, did: DeckId | None = None,
cids: list[CardId] | None = None, cids: list[CardId] | None = None,
parent: Optional[QWidget] = None, parent: QWidget | None = None,
): ):
QDialog.__init__(self, parent or mw, Qt.WindowType.Window) QDialog.__init__(self, parent or mw, Qt.WindowType.Window)
self.mw = mw self.mw = mw

View file

@ -3,8 +3,6 @@
from __future__ import annotations from __future__ import annotations
from typing import Optional
import aqt import aqt
import aqt.forms import aqt.forms
import aqt.operations import aqt.operations
@ -32,7 +30,7 @@ class FieldDialog(QDialog):
self, self,
mw: AnkiQt, mw: AnkiQt,
nt: NotetypeDict, nt: NotetypeDict,
parent: Optional[QWidget] = None, parent: QWidget | None = None,
open_at: int = 0, open_at: int = 0,
) -> None: ) -> None:
QDialog.__init__(self, parent or mw) QDialog.__init__(self, parent or mw)
@ -62,7 +60,7 @@ class FieldDialog(QDialog):
self.form.buttonBox.button(QDialogButtonBox.StandardButton.Save).setAutoDefault( self.form.buttonBox.button(QDialogButtonBox.StandardButton.Save).setAutoDefault(
False False
) )
self.currentIdx: Optional[int] = None self.currentIdx: int | None = None
self.fillFields() self.fillFields()
self.setupSignals() self.setupSignals()
self.form.fieldList.setDragDropMode(QAbstractItemView.DragDropMode.InternalMove) self.form.fieldList.setDragDropMode(QAbstractItemView.DragDropMode.InternalMove)
@ -125,8 +123,8 @@ class FieldDialog(QDialog):
self.loadField(idx) self.loadField(idx)
def _uniqueName( def _uniqueName(
self, prompt: str, ignoreOrd: Optional[int] = None, old: str = "" self, prompt: str, ignoreOrd: int | None = None, old: str = ""
) -> Optional[str]: ) -> str | None:
txt = getOnlyText(prompt, default=old).replace('"', "").strip() txt = getOnlyText(prompt, default=old).replace('"', "").strip()
if not txt: if not txt:
return None return None

View file

@ -7,8 +7,8 @@ import os
import re import re
import time import time
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from collections.abc import Sequence
from dataclasses import dataclass from dataclasses import dataclass
from typing import Optional, Sequence, Type
import aqt.forms import aqt.forms
import aqt.main import aqt.main
@ -42,7 +42,7 @@ class ExportDialog(QDialog):
mw: aqt.main.AnkiQt, mw: aqt.main.AnkiQt,
did: DeckId | None = None, did: DeckId | None = None,
nids: Sequence[NoteId] | None = None, nids: Sequence[NoteId] | None = None,
parent: Optional[QWidget] = None, parent: QWidget | None = None,
): ):
QDialog.__init__(self, parent or mw, Qt.WindowType.Window) QDialog.__init__(self, parent or mw, Qt.WindowType.Window)
self.mw = mw self.mw = mw
@ -56,7 +56,7 @@ class ExportDialog(QDialog):
self.open() self.open()
def setup(self, did: DeckId | None) -> None: def setup(self, did: DeckId | None) -> None:
self.exporter_classes: list[Type[Exporter]] = [ self.exporter_classes: list[type[Exporter]] = [
ApkgExporter, ApkgExporter,
ColpkgExporter, ColpkgExporter,
NoteCsvExporter, NoteCsvExporter,

View file

@ -5,8 +5,8 @@ from __future__ import annotations
import re import re
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from collections.abc import Callable
from itertools import chain from itertools import chain
from typing import Type
import aqt.main import aqt.main
from anki.collection import Collection, Progress from anki.collection import Collection, Progress
@ -124,7 +124,7 @@ class JsonImporter(Importer):
ImportDialog(mw, JsonFileArgs(path=path)) ImportDialog(mw, JsonFileArgs(path=path))
IMPORTERS: list[Type[Importer]] = [ IMPORTERS: list[type[Importer]] = [
ColpkgImporter, ColpkgImporter,
ApkgImporter, ApkgImporter,
MnemosyneImporter, MnemosyneImporter,

View file

@ -4,6 +4,7 @@ import os
import re import re
import traceback import traceback
import zipfile import zipfile
from collections.abc import Callable
from concurrent.futures import Future from concurrent.futures import Future
from typing import Any, Optional from typing import Any, Optional

View file

@ -10,8 +10,9 @@ import re
import signal import signal
import weakref import weakref
from argparse import Namespace from argparse import Namespace
from collections.abc import Callable, Sequence
from concurrent.futures import Future from concurrent.futures import Future
from typing import Any, Literal, Sequence, TypeVar, cast from typing import Any, Literal, TypeVar, cast
import anki import anki
import anki.cards import anki.cards

View file

@ -5,8 +5,9 @@ from __future__ import annotations
import itertools import itertools
import time import time
from collections.abc import Iterable, Sequence
from concurrent.futures import Future from concurrent.futures import Future
from typing import Iterable, Sequence, TypeVar from typing import TypeVar
import aqt import aqt
import aqt.progress import aqt.progress

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 collections.abc import Callable
from typing import Optional from typing import Optional
from aqt import AnkiQt, gui_hooks from aqt import AnkiQt, gui_hooks

View file

@ -3,9 +3,10 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable, Sequence
from concurrent.futures import Future from concurrent.futures import Future
from operator import itemgetter from operator import itemgetter
from typing import Any, Optional, Sequence from typing import Any
import aqt.clayout import aqt.clayout
from anki import stdmodels from anki import stdmodels
@ -40,9 +41,9 @@ class Models(QDialog):
def __init__( def __init__(
self, self,
mw: AnkiQt, mw: AnkiQt,
parent: Optional[QWidget] = None, parent: QWidget | None = None,
fromMain: bool = False, fromMain: bool = False,
selected_notetype_id: Optional[NotetypeId] = None, selected_notetype_id: NotetypeId | None = None,
): ):
self.mw = mw self.mw = mw
parent = parent or mw parent = parent or mw
@ -231,13 +232,13 @@ class Models(QDialog):
class AddModel(QDialog): class AddModel(QDialog):
model: Optional[NotetypeDict] model: NotetypeDict | None
def __init__( def __init__(
self, self,
mw: AnkiQt, mw: AnkiQt,
on_success: Callable[[NotetypeDict], None], on_success: Callable[[NotetypeDict], None],
parent: Optional[QWidget] = None, parent: QWidget | None = None,
) -> None: ) -> None:
self.parent_ = parent or mw self.parent_ = parent or mw
self.mw = mw self.mw = mw
@ -249,9 +250,7 @@ class AddModel(QDialog):
self.setWindowModality(Qt.WindowModality.ApplicationModal) self.setWindowModality(Qt.WindowModality.ApplicationModal)
disable_help_button(self) disable_help_button(self)
# standard models # standard models
self.notetypes: list[ self.notetypes: list[NotetypeDict | Callable[[Collection], NotetypeDict]] = []
Union[NotetypeDict, Callable[[Collection], NotetypeDict]]
] = []
for name, func in stdmodels.get_stock_notetypes(self.col): for name, func in stdmodels.get_stock_notetypes(self.col):
item = QListWidgetItem(tr.notetypes_add(val=name)) item = QListWidgetItem(tr.notetypes_add(val=name))
self.dialog.models.addItem(item) self.dialog.models.addItem(item)

View file

@ -3,6 +3,8 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable
from anki.collection import OpChanges from anki.collection import OpChanges
from anki.models import NotetypeId from anki.models import NotetypeId
from aqt import AnkiQt, gui_hooks from aqt import AnkiQt, gui_hooks

View file

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
from typing import Sequence from collections.abc import Sequence
from anki.cards import CardId from anki.cards import CardId
from anki.collection import OpChangesWithCount from anki.collection import OpChangesWithCount

View file

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
from typing import Sequence from collections.abc import Sequence
from anki.collection import OpChanges, OpChangesWithCount, OpChangesWithId from anki.collection import OpChanges, OpChangesWithCount, OpChangesWithId
from anki.decks import DeckCollapseScope, DeckDict, DeckId, UpdateDeckConfigs from anki.decks import DeckCollapseScope, DeckDict, DeckId, UpdateDeckConfigs

View file

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
from typing import Sequence from collections.abc import Sequence
from anki.collection import OpChanges, OpChangesWithCount from anki.collection import OpChanges, OpChangesWithCount
from anki.decks import DeckId from anki.decks import DeckId

View file

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
from typing import Sequence from collections.abc import Sequence
import aqt import aqt
import aqt.forms import aqt.forms

View file

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
from typing import Sequence from collections.abc import Sequence
from anki.collection import OpChanges, OpChangesWithCount from anki.collection import OpChanges, OpChangesWithCount
from anki.notes import NoteId from anki.notes import NoteId

View file

@ -5,6 +5,7 @@ from __future__ import annotations
import functools import functools
import re import re
from collections.abc import Callable
import anki.lang import anki.lang
import aqt import aqt

View file

@ -10,7 +10,7 @@ import shutil
import traceback import traceback
from enum import Enum from enum import Enum
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Any, Optional from typing import TYPE_CHECKING, Any
import anki.lang import anki.lang
import aqt.forms import aqt.forms
@ -544,7 +544,7 @@ create table if not exists profiles
def set_spacebar_rates_card(self, on: bool) -> None: def set_spacebar_rates_card(self, on: bool) -> None:
self.meta["spacebar_rates_card"] = on self.meta["spacebar_rates_card"] = on
def get_answer_key(self, ease: int) -> Optional[str]: def get_answer_key(self, ease: int) -> str | None:
return self.meta.setdefault("answer_keys", self.default_answer_keys).get(ease) return self.meta.setdefault("answer_keys", self.default_answer_keys).get(ease)
def set_answer_key(self, ease: int, key: str): def set_answer_key(self, ease: int, key: str):

View file

@ -3,6 +3,7 @@
from __future__ import annotations from __future__ import annotations
import time import time
from collections.abc import Callable
from concurrent.futures import Future from concurrent.futures import Future
from dataclasses import dataclass from dataclasses import dataclass

View file

@ -8,6 +8,7 @@ PyQt5-only audio code
""" """
import wave import wave
from collections.abc import Callable
from concurrent.futures import Future from concurrent.futures import Future
from typing import cast from typing import cast

View file

@ -7,9 +7,10 @@ import functools
import json import json
import random import random
import re import re
from collections.abc import Callable, Sequence
from dataclasses import dataclass from dataclasses import dataclass
from enum import Enum, auto from enum import Enum, auto
from typing import Any, Literal, Match, Sequence, cast from typing import Any, Literal, Match, Union, cast
import aqt import aqt
import aqt.browser import aqt.browser
@ -568,7 +569,7 @@ class Reviewer:
def korean_shortcuts( def korean_shortcuts(
self, self,
) -> Sequence[Union[tuple[str, Callable], tuple[Qt.Key, Callable]]]: ) -> Sequence[tuple[str, Callable] | tuple[Qt.Key, Callable]]:
return [ return [
("", self.mw.onEditCurrent), ("", self.mw.onEditCurrent),
("", self.showContextMenu), ("", self.showContextMenu),
@ -588,7 +589,7 @@ class Reviewer:
def _shortcutKeys( def _shortcutKeys(
self, self,
) -> Sequence[Union[tuple[str, Callable], tuple[Qt.Key, Callable]]]: ) -> Sequence[tuple[str, Callable] | tuple[Qt.Key, Callable]]:
return [ return [
("e", self.mw.onEditCurrent), ("e", self.mw.onEditCurrent),
(" ", self.onEnterKey), (" ", self.onEnterKey),
@ -839,7 +840,7 @@ timerStopped = false;
if not self.mw.col.conf["dueCounts"]: if not self.mw.col.conf["dueCounts"]:
return "" return ""
counts: list[Union[int, str]] counts: list[int | str]
idx, counts_ = self._v3.counts() idx, counts_ = self._v3.counts()
counts = cast(list[Union[int, str]], counts_) counts = cast(list[Union[int, str]], counts_)
counts[idx] = f"<u>{counts[idx]}</u>" counts[idx] = f"<u>{counts[idx]}</u>"

View file

@ -3,6 +3,7 @@
from __future__ import annotations from __future__ import annotations
import time import time
from collections.abc import Callable
from typing import Any from typing import Any
import aqt import aqt

View file

@ -4,7 +4,7 @@
from __future__ import annotations from __future__ import annotations
import re import re
from typing import Iterable from collections.abc import Iterable
from anki.collection import Collection from anki.collection import Collection
from aqt import gui_hooks from aqt import gui_hooks

View file

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
from typing import Sequence from collections.abc import Callable, Sequence
import aqt import aqt
import aqt.customstudy import aqt.customstudy

View file

@ -8,7 +8,7 @@ import os
import re import re
import subprocess import subprocess
from dataclasses import dataclass from dataclasses import dataclass
from typing import Callable, List, Tuple from typing import Callable
import anki.lang import anki.lang
import aqt import aqt
@ -386,7 +386,7 @@ def get_linux_dark_mode() -> bool:
return dbus_response[-1] == PREFER_DARK return dbus_response[-1] == PREFER_DARK
dark_mode_detection_strategies: List[Tuple[str, Callable[[str], bool]]] = [ dark_mode_detection_strategies: list[tuple[str, Callable[[str], bool]]] = [
( (
"dbus-send --session --print-reply=literal --reply-timeout=1000 " "dbus-send --session --print-reply=literal --reply-timeout=1000 "
"--dest=org.freedesktop.portal.Desktop /org/freedesktop/portal/desktop " "--dest=org.freedesktop.portal.Desktop /org/freedesktop/portal/desktop "

View file

@ -4,7 +4,8 @@ from __future__ import annotations
import enum import enum
import re import re
from typing import Any, Callable, Optional, cast from collections.abc import Callable
from typing import Any, cast
import aqt import aqt
from anki.sync import SyncStatus from anki.sync import SyncStatus
@ -86,7 +87,7 @@ class TopWebView(ToolbarWebView):
self.show() self.show()
def _onHeight(self, qvar: Optional[int]) -> None: def _onHeight(self, qvar: int | None) -> None:
super()._onHeight(qvar) super()._onHeight(qvar)
if qvar: if qvar:
self.web_height = int(qvar) self.web_height = int(qvar)

View file

@ -9,9 +9,10 @@ import re
import shutil import shutil
import subprocess import subprocess
import sys import sys
from collections.abc import Sequence
from functools import partial, wraps from functools import partial, wraps
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence, Union from typing import TYPE_CHECKING, Any, Callable, Literal, Union
from send2trash import send2trash from send2trash import send2trash

View file

@ -7,8 +7,9 @@ import dataclasses
import json import json
import re import re
import sys import sys
from collections.abc import Sequence
from enum import Enum from enum import Enum
from typing import TYPE_CHECKING, Any, Callable, Optional, Sequence, cast from typing import TYPE_CHECKING, Any, Callable, cast
import anki import anki
import anki.lang import anki.lang
@ -524,10 +525,10 @@ html {{ {font} }}
def stdHtml( def stdHtml(
self, self,
body: str, body: str,
css: Optional[list[str]] = None, css: list[str] | None = None,
js: Optional[list[str]] = None, js: list[str] | None = None,
head: str = "", head: str = "",
context: Optional[Any] = None, context: Any | None = None,
default_css: bool = True, default_css: bool = True,
) -> None: ) -> None:
css = (["css/webview.css"] if default_css else []) + ( css = (["css/webview.css"] if default_css else []) + (
@ -705,7 +706,7 @@ html {{ {font} }}
def adjustHeightToFit(self) -> None: def adjustHeightToFit(self) -> None:
self.evalWithCallback("document.documentElement.offsetHeight", self._onHeight) self.evalWithCallback("document.documentElement.offsetHeight", self._onHeight)
def _onHeight(self, qvar: Optional[int]) -> None: def _onHeight(self, qvar: int | None) -> None:
from aqt import mw from aqt import mw
if qvar is None: if qvar is None:
@ -842,5 +843,5 @@ html {{ {font} }}
) )
@deprecated(info="use theme_manager.qcolor() instead") @deprecated(info="use theme_manager.qcolor() instead")
def get_window_bg_color(self, night_mode: Optional[bool] = None) -> QColor: def get_window_bg_color(self, night_mode: bool | None = None) -> QColor:
return theme_manager.qcolor(colors.CANVAS) return theme_manager.qcolor(colors.CANVAS)