mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Update type annotations to use |
operator (#3323)
* refactor: update to `|` operator * refactor: add missing type hint * refactor: enable `|` operator for older versions * refactor: remove obsolete import
This commit is contained in:
parent
f0933cf06c
commit
0743e6e40e
10 changed files with 36 additions and 30 deletions
|
@ -2,10 +2,11 @@
|
||||||
# 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
|
||||||
|
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from typing import Any, Optional
|
from typing import Any
|
||||||
|
|
||||||
from anki.cards import CardId
|
from anki.cards import CardId
|
||||||
from anki.collection import Collection
|
from anki.collection import Collection
|
||||||
|
@ -31,7 +32,7 @@ class MediaMapInvalid(Exception):
|
||||||
|
|
||||||
class Anki2Importer(Importer):
|
class Anki2Importer(Importer):
|
||||||
needMapper = False
|
needMapper = False
|
||||||
deckPrefix: Optional[str] = None
|
deckPrefix: str | None = None
|
||||||
allowUpdate = True
|
allowUpdate = True
|
||||||
src: Collection
|
src: Collection
|
||||||
dst: Collection
|
dst: Collection
|
||||||
|
@ -409,7 +410,7 @@ insert or ignore into revlog values (?,?,?,?,?,?,?,?,?)""",
|
||||||
if fname.startswith("_") and not self.dst.media.have(fname):
|
if fname.startswith("_") and not self.dst.media.have(fname):
|
||||||
self._writeDstMedia(fname, self._srcMediaData(fname))
|
self._writeDstMedia(fname, self._srcMediaData(fname))
|
||||||
|
|
||||||
def _mediaData(self, fname: str, dir: Optional[str] = None) -> bytes:
|
def _mediaData(self, fname: str, dir: str | None = None) -> bytes:
|
||||||
if not dir:
|
if not dir:
|
||||||
dir = self.src.media.dir()
|
dir = self.src.media.dir()
|
||||||
path = os.path.join(dir, fname)
|
path = os.path.join(dir, fname)
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
# 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
|
||||||
|
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import unicodedata
|
import unicodedata
|
||||||
import zipfile
|
import zipfile
|
||||||
from typing import Any, Optional
|
from typing import Any
|
||||||
|
|
||||||
from anki.importing.anki2 import Anki2Importer, MediaMapInvalid
|
from anki.importing.anki2 import Anki2Importer, MediaMapInvalid
|
||||||
from anki.utils import tmpfile
|
from anki.utils import tmpfile
|
||||||
|
@ -15,7 +16,7 @@ from anki.utils import tmpfile
|
||||||
|
|
||||||
class AnkiPackageImporter(Anki2Importer):
|
class AnkiPackageImporter(Anki2Importer):
|
||||||
nameToNum: dict[str, str]
|
nameToNum: dict[str, str]
|
||||||
zip: Optional[zipfile.ZipFile]
|
zip: zipfile.ZipFile | None
|
||||||
|
|
||||||
def run(self) -> None: # type: ignore
|
def run(self) -> None: # type: ignore
|
||||||
# extract the deck from the zip file
|
# extract the deck from the zip 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
|
||||||
|
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Any, Optional
|
from typing import Any
|
||||||
|
|
||||||
from anki.collection import Collection
|
from anki.collection import Collection
|
||||||
from anki.utils import max_id
|
from anki.utils import max_id
|
||||||
|
@ -15,7 +16,7 @@ from anki.utils import max_id
|
||||||
class Importer:
|
class Importer:
|
||||||
needMapper = False
|
needMapper = False
|
||||||
needDelimiter = False
|
needDelimiter = False
|
||||||
dst: Optional[Collection]
|
dst: Collection | None
|
||||||
|
|
||||||
def __init__(self, col: Collection, file: str) -> None:
|
def __init__(self, col: Collection, file: str) -> None:
|
||||||
self.file = file
|
self.file = file
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
# pytype: disable=attribute-error
|
# pytype: disable=attribute-error
|
||||||
# type: ignore
|
# type: ignore
|
||||||
# pylint: disable=C
|
# pylint: disable=C
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from string import capwords
|
from string import capwords
|
||||||
from typing import Optional, Union
|
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
from xml.dom.minidom import Element, Text
|
from xml.dom.minidom import Element, Text
|
||||||
|
|
||||||
|
@ -329,7 +329,7 @@ class SupermemoXmlImporter(NoteImporter):
|
||||||
self.logger("Load done.")
|
self.logger("Load done.")
|
||||||
|
|
||||||
# PARSE
|
# PARSE
|
||||||
def parse(self, node: Optional[Union[Text, Element]] = None) -> None:
|
def parse(self, node: Text | Element | None = None) -> None:
|
||||||
"Parse method - parses document elements"
|
"Parse method - parses document elements"
|
||||||
|
|
||||||
if node is None and self.xmldoc is not None:
|
if node is None and self.xmldoc is not None:
|
||||||
|
|
|
@ -5,12 +5,13 @@
|
||||||
Code for generating hooks.
|
Code for generating hooks.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
sys.path.append("pylib/anki/_vendor")
|
sys.path.append("pylib/anki/_vendor")
|
||||||
|
|
||||||
|
@ -23,19 +24,19 @@ class Hook:
|
||||||
name: str
|
name: str
|
||||||
# string of the typed arguments passed to the callback, eg
|
# string of the typed arguments passed to the callback, eg
|
||||||
# ["kind: str", "val: int"]
|
# ["kind: str", "val: int"]
|
||||||
args: list[str] = None
|
args: list[str] | None = None
|
||||||
# string of the return type. if set, hook is a filter.
|
# string of the return type. if set, hook is a filter.
|
||||||
return_type: Optional[str] = None
|
return_type: str | None = None
|
||||||
# if add-ons may be relying on the legacy hook name, add it here
|
# if add-ons may be relying on the legacy hook name, add it here
|
||||||
legacy_hook: Optional[str] = None
|
legacy_hook: str | None = None
|
||||||
# if legacy hook takes no arguments but the new hook does, set this
|
# if legacy hook takes no arguments but the new hook does, set this
|
||||||
legacy_no_args: bool = False
|
legacy_no_args: bool = False
|
||||||
# if the hook replaces a deprecated one, add its name here
|
# if the hook replaces a deprecated one, add its name here
|
||||||
replaces: Optional[str] = None
|
replaces: str | None = None
|
||||||
# arguments that the hook being replaced took
|
# arguments that the hook being replaced took
|
||||||
replaced_hook_args: Optional[list[str]] = None
|
replaced_hook_args: list[str] | None = None
|
||||||
# docstring to add to hook class
|
# docstring to add to hook class
|
||||||
doc: Optional[str] = None
|
doc: str | None = None
|
||||||
|
|
||||||
def callable(self) -> str:
|
def callable(self) -> str:
|
||||||
"Convert args into a Callable."
|
"Convert args into a Callable."
|
||||||
|
@ -47,7 +48,7 @@ class Hook:
|
||||||
types_str = ", ".join(types)
|
types_str = ", ".join(types)
|
||||||
return f"Callable[[{types_str}], {self.return_type or 'None'}]"
|
return f"Callable[[{types_str}], {self.return_type or 'None'}]"
|
||||||
|
|
||||||
def arg_names(self, args: Optional[list[str]]) -> list[str]:
|
def arg_names(self, args: list[str] | None) -> list[str]:
|
||||||
names = []
|
names = []
|
||||||
for arg in args or []:
|
for arg in args or []:
|
||||||
if not arg:
|
if not arg:
|
||||||
|
|
|
@ -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 __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
import aqt.editor
|
import aqt.editor
|
||||||
from anki.collection import OpChanges
|
from anki.collection import OpChanges
|
||||||
|
@ -38,7 +39,7 @@ class EditCurrent(QMainWindow):
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
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.note_text and handler is not self.editor:
|
if changes.note_text and handler is not self.editor:
|
||||||
# reload note
|
# reload note
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
# 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 __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import traceback
|
import traceback
|
||||||
import zipfile
|
import zipfile
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from concurrent.futures import Future
|
from concurrent.futures import Future
|
||||||
from typing import Any, Optional
|
from typing import Any
|
||||||
|
|
||||||
import anki.importing as importing
|
import anki.importing as importing
|
||||||
import aqt.deckchooser
|
import aqt.deckchooser
|
||||||
|
@ -55,7 +57,7 @@ class ChangeMap(QDialog):
|
||||||
self.frm.fields.setCurrentRow(n)
|
self.frm.fields.setCurrentRow(n)
|
||||||
else:
|
else:
|
||||||
self.frm.fields.setCurrentRow(n + 1)
|
self.frm.fields.setCurrentRow(n + 1)
|
||||||
self.field: Optional[str] = None
|
self.field: str | None = None
|
||||||
|
|
||||||
def getField(self) -> str:
|
def getField(self) -> str:
|
||||||
self.exec()
|
self.exec()
|
||||||
|
@ -231,13 +233,13 @@ class ImportDialog(QDialog):
|
||||||
self.frm.mappingArea.setWidget(self.frame)
|
self.frm.mappingArea.setWidget(self.frame)
|
||||||
self.mapbox = QVBoxLayout(self.frame)
|
self.mapbox = QVBoxLayout(self.frame)
|
||||||
self.mapbox.setContentsMargins(0, 0, 0, 0)
|
self.mapbox.setContentsMargins(0, 0, 0, 0)
|
||||||
self.mapwidget: Optional[QWidget] = None
|
self.mapwidget: QWidget | None = None
|
||||||
|
|
||||||
def hideMapping(self) -> None:
|
def hideMapping(self) -> None:
|
||||||
self.frm.mappingGroup.hide()
|
self.frm.mappingGroup.hide()
|
||||||
|
|
||||||
def showMapping(
|
def showMapping(
|
||||||
self, keepMapping: bool = False, hook: Optional[Callable] = None
|
self, keepMapping: bool = False, hook: Callable | None = None
|
||||||
) -> None:
|
) -> None:
|
||||||
if hook:
|
if hook:
|
||||||
hook()
|
hook()
|
||||||
|
|
|
@ -1,8 +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 __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from aqt import AnkiQt, gui_hooks
|
from aqt import AnkiQt, gui_hooks
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
|
@ -17,7 +17,7 @@ class ModelChooser(QHBoxLayout):
|
||||||
mw: AnkiQt,
|
mw: AnkiQt,
|
||||||
widget: QWidget,
|
widget: QWidget,
|
||||||
label: bool = True,
|
label: bool = True,
|
||||||
on_activated: Optional[Callable[[], None]] = None,
|
on_activated: Callable[[], None] | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""If provided, on_activated() will be called when the button is clicked,
|
"""If provided, on_activated() will be called when the button is clicked,
|
||||||
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
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
# pylint: disable=raise-missing-from
|
# pylint: disable=raise-missing-from
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
import json
|
import json
|
||||||
|
@ -38,7 +39,6 @@ import threading
|
||||||
import time
|
import time
|
||||||
from queue import Empty, Full, Queue
|
from queue import Empty, Full, Queue
|
||||||
from shutil import which
|
from shutil import which
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from anki.utils import is_win
|
from anki.utils import is_win
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ class MPVBase:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
executable = which("mpv")
|
executable = which("mpv")
|
||||||
popenEnv: Optional[dict[str, str]] = None
|
popenEnv: dict[str, str] | None = None
|
||||||
|
|
||||||
default_argv = [
|
default_argv = [
|
||||||
"--idle",
|
"--idle",
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
# make sure not to optimize imports on this file
|
# make sure not to optimize imports on this file
|
||||||
# pylint: disable=unused-import
|
# pylint: disable=unused-import
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -55,9 +56,7 @@ if qtmajor < 5 or (qtmajor == 5 and qtminor < 14):
|
||||||
raise Exception("Anki does not support your Qt version.")
|
raise Exception("Anki does not support your Qt version.")
|
||||||
|
|
||||||
|
|
||||||
def qconnect(
|
def qconnect(signal: Callable | pyqtSignal | pyqtBoundSignal, func: Callable) -> None:
|
||||||
signal: Union[Callable, pyqtSignal, pyqtBoundSignal], func: Callable
|
|
||||||
) -> None:
|
|
||||||
"""Helper to work around type checking not working with signal.connect(func)."""
|
"""Helper to work around type checking not working with signal.connect(func)."""
|
||||||
signal.connect(func) # type: ignore
|
signal.connect(func) # type: ignore
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue