diff --git a/.gitignore b/.gitignore index 26f7f0a..42fd999 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ swh-*/ packages/* snippets/ !packages/README !packages/keys/ .venv +.mypy_cache diff --git a/Makefile b/Makefile index ebfac09..4bd00a7 100644 --- a/Makefile +++ b/Makefile @@ -1,44 +1,47 @@ PYMODULES := $(shell bin/ls-py-modules) DB_MODULES = swh-storage swh-archiver swh-scheduler swh-indexer swh-scheduler/sql/updater DOC_MODULE = swh-docs all: # TODO this is too close to "docs" below, but is meant to go away anyhow, when # the dependency graph stuff will migrate to the swh-docs/ module .PHONY: doc doc: make -C doc/ check: $(patsubst %,check/%,$(PYMODULES)) +typecheck: $(patsubst %,typecheck/%,$(PYMODULES)) distclean: $(patsubst %,distclean/%,$(PYMODULES)) test: $(patsubst %,test/%,$(PYMODULES)) docs: $(patsubst %,docs/%,$(filter-out $(DOC_MODULE),$(PYMODULES))) docs-assets: $(patsubst %,docs-assets/%,$(filter-out $(DOC_MODULE),$(PYMODULES))) docs-apidoc: $(patsubst %,docs-apidoc/%,$(filter-out $(DOC_MODULE),$(PYMODULES))) docs-clean: $(patsubst %,docs-clean/%,$(filter-out $(DOC_MODULE),$(PYMODULES))) check/%: make -C $* check +typecheck/%: + make -C $* typecheck distclean/%: make -C $* distclean test/%: make -C $* test docs/%: make -C $*/docs docs-assets/%: make -C $*/docs assets docs-apidoc/%: make -C $*/docs apidoc docs-clean/%: make -C $*/docs clean .PHONY: update clean update: git pull mr up clean: make -C doc/ clean diff --git a/Makefile.python b/Makefile.python index bd0e847..837c935 100644 --- a/Makefile.python +++ b/Makefile.python @@ -1,55 +1,60 @@ # -*- mode: Makefile -*- PYMODULE := $(shell basename `pwd` | sed 's/-/./g') PYDIR := $(shell basename `pwd` | sed 's%-%/%g') PYTHON_BIN := $(shell test -d bin/ && find bin/ -type f -executable | xargs egrep -H '^\#.*python' | cut -f 1 -d :) TEST_DIRS := . TEST = python3 -m pytest TESTFLAGS = CODESPELL = codespell CODESPELLFLAGS = FLAKE = python3 -m flake8 FLAKEFLAGS = LINT = pylint3 LINTFLAGS = --rcfile=../pylintrc +MYPY = mypy +MYPYFLAGS = --config-file ../mypy.ini all: .PHONY: test test: $(TEST) $(TESTFLAGS) $(TEST_DIRS) .PHONY: coverage coverage: $(TEST) $(TESTFLAGS) --cov=$(PYMODULE) --cov-branch $(TEST_DIRS) .PHONY: check check-flake check-codespell check: check-flake check-codespell check-flake: $(FLAKE) $(FLAKEFLAGS) swh $(PYTHON_BIN) check-codespell: find swh docs -name '*.py' -o -name '*.rst' | xargs -r $(CODESPELL) $(CODESPELLFLAGS) find . -maxdepth 1 -iname 'readme*' | xargs -r $(CODESPELL) $(CODESPELLFLAGS) +typecheck: + @echo PYTHONPATH=... $(MYPY) $(MYPYFLAGS) -p $(PYMODULE) + @MYPYPATH=$(shell bash ../pythonpath.sh --print) $(MYPY) $(MYPYFLAGS) -p $(PYMODULE) .PHONY: check-staged check-staged: git diff -z --staged --name-only -- '*.py' $(PYTHON_BIN) \ | xargs -0 -L1 -i'{}' /bin/sh -c \ "git show ':{}' | $(FLAKE) $(FLAKEFLAGS) --stdin-display-name '{}' -" .PHONY: lint lint: $(LINT) $(LINTFLAGS) $(PYMODULE) .PHONY: docs docs: make -C docs .PHONY: distclean # clean up Python bytecode files. Also consider random *.pyc files, in case # Python 2.x has been run by mistake distclean: find . -type d -name __pycache__ | xargs rm -rf find . -type f -name '*.pyc' -delete diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 0000000..ecf0a75 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,52 @@ +[mypy] +cache_dir = ../.mypy_cache +namespace_packages = True +warn_unused_ignores = True + + +# 3rd party libraries without stubs (yet) + +[mypy-aiohttp_utils.*] +ignore_missing_imports = True + +[mypy-azure.*] +ignore_missing_imports = True + +[mypy-arrow.*] +ignore_missing_imports = True + +[mypy-celery.*] +ignore_missing_imports = True + +[mypy-decorator.*] +ignore_missing_imports = True + +[mypy-deprecated.*] +ignore_missing_imports = True + +[mypy-libcloud.*] +ignore_missing_imports = True + +[mypy-msgpack.*] +ignore_missing_imports = True + +[mypy-pkg_resources.extern.*] +ignore_missing_imports = True + +[mypy-psycopg2.*] +ignore_missing_imports = True + +[mypy-pyblake2.*] +ignore_missing_imports = True + +[mypy-pytest.*] +ignore_missing_imports = True + +[mypy-rados.*] +ignore_missing_imports = True + +[mypy-request_mock.*] +ignore_missing_imports = True + +[mypy-systemd.*] +ignore_missing_imports = True