add basic type checking for anki/

This commit is contained in:
Damien Elmes 2019-12-16 08:17:28 +10:00
parent 81bdd860f3
commit 37a239cf38
12 changed files with 52 additions and 12 deletions

1
.gitignore vendored
View file

@ -8,3 +8,4 @@ aqt/forms
locale locale
tools/runanki.system tools/runanki.system
anki/buildhash.py anki/buildhash.py
.mypy_cache

View file

@ -8,5 +8,8 @@ echo "building ui..."
echo "running unit tests..." echo "running unit tests..."
nosetests ./tests nosetests ./tests
echo "type checking..."
./tools/typecheck.sh
echo "linting..." echo "linting..."
./tools/lint.sh ./tools/lint.sh

View file

@ -6,6 +6,7 @@ install:
- sudo apt-get update - sudo apt-get update
- sudo apt-get install portaudio19-dev - sudo apt-get install portaudio19-dev
- pip install -r requirements.txt - pip install -r requirements.txt
- pip install nose pylint pyqt5 pyqtwebengine - pip install -r requirements.dev
- pip install pyqt5 pyqtwebengine
script: ./.travis.sh script: ./.travis.sh

View file

@ -13,13 +13,14 @@ provide support for problems you encounter when running from source.
Anki requires: Anki requires:
- Python 3.6+ - Python 3.6+
- Qt 5.9.x/5.11.x/5.12.x and a PyQT that supports it - Qt 5.9.x or 5.11.x+, and a PyQT that supports it
- mpv - mpv
- lame - lame
It also requires a number of Python packages, which you can grab via pip: It also requires a number of Python packages, which you can grab via pip:
$ pip3 install -r requirements.txt $ pip3 install -r requirements.txt
$ pip3 install -r requirements.dev
If you're on a Linux distribution that packages a compatible Qt then you can If you're on a Linux distribution that packages a compatible Qt then you can
use the distro's packages. Make sure you install the development tools (eg use the distro's packages. Make sure you install the development tools (eg

View file

@ -3,7 +3,7 @@
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import re, os, zipfile, shutil, unicodedata import re, os, zipfile, shutil, unicodedata
import json import json, typing
from anki.lang import _ from anki.lang import _
from anki.utils import ids2str, splitFields, namedtmp, stripHTML from anki.utils import ids2str, splitFields, namedtmp, stripHTML
@ -11,7 +11,7 @@ from anki.hooks import runHook
from anki import Collection from anki import Collection
class Exporter: class Exporter:
includeHTML = None includeHTML: typing.Union[bool, None] = None
def __init__(self, col, did=None): def __init__(self, col, did=None):
self.col = col self.col = col
@ -134,7 +134,7 @@ class AnkiExporter(Exporter):
key = _("Anki 2.0 Deck") key = _("Anki 2.0 Deck")
ext = ".anki2" ext = ".anki2"
includeSched = False includeSched: typing.Union[bool, None] = False
includeMedia = True includeMedia = True
def __init__(self, col): def __init__(self, col):

View file

@ -14,11 +14,12 @@ automatically but can be called with _old().
""" """
import decorator import decorator
from typing import Dict, List, Callable, Any
# Hooks # Hooks
############################################################################## ##############################################################################
_hooks = {} _hooks: Dict[str, List[Callable[..., Any]]] = {}
def runHook(hook, *args): def runHook(hook, *args):
"Run all functions on hook." "Run all functions on hook."

View file

@ -3,6 +3,7 @@
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import copy, re, json import copy, re, json
from typing import Dict, Any
from anki.utils import intTime, joinFields, splitFields, ids2str,\ from anki.utils import intTime, joinFields, splitFields, ids2str,\
checksum checksum
from anki.lang import _ from anki.lang import _
@ -43,7 +44,7 @@ defaultModel = {
""" """
} }
defaultField = { defaultField: Dict[str, Any] = {
'name': "", 'name': "",
'ord': None, 'ord': None,
'sticky': False, 'sticky': False,

View file

@ -5,6 +5,7 @@
import html import html
import re, sys, threading, time, subprocess, os, atexit import re, sys, threading, time, subprocess, os, atexit
import random import random
from typing import List
from anki.hooks import addHook, runHook from anki.hooks import addHook, runHook
from anki.utils import tmpdir, isWin, isMac, isLin from anki.utils import tmpdir, isWin, isMac, isLin
from anki.lang import _ from anki.lang import _
@ -56,15 +57,15 @@ def _packagedCmd(cmd):
processingSrc = "rec.wav" processingSrc = "rec.wav"
processingDst = "rec.mp3" processingDst = "rec.mp3"
processingChain = [] processingChain: List[List[str]] = []
recFiles = [] recFiles: List[str] = []
processingChain = [ processingChain = [
["lame", processingSrc, processingDst, "--noreplaygain", "--quiet"], ["lame", processingSrc, processingDst, "--noreplaygain", "--quiet"],
] ]
# don't show box on windows # don't show box on windows
if isWin: if sys.platform == "win32":
si = subprocess.STARTUPINFO() si = subprocess.STARTUPINFO()
try: try:
si.dwFlags |= subprocess.STARTF_USESHOWWINDOW si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
@ -177,7 +178,7 @@ if isWin:
cleanupOldMplayerProcesses() cleanupOldMplayerProcesses()
mplayerQueue = [] mplayerQueue: List[str] = []
mplayerManager = None mplayerManager = None
mplayerReader = None mplayerReader = None
mplayerEvt = threading.Event() mplayerEvt = threading.Event()
@ -409,7 +410,7 @@ class PyAudioRecorder(_Recorder):
return processingSrc return processingSrc
if not pyaudio: if not pyaudio:
PyAudioRecorder = None PyAudioRecorder = None # type: ignore
# Audio interface # Audio interface
########################################################################## ##########################################################################

23
mypy.ini Normal file
View file

@ -0,0 +1,23 @@
[mypy]
python_version = 3.6
[mypy-win32file]
ignore_missing_imports = True
[mypy-win32pipe]
ignore_missing_imports = True
[mypy-pywintypes]
ignore_missing_imports = True
[mypy-winerror]
ignore_missing_imports = True
[mypy-distro]
ignore_missing_imports = True
[mypy-pyaudio]
ignore_missing_imports = True
[mypy-win32api]
ignore_missing_imports = True
[mypy-xml.dom]
ignore_missing_imports = True
[mypy-psutil]
ignore_missing_imports = True
[mypy-bs4]
ignore_missing_imports = True

3
requirements.dev Normal file
View file

@ -0,0 +1,3 @@
nose
mypy==0.750
pylint

View file

@ -7,3 +7,4 @@ markdown
jsonschema jsonschema
psutil; sys_platform == "win32" psutil; sys_platform == "win32"
distro; sys_platform != "win32" and sys_platform != "darwin" distro; sys_platform != "win32" and sys_platform != "darwin"
typing

4
tools/typecheck.sh Executable file
View file

@ -0,0 +1,4 @@
#!/bin/bash
TOOLS="$(cd "`dirname "$0"`"; pwd)"
mypy $TOOLS/../anki