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:
David Culley 2024-07-26 13:15:39 +02:00 committed by GitHub
parent f0933cf06c
commit 0743e6e40e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 36 additions and 30 deletions

View file

@ -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)

View file

@ -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

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
# 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

View 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:

View file

@ -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:

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 __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

View file

@ -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()

View file

@ -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

View file

@ -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",

View file

@ -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