From c1587254f446adf12971955c180c21bba479e866 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Fri, 20 Dec 2019 19:19:03 +1000 Subject: [PATCH] use isort to tidy up imports --- .isort.cfg | 2 ++ Makefile | 14 +++++++-- anki/__init__.py | 3 +- anki/cards.py | 8 +++--- anki/collection.py | 50 ++++++++++++++++----------------- anki/consts.py | 3 +- anki/db.py | 4 +-- anki/decks.py | 13 +++++---- anki/errors.py | 1 + anki/exporting.py | 26 ++++++++++------- anki/find.py | 6 ++-- anki/hooks.py | 3 +- anki/importing/__init__.py | 6 ++-- anki/importing/anki2.py | 9 +++--- anki/importing/apkg.py | 11 +++++--- anki/importing/base.py | 5 ++-- anki/importing/csvfile.py | 9 +++--- anki/importing/mnemo.py | 9 ++++-- anki/importing/noteimp.py | 16 +++++------ anki/importing/pauker.py | 9 ++++-- anki/importing/supermemo_xml.py | 17 +++++------ anki/lang.py | 4 ++- anki/latex.py | 10 +++++-- anki/media.py | 25 +++++++++-------- anki/models.py | 14 +++++---- anki/mpv.py | 23 ++++++++------- anki/notes.py | 9 +++--- anki/sched.py | 12 ++++---- anki/schedv2.py | 20 ++++++------- anki/sound.py | 17 +++++++---- anki/stats.py | 7 ++--- anki/stdmodels.py | 4 +-- anki/storage.py | 15 +++++----- anki/sync.py | 24 ++++++++-------- anki/tags.py | 7 +++-- anki/template/__init__.py | 4 ++- anki/template/furigana.py | 3 +- anki/template/hint.py | 1 + anki/template/template.py | 5 ++-- anki/template/view.py | 4 ++- anki/utils.py | 29 +++++++++---------- aqt/__init__.py | 26 ++++++++--------- aqt/about.py | 7 +++-- aqt/addcards.py | 21 +++++++------- aqt/addons.py | 29 ++++++++++--------- aqt/browser.py | 40 ++++++++++++-------------- aqt/clayout.py | 18 ++++++------ aqt/customstudy.py | 4 +-- aqt/deckbrowser.py | 15 +++++----- aqt/deckchooser.py | 5 ++-- aqt/deckconf.py | 9 +++--- aqt/downloader.py | 11 +++++--- aqt/dyndeckconf.py | 5 ++-- aqt/editcurrent.py | 7 ++--- aqt/editor.py | 34 +++++++++++----------- aqt/errors.py | 5 ++-- aqt/exporting.py | 13 +++++---- aqt/fields.py | 7 +++-- aqt/importing.py | 23 +++++++-------- aqt/main.py | 46 +++++++++++++++--------------- aqt/mediasrv.py | 15 +++++----- aqt/modelchooser.py | 5 ++-- aqt/models.py | 12 ++++---- aqt/overview.py | 5 ++-- aqt/pinnedmodules.py | 23 ++++++++------- aqt/preferences.py | 10 ++++--- aqt/profiles.py | 24 ++++++++-------- aqt/progress.py | 3 +- aqt/qt.py | 22 ++++++++------- aqt/reviewer.py | 17 ++++++----- aqt/sound.py | 8 +++--- aqt/stats.py | 9 +++--- aqt/studydeck.py | 6 ++-- aqt/sync.py | 14 ++++----- aqt/tagedit.py | 6 ++-- aqt/taglimit.py | 3 +- aqt/toolbar.py | 3 +- aqt/update.py | 7 +++-- aqt/utils.py | 14 +++++---- aqt/webview.py | 7 +++-- aqt/winpaths.py | 2 +- requirements.dev | 1 + 82 files changed, 545 insertions(+), 457 deletions(-) create mode 100644 .isort.cfg diff --git a/.isort.cfg b/.isort.cfg new file mode 100644 index 000000000..27c67f127 --- /dev/null +++ b/.isort.cfg @@ -0,0 +1,2 @@ +[settings] +skip=aqt/forms diff --git a/Makefile b/Makefile index 742deedd3..33bb783f0 100644 --- a/Makefile +++ b/Makefile @@ -108,7 +108,7 @@ run: build ###################### .PHONY: check -check: mypy pytest pylint pytype checkpretty +check: mypy pyimports pytest pylint pytype checkpretty # Checking python ###################### @@ -131,11 +131,21 @@ PYCHECKDEPS := $(BUILDDEPS) $(shell find anki aqt -name '*.py' | grep -v buildha pytype --config pytype.conf touch $@ -.PHONY: mypy pytest pylint pytype +.build/pyimports: $(PYCHECKDEPS) + isort -rc anki aqt --check # if this fails, run 'make fixpyimports' + touch $@ + +.PHONY: mypy pytest pylint pytype pyimports fixpyimports mypy: .build/mypy pytest: .build/pytest pylint: .build/pylint pytype: .build/pytype +pyimports: .build/pyimports + +.PHONY: fixpyimports + +fixpyimports: + isort -rc anki aqt # Checking typescript ###################### diff --git a/anki/__init__.py b/anki/__init__.py index 37f05c50c..9d705bf52 100644 --- a/anki/__init__.py +++ b/anki/__init__.py @@ -4,6 +4,8 @@ import sys +from anki.storage import Collection + if sys.version_info[0] < 3 or sys.version_info[1] < 5: raise Exception("Anki requires Python 3.5+") @@ -11,5 +13,4 @@ if sys.getfilesystemencoding().lower() in ("ascii", "ansi_x3.4-1968"): raise Exception("Anki requires a UTF-8 locale.") version="2.1.17" # build scripts grep this line, so preserve formatting -from anki.storage import Collection __all__ = ["Collection"] diff --git a/anki/cards.py b/anki/cards.py index 3affbdeb3..3198cc70c 100644 --- a/anki/cards.py +++ b/anki/cards.py @@ -2,13 +2,13 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import pprint - import time -from anki.hooks import runHook -from anki.utils import intTime, timestampID, joinFields +from typing import Any, Dict, Optional + from anki.consts import * +from anki.hooks import runHook from anki.notes import Note -from typing import Any, Optional, Dict +from anki.utils import intTime, joinFields, timestampID # Cards ########################################################################## diff --git a/anki/collection.py b/anki/collection.py index a27a412c7..a3fd21096 100644 --- a/anki/collection.py +++ b/anki/collection.py @@ -2,38 +2,40 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import pprint -import re -import time -import os -import random -import stat -import datetime import copy -import traceback +import datetime import json +import os +import pprint +import random +import re +import stat +import time +import traceback +from typing import Any, Dict, List, Optional, Tuple, Union -from anki.lang import _, ngettext -from anki.utils import ids2str, fieldChecksum, \ - intTime, splitFields, joinFields, maxID, devMode, stripHTMLMedia -from anki.hooks import runFilter, runHook -from anki.models import ModelManager -from anki.media import MediaManager -from anki.decks import DeckManager -from anki.tags import TagManager -from anki.consts import * -from anki.errors import AnkiError -from anki.sound import stripSounds -import anki.latex # sets up hook import anki.cards +import anki.find +import anki.latex # sets up hook import anki.notes import anki.template -import anki.find -from typing import Any, List, Optional, Tuple, Union, Dict - from anki.cards import Card +from anki.consts import * from anki.db import DB +from anki.decks import DeckManager +from anki.errors import AnkiError +from anki.hooks import runFilter, runHook +from anki.lang import _, ngettext +from anki.media import MediaManager +from anki.models import ModelManager from anki.notes import Note +from anki.sched import Scheduler as V1Scheduler +from anki.schedv2 import Scheduler as V2Scheduler +from anki.sound import stripSounds +from anki.tags import TagManager +from anki.utils import (devMode, fieldChecksum, ids2str, intTime, joinFields, + maxID, splitFields, stripHTMLMedia) + defaultConf = { # review options 'activeDecks': [1], @@ -59,8 +61,6 @@ def timezoneOffset() -> int: else: return time.timezone//60 -from anki.sched import Scheduler as V1Scheduler -from anki.schedv2 import Scheduler as V2Scheduler # this is initialized by storage.Collection class _Collection: db: Optional[DB] diff --git a/anki/consts.py b/anki/consts.py index f29683396..f1c44d20e 100644 --- a/anki/consts.py +++ b/anki/consts.py @@ -2,9 +2,10 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from anki.lang import _ from typing import Any, Dict +from anki.lang import _ + # whether new cards should be mixed with reviews, or shown first or last NEW_CARDS_DISTRIBUTE = 0 NEW_CARDS_LAST = 1 diff --git a/anki/db.py b/anki/db.py index 1fc3ef2be..c4ab5305b 100644 --- a/anki/db.py +++ b/anki/db.py @@ -4,8 +4,8 @@ import os import time - -from sqlite3 import dbapi2 as sqlite, Cursor +from sqlite3 import Cursor +from sqlite3 import dbapi2 as sqlite from typing import Any, List DBError = sqlite.Error diff --git a/anki/decks.py b/anki/decks.py index d8cc6cd6e..532065688 100644 --- a/anki/decks.py +++ b/anki/decks.py @@ -2,16 +2,17 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import copy, operator -import unicodedata +import copy import json +import operator +import unicodedata +from typing import Any, Dict, List, Optional, Set, Tuple, Union -from anki.utils import intTime, ids2str -from anki.hooks import runHook from anki.consts import * -from anki.lang import _ from anki.errors import DeckRenameError -from typing import Any, Dict, List, Optional, Tuple, Set, Union +from anki.hooks import runHook +from anki.lang import _ +from anki.utils import ids2str, intTime # fixmes: # - make sure users can't set grad interval < 1 diff --git a/anki/errors.py b/anki/errors.py index d283b159a..a60b7a5a0 100644 --- a/anki/errors.py +++ b/anki/errors.py @@ -1,4 +1,5 @@ from typing import Any + # -*- coding: utf-8 -*- # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html diff --git a/anki/exporting.py b/anki/exporting.py index b27a5bc24..749d24b6f 100644 --- a/anki/exporting.py +++ b/anki/exporting.py @@ -2,18 +2,24 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import re, os, zipfile, shutil, unicodedata -import json, typing - -from anki.lang import _ -from anki.utils import ids2str, splitFields, namedtmp, stripHTML -from anki.hooks import runHook -from anki.storage import Collection -from typing import Any, Dict, List, Tuple - +import json +import os +import re +import shutil +import typing +import unicodedata +import zipfile from io import BufferedWriter -from anki.collection import _Collection +from typing import Any, Dict, List, Tuple from zipfile import ZipFile + +from anki.collection import _Collection +from anki.hooks import runHook +from anki.lang import _ +from anki.storage import Collection +from anki.utils import ids2str, namedtmp, splitFields, stripHTML + + class Exporter: includeHTML: typing.Union[bool, None] = None diff --git a/anki/find.py b/anki/find.py index 5772c1ef3..ef31afa75 100644 --- a/anki/find.py +++ b/anki/find.py @@ -5,12 +5,12 @@ import re import sre_constants import unicodedata +from typing import Any, List, Optional, Set, Tuple -from anki.utils import ids2str, splitFields, joinFields, intTime, fieldChecksum, stripHTMLMedia from anki.consts import * from anki.hooks import * -from typing import Any, List, Optional, Tuple, Set - +from anki.utils import (fieldChecksum, ids2str, intTime, joinFields, + splitFields, stripHTMLMedia) # Find ########################################################################## diff --git a/anki/hooks.py b/anki/hooks.py index f94d67368..74d7bf3a5 100644 --- a/anki/hooks.py +++ b/anki/hooks.py @@ -13,8 +13,9 @@ If you call wrap() with pos='around', the original function will not be called automatically but can be called with _old(). """ +from typing import Any, Callable, Dict, List + import decorator -from typing import List, Any, Callable, Dict # Hooks ############################################################################## diff --git a/anki/importing/__init__.py b/anki/importing/__init__.py index ab390836c..597785a9c 100644 --- a/anki/importing/__init__.py +++ b/anki/importing/__init__.py @@ -2,12 +2,12 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from anki.importing.csvfile import TextImporter -from anki.importing.apkg import AnkiPackageImporter from anki.importing.anki2 import Anki2Importer -from anki.importing.supermemo_xml import SupermemoXmlImporter +from anki.importing.apkg import AnkiPackageImporter +from anki.importing.csvfile import TextImporter from anki.importing.mnemo import MnemosyneImporter from anki.importing.pauker import PaukerImporter +from anki.importing.supermemo_xml import SupermemoXmlImporter from anki.lang import _ Importers = ( diff --git a/anki/importing/anki2.py b/anki/importing/anki2.py index 773f00db4..3a019b41b 100644 --- a/anki/importing/anki2.py +++ b/anki/importing/anki2.py @@ -4,12 +4,13 @@ import os import unicodedata -from anki.storage import Collection -from anki.utils import intTime, splitFields, joinFields +from typing import Any, Dict, List, Optional, Tuple + +from anki.collection import _Collection from anki.importing.base import Importer from anki.lang import _ -from typing import Any, Optional, Dict, Tuple, List -from anki.collection import _Collection +from anki.storage import Collection +from anki.utils import intTime, joinFields, splitFields GUID = 1 MID = 2 diff --git a/anki/importing/apkg.py b/anki/importing/apkg.py index 63735bedf..e6f82d8e5 100644 --- a/anki/importing/apkg.py +++ b/anki/importing/apkg.py @@ -2,13 +2,16 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import zipfile, os -import unicodedata import json -from anki.utils import tmpfile -from anki.importing.anki2 import Anki2Importer +import os +import unicodedata +import zipfile from typing import Any, Dict, Optional +from anki.importing.anki2 import Anki2Importer +from anki.utils import tmpfile + + class AnkiPackageImporter(Anki2Importer): nameToNum: Dict[str, str] zip: Optional[zipfile.ZipFile] diff --git a/anki/importing/base.py b/anki/importing/base.py index 1159aabdd..8e38e8bcc 100644 --- a/anki/importing/base.py +++ b/anki/importing/base.py @@ -2,9 +2,10 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from anki.utils import maxID -from typing import Any, Optional, List +from typing import Any, List, Optional + from anki.collection import _Collection +from anki.utils import maxID # Base importer ########################################################################## diff --git a/anki/importing/csvfile.py b/anki/importing/csvfile.py index 79e8a3bc7..eb0cd5c56 100644 --- a/anki/importing/csvfile.py +++ b/anki/importing/csvfile.py @@ -4,12 +4,13 @@ import csv import re - -from anki.importing.noteimp import NoteImporter, ForeignNote -from anki.lang import _ -from typing import List, Optional, Any, TextIO, Union +from typing import Any, List, Optional, TextIO, Union from anki.collection import _Collection +from anki.importing.noteimp import ForeignNote, NoteImporter +from anki.lang import _ + + class TextImporter(NoteImporter): needDelimiter = True diff --git a/anki/importing/mnemo.py b/anki/importing/mnemo.py index 294253882..493a26502 100644 --- a/anki/importing/mnemo.py +++ b/anki/importing/mnemo.py @@ -2,11 +2,14 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import time, re +import re +import time + from anki.db import DB -from anki.importing.noteimp import NoteImporter, ForeignNote, ForeignCard +from anki.importing.noteimp import ForeignCard, ForeignNote, NoteImporter +from anki.lang import _, ngettext from anki.stdmodels import addBasicModel, addClozeModel -from anki.lang import ngettext, _ + class MnemosyneImporter(NoteImporter): diff --git a/anki/importing/noteimp.py b/anki/importing/noteimp.py index 9ea8ecaae..c14e78414 100644 --- a/anki/importing/noteimp.py +++ b/anki/importing/noteimp.py @@ -2,18 +2,16 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import html - +import html import unicodedata +from typing import Any, Dict, List, Optional, Tuple, Union -from anki.consts import NEW_CARDS_RANDOM, STARTING_FACTOR -from anki.lang import _ -from anki.utils import fieldChecksum, guid64, timestampID, \ - joinFields, intTime, splitFields -from anki.importing.base import Importer -from anki.lang import ngettext -from typing import Any, List, Optional, Tuple, Dict, Union from anki.collection import _Collection +from anki.consts import NEW_CARDS_RANDOM, STARTING_FACTOR +from anki.importing.base import Importer +from anki.lang import _, ngettext +from anki.utils import (fieldChecksum, guid64, intTime, joinFields, + splitFields, timestampID) # Stores a list of fields, tags and deck ###################################################################### diff --git a/anki/importing/pauker.py b/anki/importing/pauker.py index d13e4cade..3a86be742 100644 --- a/anki/importing/pauker.py +++ b/anki/importing/pauker.py @@ -2,9 +2,14 @@ # Copyright: Andreas Klauer # License: BSD-3 -import gzip, math, random, time, html +import gzip +import html +import math +import random +import time import xml.etree.ElementTree as ET -from anki.importing.noteimp import NoteImporter, ForeignNote, ForeignCard + +from anki.importing.noteimp import ForeignCard, ForeignNote, NoteImporter from anki.stdmodels import addForwardReverse ONE_DAY = 60*60*24 diff --git a/anki/importing/supermemo_xml.py b/anki/importing/supermemo_xml.py index e2d428725..f3c64cd4f 100644 --- a/anki/importing/supermemo_xml.py +++ b/anki/importing/supermemo_xml.py @@ -3,16 +3,17 @@ # License: GNU GPL, version 3 or later; http://www.gnu.org/licenses/agpl.html # pytype: disable=attribute-error +import re import sys - -from anki.stdmodels import addBasicModel -from anki.importing.noteimp import NoteImporter, ForeignNote, ForeignCard -from anki.lang import _ -from anki.lang import ngettext - -from xml.dom import minidom +import time +import unicodedata from string import capwords -import re, unicodedata, time +from xml.dom import minidom + +from anki.importing.noteimp import ForeignCard, ForeignNote, NoteImporter +from anki.lang import _, ngettext +from anki.stdmodels import addBasicModel + class SmartDict(dict): """ diff --git a/anki/lang.py b/anki/lang.py index 9715d644e..dfd43c758 100644 --- a/anki/lang.py +++ b/anki/lang.py @@ -2,8 +2,10 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import os, sys, re import gettext +import os +import re +import sys import threading from typing import Any diff --git a/anki/latex.py b/anki/latex.py index 41c1799a9..65da0c4e4 100644 --- a/anki/latex.py +++ b/anki/latex.py @@ -2,11 +2,15 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import re, os, shutil, html -from anki.utils import checksum, call, namedtmp, tmpdir, isMac, stripHTML +import html +import os +import re +import shutil +from typing import Any, Dict, List, Optional, Union + from anki.hooks import addHook from anki.lang import _ -from typing import Any, Dict, List, Optional, Union +from anki.utils import call, checksum, isMac, namedtmp, stripHTML, tmpdir pngCommands = [ ["latex", "-interaction=nonstopmode", "tmp.tex"], diff --git a/anki/media.py b/anki/media.py index 40ab7187f..13b9e8693 100644 --- a/anki/media.py +++ b/anki/media.py @@ -2,24 +2,25 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import io -import re -import traceback -import urllib.request, urllib.parse, urllib.error -import unicodedata -import sys -import zipfile -import pathlib import json import os +import pathlib +import re +import sys +import traceback +import unicodedata +import urllib.error +import urllib.parse +import urllib.request +import zipfile +from typing import Any, Callable, List, Optional, Tuple, Union -from anki.utils import checksum, isWin, isMac -from anki.db import DB, DBError from anki.consts import * -from anki.latex import mungeQA +from anki.db import DB, DBError from anki.lang import _ -from typing import Any, List, Optional, Tuple +from anki.latex import mungeQA +from anki.utils import checksum, isMac, isWin -from typing import Callable, Union class MediaManager: diff --git a/anki/models.py b/anki/models.py index a80298bbf..90d757a0b 100644 --- a/anki/models.py +++ b/anki/models.py @@ -2,14 +2,16 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import copy, re, json -from anki.utils import intTime, joinFields, splitFields, ids2str,\ - checksum -from anki.lang import _ +import copy +import json +import re +import time +from typing import Any, Callable, Dict, List, Optional, Tuple, Union + from anki.consts import * from anki.hooks import runHook -import time -from typing import Tuple, Union, Any, Callable, Dict, List, Optional +from anki.lang import _ +from anki.utils import checksum, ids2str, intTime, joinFields, splitFields # Models ########################################################################## diff --git a/anki/mpv.py b/anki/mpv.py index 1f23fa6f6..9f42df0ed 100644 --- a/anki/mpv.py +++ b/anki/mpv.py @@ -25,22 +25,23 @@ # # ------------------------------------------------------------------------------ -import sys -import os -import time +import inspect import json -import socket +import os import select +import socket +import subprocess +import sys import tempfile import threading -import subprocess -import inspect - -from distutils.spawn import find_executable # pylint: disable=import-error,no-name-in-module -from queue import Queue, Empty, Full - +import time +from distutils.spawn import \ + find_executable # pylint: disable=import-error,no-name-in-module +from queue import Empty, Full, Queue from typing import Dict, Optional +from anki.utils import isWin + class MPVError(Exception): pass @@ -57,7 +58,6 @@ class MPVCommandError(MPVError): class MPVTimeoutError(MPVError): pass -from anki.utils import isWin if isWin: # pylint: disable=import-error import win32file, win32pipe, pywintypes, winerror # pytype: disable=import-error @@ -569,4 +569,3 @@ class MPV(MPVBase): """Set the value of property `name`. """ return self.command("set_property", name, value) - diff --git a/anki/notes.py b/anki/notes.py index 2294ca810..1a515adcd 100644 --- a/anki/notes.py +++ b/anki/notes.py @@ -2,10 +2,11 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from anki.utils import fieldChecksum, intTime, \ - joinFields, splitFields, stripHTMLMedia, timestampID, guid64 -from typing import List, Tuple -from typing import Any, Optional +from typing import Any, List, Optional, Tuple + +from anki.utils import (fieldChecksum, guid64, intTime, joinFields, + splitFields, stripHTMLMedia, timestampID) + class Note: tags: List[str] diff --git a/anki/sched.py b/anki/sched.py index dcce7963f..48bbeca15 100644 --- a/anki/sched.py +++ b/anki/sched.py @@ -2,17 +2,17 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import time -import random import itertools -from operator import itemgetter +import random +import time from heapq import * +from operator import itemgetter -#from anki.cards import Card -from anki.utils import ids2str, intTime, fmtTimeSpan -from anki.lang import _ from anki.consts import * from anki.hooks import runHook +from anki.lang import _ +#from anki.cards import Card +from anki.utils import fmtTimeSpan, ids2str, intTime # queue types: 0=new/cram, 1=lrn, 2=rev, 3=day lrn, -1=suspended, -2=buried # revlog types: 0=lrn, 1=rev, 2=relrn, 3=cram diff --git a/anki/schedv2.py b/anki/schedv2.py index 591e19a73..0306e9a8b 100644 --- a/anki/schedv2.py +++ b/anki/schedv2.py @@ -2,17 +2,20 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import time -import random -import itertools -from operator import itemgetter -from heapq import * import datetime +import itertools +import random +import time +from heapq import * +from operator import itemgetter +#from anki.collection import _Collection +from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union -from anki.utils import ids2str, intTime, fmtTimeSpan -from anki.lang import _ +from anki.cards import Card from anki.consts import * from anki.hooks import runHook +from anki.lang import _ +from anki.utils import fmtTimeSpan, ids2str, intTime # card types: 0=new, 1=lrn, 2=rev, 3=relrn # queue types: 0=new, 1=(re)lrn, 2=rev, 3=day (re)lrn, @@ -21,9 +24,6 @@ from anki.hooks import runHook # positive revlog intervals are in days (rev), negative in seconds (lrn) # odue/odid store original due/did when cards moved to filtered deck -from anki.cards import Card -#from anki.collection import _Collection -from typing import Any, Callable, Dict, List, Optional, Union, Tuple, Set class Scheduler: diff --git a/anki/sound.py b/anki/sound.py index 7ff23b5fb..d14fcf861 100644 --- a/anki/sound.py +++ b/anki/sound.py @@ -2,15 +2,21 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +import atexit import html -import re, sys, threading, time, subprocess, os, atexit -import random -from typing import List, Tuple, Dict, Any -from typing import Callable, NoReturn, Optional +import os +import random +import re +import subprocess +import sys +import threading +import time +from typing import Any, Callable, Dict, List, NoReturn, Optional, Tuple from anki.hooks import addHook, runHook -from anki.utils import tmpdir, isWin, isMac, isLin from anki.lang import _ +from anki.mpv import MPV, MPVBase +from anki.utils import isLin, isMac, isWin, tmpdir # Shared utils ########################################################################## @@ -90,7 +96,6 @@ def retryWait(proc) -> Any: # MPV ########################################################################## -from anki.mpv import MPV, MPVBase _player: Optional[Callable[[Any], Any]] _queueEraser: Optional[Callable[[], Any]] diff --git a/anki/stats.py b/anki/stats.py index f5936e7b3..3bc6dfe44 100644 --- a/anki/stats.py +++ b/anki/stats.py @@ -2,14 +2,13 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import time import datetime import json +import time +from typing import Any, Dict, List, Optional, Tuple -from anki.utils import fmtTimeSpan, ids2str from anki.lang import _, ngettext -from typing import Any, List, Tuple, Optional, Dict - +from anki.utils import fmtTimeSpan, ids2str # Card stats ########################################################################## diff --git a/anki/stdmodels.py b/anki/stdmodels.py index c96413a73..cd8ac6e47 100644 --- a/anki/stdmodels.py +++ b/anki/stdmodels.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from typing import Dict, Any +from typing import Any, Dict -from anki.lang import _ from anki.consts import MODEL_CLOZE +from anki.lang import _ models = [] diff --git a/anki/storage.py b/anki/storage.py index 478f9a840..7e6b6427a 100644 --- a/anki/storage.py +++ b/anki/storage.py @@ -3,18 +3,19 @@ # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import copy -import re import json import os +import re +from typing import Any, Dict, Tuple -from anki.lang import _ -from anki.utils import intTime, isWin -from anki.db import DB from anki.collection import _Collection from anki.consts import * -from anki.stdmodels import addBasicModel, addClozeModel, addForwardReverse, \ - addForwardOptionalReverse, addBasicTypingModel -from typing import Any, Dict, Tuple +from anki.db import DB +from anki.lang import _ +from anki.stdmodels import (addBasicModel, addBasicTypingModel, addClozeModel, + addForwardOptionalReverse, addForwardReverse) +from anki.utils import intTime, isWin + def Collection(path: str, lock: bool = True, server: bool = False, log: bool = False) -> _Collection: "Open a new or existing collection. Path must be unicode." diff --git a/anki/sync.py b/anki/sync.py index 83bf8b6b0..2440b49d7 100644 --- a/anki/sync.py +++ b/anki/sync.py @@ -2,23 +2,25 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import io import gzip -import random -import requests +import io import json import os +import random import sqlite3 - -from anki.db import DB, DBError -from anki.utils import ids2str, intTime, platDesc, checksum, devMode -from anki.consts import * -from anki.utils import versionWithBuild -from .hooks import runHook -import anki -from .lang import ngettext from typing import Any, Dict, List, Optional, Tuple, Union +import requests + +import anki +from anki.consts import * +from anki.db import DB, DBError +from anki.utils import (checksum, devMode, ids2str, intTime, platDesc, + versionWithBuild) + +from .hooks import runHook +from .lang import ngettext + # syncing vars HTTP_TIMEOUT = 90 HTTP_BUF_SIZE = 64*1024 diff --git a/anki/tags.py b/anki/tags.py index 93eb7c43e..373dc4d20 100644 --- a/anki/tags.py +++ b/anki/tags.py @@ -11,10 +11,11 @@ This module manages the tag cache and tags for notes. """ import json -from anki.utils import intTime, ids2str -from anki.hooks import runHook import re -from typing import Any, List, Tuple, Callable, Dict +from typing import Any, Callable, Dict, List, Tuple + +from anki.hooks import runHook +from anki.utils import ids2str, intTime class TagManager: diff --git a/anki/template/__init__.py b/anki/template/__init__.py index afb92d515..2c9dca894 100644 --- a/anki/template/__init__.py +++ b/anki/template/__init__.py @@ -1,7 +1,9 @@ +from typing import Any + from .template import Template + from . import furigana; furigana.install() from . import hint; hint.install() -from typing import Any def render(template, context=None, **kwargs) -> Any: context = context and context.copy() or {} diff --git a/anki/template/furigana.py b/anki/template/furigana.py index bef895c1d..d8ed33cde 100644 --- a/anki/template/furigana.py +++ b/anki/template/furigana.py @@ -4,9 +4,10 @@ # Based off Kieran Clancy's initial implementation. import re -from anki.hooks import addHook from typing import Any, Callable +from anki.hooks import addHook + r = r' ?([^ >]+?)\[(.+?)\]' ruby = r'\1\2' diff --git a/anki/template/hint.py b/anki/template/hint.py index d2bfaf65a..ff02a7ca1 100644 --- a/anki/template/hint.py +++ b/anki/template/hint.py @@ -5,6 +5,7 @@ from anki.hooks import addHook from anki.lang import _ + def hint(txt, extra, context, tag, fullname) -> str: if not txt.strip(): return "" diff --git a/anki/template/template.py b/anki/template/template.py index a39afe573..e5f780df6 100644 --- a/anki/template/template.py +++ b/anki/template/template.py @@ -1,7 +1,8 @@ import re -from anki.utils import stripHTML, stripHTMLMedia +from typing import Any, Callable, Dict, Pattern + from anki.hooks import runFilter -from typing import Any, Callable, Pattern, Dict +from anki.utils import stripHTML, stripHTMLMedia clozeReg = r"(?si)\{\{(c)%s::(.*?)(::(.*?))?\}\}" diff --git a/anki/template/view.py b/anki/template/view.py index 1c3676767..7b36c14c8 100644 --- a/anki/template/view.py +++ b/anki/template/view.py @@ -1,8 +1,10 @@ -from .template import Template import os.path import re from typing import Any +from .template import Template + + class View: # Path where this view's template(s) live template_path = '.' diff --git a/anki/utils.py b/anki/utils.py index 4b47fa34d..bc37bf0fc 100644 --- a/anki/utils.py +++ b/anki/utils.py @@ -2,29 +2,28 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import re -import os -import random -import time +# some add-ons expect json to be in the utils module +import json # pylint: disable=unused-import +import locale import math -from html.entities import name2codepoint -import subprocess -import tempfile +import os +import platform +import random +import re import shutil import string +import subprocess import sys -import locale -from hashlib import sha1 -import platform +import tempfile +import time import traceback from contextlib import contextmanager -from anki.lang import _, ngettext - -# some add-ons expect json to be in the utils module -import json # pylint: disable=unused-import +from hashlib import sha1 +from html.entities import name2codepoint +from typing import Any, Iterator, List, Optional, Tuple, Union from anki.db import DB -from typing import Any, Iterator, List, Union, Optional, Tuple +from anki.lang import _, ngettext _tmpdir: Optional[str] diff --git a/aqt/__init__.py b/aqt/__init__.py index 5aacc26d9..d581373c2 100644 --- a/aqt/__init__.py +++ b/aqt/__init__.py @@ -1,22 +1,21 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from anki import version as _version - -import getpass -import sys import argparse -import tempfile import builtins -import locale +import getpass import gettext -from typing import Optional, Any +import locale +import sys +import tempfile +from typing import Any, Optional -from aqt.qt import * import anki.lang +from anki import version as _version from anki.consts import HELP_SITE from anki.lang import langDir -from anki.utils import isMac, isLin +from anki.utils import checksum, isLin, isMac +from aqt.qt import * appVersion=_version appWebsite="http://ankisrs.net/" @@ -26,8 +25,8 @@ appShared="https://ankiweb.net/shared/" appUpdate="https://ankiweb.net/update/desktop" appHelpSite=HELP_SITE -from aqt.main import AnkiQt -from aqt.profiles import ProfileManager +from aqt.main import AnkiQt # isort:skip +from aqt.profiles import ProfileManager # isort:skip mw: Optional[AnkiQt] = None # set on init @@ -41,7 +40,6 @@ except ImportError as e: print() raise -from anki.utils import checksum # Dialog manager ########################################################################## @@ -59,8 +57,8 @@ from anki.utils import checksum #- make preferences modal? cmd+q does wrong thing -from aqt import addcards, browser, editcurrent, stats, about, \ - preferences +from aqt import addcards, browser, editcurrent # isort:skip +from aqt import stats, about, preferences # isort:skip class DialogManager: diff --git a/aqt/about.py b/aqt/about.py index 6d131a41e..01adc8cd1 100644 --- a/aqt/about.py +++ b/aqt/about.py @@ -2,11 +2,12 @@ # -*- coding: utf-8 -*- # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from aqt.qt import * import aqt.forms -from anki.utils import versionWithBuild -from aqt.utils import supportText, tooltip from anki.lang import _ +from anki.utils import versionWithBuild +from aqt.qt import * +from aqt.utils import supportText, tooltip + class ClosableQDialog(QDialog): def reject(self): diff --git a/aqt/addcards.py b/aqt/addcards.py index 7d8af1f5a..3c5abc170 100644 --- a/aqt/addcards.py +++ b/aqt/addcards.py @@ -1,21 +1,22 @@ # Copyright: Ankitects Pty Ltd and contributors # -*- coding: utf-8 -*- # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from typing import List +from typing import Callable, List +import aqt.deckchooser +import aqt.editor +import aqt.forms +import aqt.modelchooser +from anki.hooks import addHook, remHook, runHook from anki.lang import _ +from anki.notes import Note +from anki.sound import clearAudioQueue +from anki.utils import htmlToTextLine, isMac from aqt import AnkiQt from aqt.qt import * -import aqt.forms -from aqt.utils import saveGeom, restoreGeom, showWarning, askUser, shortcut, \ - tooltip, openHelp, addCloseShortcut, downArrow -from anki.sound import clearAudioQueue -from anki.hooks import addHook, remHook, runHook -from anki.utils import htmlToTextLine, isMac -import aqt.editor, aqt.modelchooser, aqt.deckchooser +from aqt.utils import (addCloseShortcut, askUser, downArrow, openHelp, + restoreGeom, saveGeom, shortcut, showWarning, tooltip) -from anki.notes import Note -from typing import Callable class AddCards(QDialog): diff --git a/aqt/addons.py b/aqt/addons.py index 4df7bbf3b..4af79fee1 100644 --- a/aqt/addons.py +++ b/aqt/addons.py @@ -6,24 +6,25 @@ import json import re import zipfile from collections import defaultdict -from typing import Callable, Dict, Any - -import markdown -from send2trash import send2trash -import jsonschema -from jsonschema.exceptions import ValidationError - -from aqt.qt import * -from aqt.utils import showInfo, openFolder, isWin, openLink, \ - askUser, restoreGeom, saveGeom, restoreSplitter, saveSplitter, \ - showWarning, tooltip, getFile +from typing import Any, Callable, Dict from zipfile import ZipFile -import aqt.forms + +import jsonschema +import markdown +from jsonschema.exceptions import ValidationError +from send2trash import send2trash + import aqt -from aqt.downloader import download +import aqt.forms from anki.lang import _, ngettext -from anki.utils import intTime from anki.sync import AnkiRequestsClient +from anki.utils import intTime +from aqt.downloader import download +from aqt.qt import * +from aqt.utils import (askUser, getFile, isWin, openFolder, openLink, + restoreGeom, restoreSplitter, saveGeom, saveSplitter, + showInfo, showWarning, tooltip) + class AddonManager: diff --git a/aqt/browser.py b/aqt/browser.py index 8af829962..69803d77b 100644 --- a/aqt/browser.py +++ b/aqt/browser.py @@ -2,35 +2,32 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import sre_constants import html -import time +import json import re +import sre_constants +import time import unicodedata -from operator import itemgetter +from operator import itemgetter from typing import Callable, List, Optional -from anki.collection import _Collection -from anki.lang import ngettext -import json - -from aqt import AnkiQt -from aqt.qt import * import anki import aqt.forms -from anki.utils import fmtTimeSpan, ids2str, htmlToTextLine, \ - isWin, intTime, \ - isMac, bodyClass -from aqt.utils import saveGeom, restoreGeom, saveSplitter, restoreSplitter, \ - saveHeader, restoreHeader, saveState, restoreState, getTag, \ - showInfo, askUser, tooltip, openHelp, showWarning, shortcut, mungeQA, \ - getOnlyText, MenuList, SubMenu, qtMenuShortcutWorkaround -from anki.lang import _ -from anki.hooks import runHook, addHook, remHook, runFilter -from aqt.webview import AnkiWebView +from anki.collection import _Collection from anki.consts import * -from anki.sound import clearAudioQueue, allSounds, play - +from anki.hooks import addHook, remHook, runFilter, runHook +from anki.lang import _, ngettext +from anki.sound import allSounds, clearAudioQueue, play +from anki.utils import (bodyClass, fmtTimeSpan, htmlToTextLine, ids2str, + intTime, isMac, isWin) +from aqt import AnkiQt +from aqt.qt import * +from aqt.utils import (MenuList, SubMenu, askUser, getOnlyText, getTag, + mungeQA, openHelp, qtMenuShortcutWorkaround, + restoreGeom, restoreHeader, restoreSplitter, + restoreState, saveGeom, saveHeader, saveSplitter, + saveState, shortcut, showInfo, showWarning, tooltip) +from aqt.webview import AnkiWebView # Data model ########################################################################## @@ -2264,4 +2261,3 @@ Are you sure you want to continue?""")): def onHelp(self): openHelp("browsermisc") - diff --git a/aqt/clayout.py b/aqt/clayout.py index ea198d763..799f1c174 100644 --- a/aqt/clayout.py +++ b/aqt/clayout.py @@ -3,20 +3,20 @@ # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import collections +import json import re -from aqt.qt import * -from anki.consts import * import aqt -from anki.sound import playFromText, clearAudioQueue -from aqt.utils import saveGeom, restoreGeom, mungeQA,\ - showInfo, askUser, getOnlyText, \ - showWarning, openHelp, downArrow -from anki.utils import isMac, isWin, joinFields, bodyClass -from aqt.webview import AnkiWebView -import json +from anki.consts import * from anki.hooks import runFilter from anki.lang import _, ngettext +from anki.sound import clearAudioQueue, playFromText +from anki.utils import bodyClass, isMac, isWin, joinFields +from aqt.qt import * +from aqt.utils import (askUser, downArrow, getOnlyText, mungeQA, openHelp, + restoreGeom, saveGeom, showInfo, showWarning) +from aqt.webview import AnkiWebView + class CardLayout(QDialog): diff --git a/aqt/customstudy.py b/aqt/customstudy.py index 5dc08f5be..23a1ade05 100644 --- a/aqt/customstudy.py +++ b/aqt/customstudy.py @@ -2,11 +2,11 @@ # -*- coding: utf-8 -*- # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from aqt.qt import * import aqt -from aqt.utils import showInfo, showWarning from anki.consts import * from anki.lang import _ +from aqt.qt import * +from aqt.utils import showInfo, showWarning RADIO_NEW = 1 RADIO_REV = 2 diff --git a/aqt/deckbrowser.py b/aqt/deckbrowser.py index 4223b5aa8..cdc3c4fe8 100644 --- a/aqt/deckbrowser.py +++ b/aqt/deckbrowser.py @@ -1,18 +1,19 @@ # Copyright: Ankitects Pty Ltd and contributors # -*- coding: utf-8 -*- # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +from copy import deepcopy from typing import Any -from aqt.qt import * -from aqt.utils import askUser, getOnlyText, openLink, showWarning, shortcut, \ - openHelp -from anki.utils import ids2str, fmtTimeSpan -from anki.errors import DeckRenameError import aqt -from anki.sound import clearAudioQueue +from anki.errors import DeckRenameError from anki.hooks import runHook -from copy import deepcopy from anki.lang import _, ngettext +from anki.sound import clearAudioQueue +from anki.utils import fmtTimeSpan, ids2str +from aqt.qt import * +from aqt.utils import (askUser, getOnlyText, openHelp, openLink, shortcut, + showWarning) + class DeckBrowser: _dueTree: Any diff --git a/aqt/deckchooser.py b/aqt/deckchooser.py index 4aa5739de..92568e721 100644 --- a/aqt/deckchooser.py +++ b/aqt/deckchooser.py @@ -2,10 +2,11 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from aqt.qt import * from anki.hooks import addHook, remHook -from aqt.utils import shortcut from anki.lang import _ +from aqt.qt import * +from aqt.utils import shortcut + class DeckChooser(QHBoxLayout): diff --git a/aqt/deckconf.py b/aqt/deckconf.py index dcad9b971..5497b7ea8 100644 --- a/aqt/deckconf.py +++ b/aqt/deckconf.py @@ -3,12 +3,13 @@ # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html from operator import itemgetter -from anki.consts import NEW_CARDS_RANDOM -from aqt.qt import * import aqt -from aqt.utils import showInfo, showWarning, openHelp, getOnlyText, askUser, \ - tooltip, saveGeom, restoreGeom +from anki.consts import NEW_CARDS_RANDOM from anki.lang import _, ngettext +from aqt.qt import * +from aqt.utils import (askUser, getOnlyText, openHelp, restoreGeom, saveGeom, + showInfo, showWarning, tooltip) + class DeckConf(QDialog): def __init__(self, mw, deck): diff --git a/aqt/downloader.py b/aqt/downloader.py index 37127bc10..4a29b770e 100644 --- a/aqt/downloader.py +++ b/aqt/downloader.py @@ -2,12 +2,15 @@ # -*- coding: utf-8 -*- # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import time, re -from aqt.qt import * -from anki.sync import AnkiRequestsClient -from anki.hooks import addHook, remHook +import re +import time + import aqt +from anki.hooks import addHook, remHook from anki.lang import _ +from anki.sync import AnkiRequestsClient +from aqt.qt import * + def download(mw, code): "Download addon from AnkiWeb. Caller must start & stop progress diag." diff --git a/aqt/dyndeckconf.py b/aqt/dyndeckconf.py index 36abeb2c2..6fa5a76d5 100644 --- a/aqt/dyndeckconf.py +++ b/aqt/dyndeckconf.py @@ -2,10 +2,11 @@ # -*- coding: utf-8 -*- # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from aqt.qt import * import aqt -from aqt.utils import showWarning, openHelp, askUser, saveGeom, restoreGeom from anki.lang import _ +from aqt.qt import * +from aqt.utils import askUser, openHelp, restoreGeom, saveGeom, showWarning + class DeckConf(QDialog): def __init__(self, mw, first=False, search="", deck=None): diff --git a/aqt/editcurrent.py b/aqt/editcurrent.py index 79377d689..b591f328e 100644 --- a/aqt/editcurrent.py +++ b/aqt/editcurrent.py @@ -2,13 +2,12 @@ # -*- coding: utf-8 -*- # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from aqt.qt import * -from aqt.utils import tooltip import aqt.editor -from aqt.utils import saveGeom, restoreGeom from anki.hooks import addHook, remHook -from anki.utils import isMac from anki.lang import _ +from aqt.qt import * +from aqt.utils import restoreGeom, saveGeom, tooltip + class EditCurrent(QDialog): diff --git a/aqt/editor.py b/aqt/editor.py index a333b373c..1c14ec23e 100644 --- a/aqt/editor.py +++ b/aqt/editor.py @@ -1,30 +1,32 @@ # -*- coding: utf-8 -*- # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import re -import urllib.request, urllib.parse, urllib.error -import warnings -import html -import mimetypes import base64 -import unicodedata +import html import json +import mimetypes +import re +import unicodedata +import urllib.error +import urllib.parse +import urllib.request +import warnings +import requests +from bs4 import BeautifulSoup + +import anki.sound +import aqt +from anki.hooks import addHook, runFilter, runHook from anki.lang import _ +from anki.sync import AnkiRequestsClient +from anki.utils import checksum, isWin, namedtmp, stripHTMLMedia from aqt import AnkiQt from aqt.qt import * -from anki.utils import isWin, namedtmp, stripHTMLMedia, \ - checksum -import anki.sound -from anki.hooks import runHook, runFilter, addHook from aqt.sound import getAudio +from aqt.utils import (getFile, openHelp, qtMenuShortcutWorkaround, shortcut, + showInfo, showWarning, tooltip) from aqt.webview import AnkiWebView -from aqt.utils import shortcut, showInfo, showWarning, getFile, \ - openHelp, tooltip, qtMenuShortcutWorkaround -import aqt -from bs4 import BeautifulSoup -import requests -from anki.sync import AnkiRequestsClient pics = ("jpg", "jpeg", "png", "tif", "tiff", "gif", "svg", "webp") audio = ("wav", "mp3", "ogg", "flac", "mp4", "swf", "mov", "mpeg", "mkv", "m4a", "3gp", "spx", "oga", "webm") diff --git a/aqt/errors.py b/aqt/errors.py index 142fe019c..9657145c8 100644 --- a/aqt/errors.py +++ b/aqt/errors.py @@ -1,14 +1,15 @@ # Copyright: Ankitects Pty Ltd and contributors # -*- coding: utf-8 -*- # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import sys, traceback import html import re +import sys +import traceback from anki.lang import _ +from aqt import mw from aqt.qt import * from aqt.utils import showText, showWarning, supportText -from aqt import mw if not os.environ.get("DEBUG"): def excepthook(etype,val,tb): diff --git a/aqt/exporting.py b/aqt/exporting.py index fd9612f2b..18ed94472 100644 --- a/aqt/exporting.py +++ b/aqt/exporting.py @@ -3,15 +3,16 @@ import os import re +import time -from aqt.qt import * -import aqt -from aqt.utils import getSaveFile, tooltip, showWarning, \ - checkInvalidFilename, showInfo +import aqt from anki.exporting import exporters from anki.hooks import addHook, remHook -from anki.lang import ngettext, _ -import time +from anki.lang import _, ngettext +from aqt.qt import * +from aqt.utils import (checkInvalidFilename, getSaveFile, showInfo, + showWarning, tooltip) + class ExportDialog(QDialog): diff --git a/aqt/fields.py b/aqt/fields.py index 55362d9fa..7d308e84d 100644 --- a/aqt/fields.py +++ b/aqt/fields.py @@ -1,11 +1,12 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from aqt.qt import * -from anki.consts import * import aqt -from aqt.utils import showWarning, openHelp, getOnlyText, askUser +from anki.consts import * from anki.lang import _, ngettext +from aqt.qt import * +from aqt.utils import askUser, getOnlyText, openHelp, showWarning + class FieldDialog(QDialog): diff --git a/aqt/importing.py b/aqt/importing.py index 6d47138fd..5da5e8fa4 100644 --- a/aqt/importing.py +++ b/aqt/importing.py @@ -2,24 +2,25 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +import json import os import re -import traceback -import zipfile -import json -import unicodedata import shutil +import traceback +import unicodedata +import zipfile -from aqt import AnkiQt -from aqt.qt import * import anki.importing as importing -from aqt.utils import getOnlyText, getFile, showText, showWarning, openHelp, \ - askUser, tooltip, showInfo -from anki.hooks import addHook, remHook +import aqt.deckchooser import aqt.forms import aqt.modelchooser -import aqt.deckchooser -from anki.lang import ngettext, _ +from anki.hooks import addHook, remHook +from anki.lang import _, ngettext +from aqt import AnkiQt +from aqt.qt import * +from aqt.utils import (askUser, getFile, getOnlyText, openHelp, showInfo, + showText, showWarning, tooltip) + class ChangeMap(QDialog): def __init__(self, mw: AnkiQt, model, current): diff --git a/aqt/main.py b/aqt/main.py index 53a611359..1d98c046d 100644 --- a/aqt/main.py +++ b/aqt/main.py @@ -2,39 +2,39 @@ # -*- coding: utf-8 -*- # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +import faulthandler +import gc +import platform import re import signal -import zipfile -import gc import time -import faulthandler -import platform +import zipfile +from argparse import Namespace from threading import Thread -from typing import Sequence +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple + from send2trash import send2trash + +import anki.mpv +import anki.sound +import aqt +import aqt.mediasrv +import aqt.progress +import aqt.stats +import aqt.toolbar +import aqt.webview from anki.collection import _Collection +from anki.hooks import addHook, runFilter, runHook +from anki.lang import _, ngettext +from anki.storage import Collection +from anki.utils import devMode, ids2str, intTime, isMac, isWin, splitFields from aqt.profiles import ProfileManager as ProfileManagerType from aqt.qt import * -from anki.storage import Collection -from anki.utils import isWin, isMac, intTime, splitFields, ids2str, \ - devMode -from anki.hooks import runHook, addHook, runFilter -import aqt -import aqt.progress -import aqt.webview -import aqt.toolbar -import aqt.stats -import aqt.mediasrv -import anki.sound -import anki.mpv -from aqt.utils import saveGeom, restoreGeom, showInfo, showWarning, \ - restoreState, getOnlyText, askUser, showText, tooltip, \ - openHelp, openLink, checkInvalidFilename, getFile from aqt.qt import sip -from anki.lang import _, ngettext +from aqt.utils import (askUser, checkInvalidFilename, getFile, getOnlyText, + openHelp, openLink, restoreGeom, restoreState, saveGeom, + showInfo, showText, showWarning, tooltip) -from argparse import Namespace -from typing import Any, Callable, Dict, List, Optional, Tuple class AnkiQt(QMainWindow): col: _Collection diff --git a/aqt/mediasrv.py b/aqt/mediasrv.py index 8242ac574..498680d48 100644 --- a/aqt/mediasrv.py +++ b/aqt/mediasrv.py @@ -1,17 +1,18 @@ # Copyright: Ankitects Pty Ltd and contributors # -*- coding: utf-8 -*- # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +import http.server +import re +import socket +import socketserver +import threading +from http import HTTPStatus from typing import Optional from anki.collection import _Collection -from aqt.qt import * -from http import HTTPStatus -import http.server -import socketserver -import socket from anki.utils import devMode -import threading -import re +from aqt.qt import * + # locate web folder in source/binary distribution def _getExportFolder(): diff --git a/aqt/modelchooser.py b/aqt/modelchooser.py index 2eeae55cb..dbd9f389c 100644 --- a/aqt/modelchooser.py +++ b/aqt/modelchooser.py @@ -2,10 +2,11 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from aqt.qt import * from anki.hooks import addHook, remHook, runHook -from aqt.utils import shortcut from anki.lang import _ +from aqt.qt import * +from aqt.utils import shortcut + class ModelChooser(QHBoxLayout): diff --git a/aqt/models.py b/aqt/models.py index eeba72b43..75fe063b1 100644 --- a/aqt/models.py +++ b/aqt/models.py @@ -1,14 +1,16 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from aqt import AnkiQt -from aqt.qt import * +import collections from operator import itemgetter -from aqt.utils import showInfo, askUser, getText, maybeHideClose, openHelp + import aqt.clayout from anki import stdmodels -from aqt.utils import saveGeom, restoreGeom -import collections from anki.lang import _, ngettext +from aqt import AnkiQt +from aqt.qt import * +from aqt.utils import (askUser, getText, maybeHideClose, openHelp, restoreGeom, + saveGeom, showInfo) + class Models(QDialog): def __init__(self, mw: AnkiQt, parent=None, fromMain=False): diff --git a/aqt/overview.py b/aqt/overview.py index 12c5cd6ae..df8fb2602 100644 --- a/aqt/overview.py +++ b/aqt/overview.py @@ -2,10 +2,11 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from aqt.utils import openLink, shortcut, tooltip, askUserDialog import aqt -from anki.sound import clearAudioQueue from anki.lang import _ +from anki.sound import clearAudioQueue +from aqt.utils import askUserDialog, openLink, shortcut, tooltip + class Overview: "Deck overview." diff --git a/aqt/pinnedmodules.py b/aqt/pinnedmodules.py index 545202183..40c1ba4e8 100644 --- a/aqt/pinnedmodules.py +++ b/aqt/pinnedmodules.py @@ -6,8 +6,19 @@ # pylint: disable=import-error,unused-import +# included implicitly in the past, and relied upon by some add-ons +import cgi +import decimal +# useful for add-ons +import logging +import logging.config +import logging.handlers # required by requests library import queue +import typing +import uuid + +import PyQt5.QtSvg from anki.utils import isWin @@ -16,15 +27,3 @@ if isWin: import pythoncom import win32com import pywintypes - -# included implicitly in the past, and relied upon by some add-ons -import cgi -import uuid -import decimal -import PyQt5.QtSvg - -# useful for add-ons -import logging -import logging.handlers -import logging.config -import typing diff --git a/aqt/preferences.py b/aqt/preferences.py index 96f888739..06458f91d 100644 --- a/aqt/preferences.py +++ b/aqt/preferences.py @@ -2,14 +2,16 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import datetime, time +import datetime +import time -from aqt import AnkiQt -from aqt.qt import * import anki.lang -from aqt.utils import openHelp, showInfo, askUser import aqt from anki.lang import _ +from aqt import AnkiQt +from aqt.qt import * +from aqt.utils import askUser, openHelp, showInfo + class Preferences(QDialog): diff --git a/aqt/profiles.py b/aqt/profiles.py index 1505b1f0c..5fcb8e28c 100644 --- a/aqt/profiles.py +++ b/aqt/profiles.py @@ -6,24 +6,24 @@ # - Saves in pickles rather than json to easily store Qt window state. # - Saves in sqlite rather than a flat file so the config can't be corrupted -import random -import pickle -import shutil import io import locale +import pickle +import random +import shutil +from typing import Any, Dict -from typing import Dict, Any - -from aqt.qt import * -from anki.db import DB -from anki.utils import isMac, isWin, intTime -import anki.lang -from aqt.utils import showWarning -from aqt import appHelpSite -import aqt.forms from send2trash import send2trash + +import anki.lang import anki.sound +import aqt.forms +from anki.db import DB from anki.lang import _ +from anki.utils import intTime, isMac, isWin +from aqt import appHelpSite +from aqt.qt import * +from aqt.utils import showWarning metaConf = dict( ver=0, diff --git a/aqt/progress.py b/aqt/progress.py index 3e3bf823d..1fa687e6f 100644 --- a/aqt/progress.py +++ b/aqt/progress.py @@ -3,9 +3,10 @@ # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import time -from aqt.qt import * + import aqt.forms from anki.lang import _ +from aqt.qt import * # fixme: if mw->subwindow opens a progress dialog with mw as the parent, mw # gets raised on finish on compiz. perhaps we should be using the progress diff --git a/aqt/qt.py b/aqt/qt.py index 815200a10..3d80f7f69 100644 --- a/aqt/qt.py +++ b/aqt/qt.py @@ -5,32 +5,34 @@ # pylint: disable=unused-import import os +import sys +import traceback + +from PyQt5.Qt import * # type: ignore +from PyQt5.QtCore import * +from PyQt5.QtCore import \ + pyqtRemoveInputHook # pylint: disable=no-name-in-module +from PyQt5.QtGui import * # type: ignore +from PyQt5.QtWebEngineWidgets import * # type: ignore +from PyQt5.QtWidgets import * + +from anki.utils import isMac, isWin # fix buggy ubuntu12.04 display of language selector os.environ["LIBOVERLAY_SCROLLBAR"] = "0" -from anki.utils import isWin, isMac -from PyQt5.QtCore import * -from PyQt5.QtWidgets import * -from PyQt5.QtGui import * # type: ignore -from PyQt5.Qt import * # type: ignore -# trigger explicit message in case of missing libraries -# instead of silently failing to import -from PyQt5.QtWebEngineWidgets import * # type: ignore try: from PyQt5 import sip except ImportError: import sip # type: ignore -from PyQt5.QtCore import pyqtRemoveInputHook # pylint: disable=no-name-in-module def debug(): from pdb import set_trace pyqtRemoveInputHook() set_trace() -import sys, traceback if os.environ.get("DEBUG"): def info(type, value, tb): diff --git a/aqt/reviewer.py b/aqt/reviewer.py index c47bff4e0..961e3d0ed 100644 --- a/aqt/reviewer.py +++ b/aqt/reviewer.py @@ -3,25 +3,24 @@ # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import difflib -import re import html -import unicodedata as ucd import html.parser import json - +import re +import unicodedata as ucd from typing import List +import aqt from anki.cards import Card +from anki.hooks import addHook, runFilter, runHook from anki.lang import _, ngettext +from anki.sound import clearAudioQueue, play, playFromText +from anki.utils import bodyClass, stripHTML from aqt import AnkiQt from aqt.qt import * -from anki.utils import stripHTML, bodyClass -from anki.hooks import addHook, runHook, runFilter -from anki.sound import playFromText, clearAudioQueue, play -from aqt.utils import mungeQA, tooltip, askUserDialog, \ - downArrow, qtMenuShortcutWorkaround from aqt.sound import getAudio -import aqt +from aqt.utils import (askUserDialog, downArrow, mungeQA, + qtMenuShortcutWorkaround, tooltip) class Reviewer: diff --git a/aqt/sound.py b/aqt/sound.py index 0bcf70cc6..b39e324ad 100644 --- a/aqt/sound.py +++ b/aqt/sound.py @@ -1,12 +1,12 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from aqt.qt import * - import time -from anki.sound import Recorder -from aqt.utils import saveGeom, restoreGeom, showWarning + from anki.lang import _ +from anki.sound import Recorder +from aqt.qt import * +from aqt.utils import restoreGeom, saveGeom, showWarning if not Recorder: print("pyaudio not installed") diff --git a/aqt/stats.py b/aqt/stats.py index f7856340c..f29ab4e9a 100644 --- a/aqt/stats.py +++ b/aqt/stats.py @@ -2,12 +2,13 @@ # -*- coding: utf-8 -*- # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from aqt.qt import * -import os, time -from aqt.utils import saveGeom, restoreGeom, maybeHideClose, addCloseShortcut, \ - tooltip, getSaveFile +import time + import aqt from anki.lang import _ +from aqt.qt import * +from aqt.utils import (addCloseShortcut, getSaveFile, maybeHideClose, + restoreGeom, saveGeom, tooltip) # Deck Stats ###################################################################### diff --git a/aqt/studydeck.py b/aqt/studydeck.py index f7d0bbb36..1cb53c9a2 100644 --- a/aqt/studydeck.py +++ b/aqt/studydeck.py @@ -2,11 +2,13 @@ # -*- coding: utf-8 -*- # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from aqt.qt import * import aqt -from aqt.utils import showInfo, openHelp, getOnlyText, shortcut, restoreGeom, saveGeom from anki.hooks import addHook, remHook from anki.lang import _ +from aqt.qt import * +from aqt.utils import (getOnlyText, openHelp, restoreGeom, saveGeom, shortcut, + showInfo) + class StudyDeck(QDialog): def __init__(self, mw, names=None, accept=None, title=None, diff --git a/aqt/sync.py b/aqt/sync.py index c2a7e74c7..b8af783e6 100644 --- a/aqt/sync.py +++ b/aqt/sync.py @@ -1,16 +1,16 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import time import gc +import time -from aqt.qt import * -from anki.storage import Collection -from anki.sync import Syncer, RemoteServer, FullSyncer, MediaSyncer, \ - RemoteMediaServer from anki.hooks import addHook, remHook -from aqt.utils import tooltip, askUserDialog, showWarning, showText, showInfo from anki.lang import _ +from anki.storage import Collection +from anki.sync import (FullSyncer, MediaSyncer, RemoteMediaServer, + RemoteServer, Syncer) +from aqt.qt import * +from aqt.utils import askUserDialog, showInfo, showText, showWarning, tooltip # Sync manager ###################################################################### @@ -461,5 +461,3 @@ class SyncThread(QThread): def fireEvent(self, cmd, arg=""): self._event.emit(cmd, arg) - - diff --git a/aqt/tagedit.py b/aqt/tagedit.py index 2870e39ff..134ff9ca2 100644 --- a/aqt/tagedit.py +++ b/aqt/tagedit.py @@ -1,9 +1,11 @@ # Copyright: Ankitects Pty Ltd and contributors # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from aqt.qt import * import re +from aqt.qt import * + + class TagEdit(QLineEdit): lostFocus = pyqtSignal() @@ -112,4 +114,4 @@ class TagCompleter(QCompleter): self.tags.remove("") except ValueError: pass - return " ".join(self.tags) + " " \ No newline at end of file + return " ".join(self.tags) + " " diff --git a/aqt/taglimit.py b/aqt/taglimit.py index 42edb1f71..b568b2347 100644 --- a/aqt/taglimit.py +++ b/aqt/taglimit.py @@ -3,7 +3,8 @@ import aqt from aqt.qt import * -from aqt.utils import saveGeom, restoreGeom +from aqt.utils import restoreGeom, saveGeom + class TagLimit(QDialog): diff --git a/aqt/toolbar.py b/aqt/toolbar.py index 86caa8e4a..3420a0ee6 100644 --- a/aqt/toolbar.py +++ b/aqt/toolbar.py @@ -2,8 +2,9 @@ # -*- coding: utf-8 -*- # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -from aqt.qt import * from anki.lang import _ +from aqt.qt import * + class Toolbar: diff --git a/aqt/update.py b/aqt/update.py index 68f7057f3..c94949c40 100644 --- a/aqt/update.py +++ b/aqt/update.py @@ -5,11 +5,12 @@ import time import requests -from aqt.qt import * import aqt -from aqt.utils import openLink, showText -from anki.utils import platDesc, versionWithBuild from anki.lang import _ +from anki.utils import platDesc, versionWithBuild +from aqt.qt import * +from aqt.utils import openLink, showText + class LatestVersionFinder(QThread): diff --git a/aqt/utils.py b/aqt/utils.py index 6f8ef1423..82dadd959 100644 --- a/aqt/utils.py +++ b/aqt/utils.py @@ -1,15 +1,19 @@ # Copyright: Ankitects Pty Ltd and contributors # -*- coding: utf-8 -*- # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +import os +import re +import subprocess +import sys from typing import Optional -from aqt.qt import * -import re, os, sys, subprocess import aqt -from anki.sound import stripSounds -from anki.utils import isWin, isMac, invalidFilename, noBundledLibs, \ - versionWithBuild from anki.lang import _ +from anki.sound import stripSounds +from anki.utils import (invalidFilename, isMac, isWin, noBundledLibs, + versionWithBuild) +from aqt.qt import * + def openHelp(section): link = aqt.appHelpSite diff --git a/aqt/webview.py b/aqt/webview.py index 633c867e1..e70c94a01 100644 --- a/aqt/webview.py +++ b/aqt/webview.py @@ -2,13 +2,14 @@ # -*- coding: utf-8 -*- # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import json -import sys import math +import sys + from anki.hooks import runHook +from anki.lang import _ +from anki.utils import isLin, isMac, isWin from aqt.qt import * from aqt.utils import openLink -from anki.utils import isMac, isWin, isLin -from anki.lang import _ # Page for debug messages ########################################################################## diff --git a/aqt/winpaths.py b/aqt/winpaths.py index 6ef09d257..cb0aacb61 100644 --- a/aqt/winpaths.py +++ b/aqt/winpaths.py @@ -7,7 +7,7 @@ Depends only on ctypes, and retrieves path locations in Unicode """ import ctypes -from ctypes import windll, wintypes # type: ignore +from ctypes import windll, wintypes # type: ignore __license__ = "MIT" __version__ = "0.2" diff --git a/requirements.dev b/requirements.dev index 69b16dc2f..40d55e331 100644 --- a/requirements.dev +++ b/requirements.dev @@ -3,3 +3,4 @@ mypy==0.750 pylint mock pytype +isort