diff --git a/.travis.yml b/.travis.yml index f7b1e2b0c..6e6bc35bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ jobs: - python: 3.6 script: make -j 4 pytest pylint pytype - python: 3.7 - script: make -j 4 check + script: make -j 4 check pytype notifications: email: diff --git a/Makefile b/Makefile index 6224fe189..93bda0f1b 100644 --- a/Makefile +++ b/Makefile @@ -54,15 +54,31 @@ uninstall: # Prerequisites ###################### -REQS := .build/pyrunreqs .build/pydevreqs .build/jsreqs +REQS := .build/pyrunreqs .build/jsreqs .build/pyrunreqs: requirements.txt pip install -r $< ./tools/typecheck-setup.sh touch $@ -.build/pydevreqs: requirements.dev - pip install -r $< +.build/pytest-deps: + pip install nose mock + touch $@ + +.build/mypy-deps: + pip install mypy==0.750 + touch $@ + +.build/pylint-deps: + pip install pylint + touch $@ + +.build/pyimport-deps: + pip install isort + touch $@ + +.build/pytype-deps: + pip install pytype touch $@ .build/jsreqs: ts/package.json @@ -108,30 +124,30 @@ run: build ###################### .PHONY: check -check: mypy pyimports pytest pylint pytype checkpretty +check: mypy pyimports pytest pylint checkpretty # Checking python ###################### PYCHECKDEPS := $(BUILDDEPS) $(shell find anki aqt -name '*.py' | grep -v buildhash.py) -.build/mypy: $(PYCHECKDEPS) +.build/mypy: .build/mypy-deps $(PYCHECKDEPS) mypy anki aqt touch $@ -.build/pytest: $(PYCHECKDEPS) +.build/pytest: .build/pytest-deps $(PYCHECKDEPS) ./tools/tests.sh touch $@ -.build/pylint: $(PYCHECKDEPS) +.build/pylint: .build/pylint-deps $(PYCHECKDEPS) pylint -j 0 --rcfile=.pylintrc -f colorized --extension-pkg-whitelist=PyQt5 anki aqt touch $@ -.build/pytype: $(PYCHECKDEPS) +.build/pytype: .build/pytype-deps $(PYCHECKDEPS) pytype --config pytype.conf touch $@ -.build/pyimports: $(PYCHECKDEPS) +.build/pyimports: .build/pyimport-deps $(PYCHECKDEPS) isort -rc anki aqt --check # if this fails, run 'make fixpyimports' touch $@ diff --git a/README.contributing b/README.contributing index 957fed0f1..bf966b2a7 100644 --- a/README.contributing +++ b/README.contributing @@ -49,14 +49,17 @@ avoid 'Any' when a proper type is impractical. When adding type signatures, please avoid refactoring the code, as this is liable to break add-ons or introduce regressions. -Anki's Makefile invokes two type checkers - mypy and pytype. Mypy is fast, but -not very good at type inference, so it is mostly useful for checking code +When running 'make check', Anki uses mypy to typecheck the code. Mypy is fast, +but not very good at type inference, so it is mostly useful for checking code that has type signatures. It is able to read the bundled Qt stubs, and works across the whole Anki codebase. -pytype is much slower, but is better able to infer types when typing hints -are unavailable. It is not able to check the aqt/* code, as it can't read -the Qt stubs, and it is not currently compatible with Python 3.8. +When you use 'make pytype', Anki will typecheck the code with pytype. Pytype +is much slower, but it can catch errors in untyped code that mypy misses. It +is not able to check the aqt/* code, as it can't read the Qt stubs, and it is +not currently compatible with Python 3.8. It can also be difficult to build, +so it is not included in the default 'make check', but it will be run when a +pull request is submitted. The Qt stubs are not perfect, so you'll find when doing things like connecting signals, you may have to add the following to the end of a line to silence diff --git a/requirements.dev b/requirements.dev deleted file mode 100644 index 40d55e331..000000000 --- a/requirements.dev +++ /dev/null @@ -1,6 +0,0 @@ -nose -mypy==0.750 -pylint -mock -pytype -isort