style: Add mypy for better code quality

Description

Abstract

Install and configure black and isort to force the code to be well written.

Motivation

Having documentation in every method is great but nothing ensure that the it is up to date. Having a tool to check that at least the documented types of attributes and return values are correct and correctly used from one function to another is great. We previously installed pylint and flake8 to ensure t

Rationale

Python provide “types annotation”. And mypy will check the project that they are correctly used.

As it can be cumbersome to use, we choose to not use them in tests.

1 make command is added:

  • make mypy: Run the mypy tool

And make lint is updated to add mypy

Info

Hash

141b284a4c9579ccaf65b84b68964385a0c7f469

Date

2019-05-27 17:14:12 +0200

Parents
  • style: Add black and isort to ensure code quality [2de7ffd1]2019-05-27 17:14:12 +0200

Children
  • style(git): Force format of git commit messages [4467a1f6]2019-06-03 13:54:59 +0200

Branches
Tags

(No tags)

Changes

Makefile

Type

Modified

Stats

+8 -3

@@ -43,7 +43,7 @@ clean:  ## Clean python build related directories and files
 full-clean:  ## Like "clean" but with clean-doc and will clean some other generated directories or files
 full-clean: clean
     @echo "$(BOLD)Full cleaning$(RESET)"
-    find ./ -type d \( -name '__pycache__' -or -name '.pytest_cache'  \) -print0 | xargs -tr0 rm -r
+    find ./ -type d  \( -name '__pycache__' -or -name '.pytest_cache' -or -name '.mypy_cache'  \) -print0 | xargs -tr0 rm -r
     -$(MAKE) clean-doc

 .PHONY: doc docs
@@ -66,14 +66,19 @@ tests:  ## Run tests for the isshub project.
     @pytest

 .PHONY: lint
-lint:  ## Run all linters (check-isort, check-black, flake8, pylint)
-lint: check-isort check-black flake8 pylint
+lint:  ## Run all linters (check-isort, check-black, mypy, flake8, pylint)
+lint: check-isort check-black flake8 pylint mypy

 .PHONY: check checks
 check: checks
 checks:  ## Run all checkers (lint, tests)
 checks: lint test

+.PHONY: mypy
+mypy:  ## Run the mypy tool
+    @echo "$(BOLD)Running mypy$(RESET)"
+    @mypy .
+
 .PHONY: check-isort
 check-isort:  ## Run the isort tool in check mode only (won't modify files)
     @echo "$(BOLD)Checking isort(RESET)"

README.rst

Type

Modified

Stats

+4 -0

@@ -218,6 +218,10 @@ For code documentation, I enforce docstrings in all modules, classes, and functi

 The checks are enforced by `flake8-docstrings`_ for basic docstring presentation, and by `pylint.extensions.docparams`_ for content.

+I'll try to use `python typing <https://docs.python.org/3/library/typing.html>`_ while avoiding making things too much complicated. So expect some `# type: ignore` comments here and there, notably on decorators.
+
+The types will be checked by `mypy`_.
+
 So, code documentation is important (take that, Django). But it is clearly not enough.

 We need to document the install process and how to run the application, how to participate and use all the tools, how things works, from a developer point of view and from a user point of view, etc, etc.

setup.cfg

Type

Modified

Stats

+28 -0

@@ -31,6 +31,7 @@ exclude =
 [options.extras_require]
 dev =
     ipython
+    mypy
     wheel
 tests =
     pytest
@@ -44,6 +45,7 @@ lint=
     flake8-docstrings
     flake8-formatter-abspath
     flake8-imports
+    flake8-mypy
     isort
     pycodestyle
     pydocstyle
@@ -54,6 +56,26 @@ docs =
     sphinx_rtd_theme
     sphinxprettysearchresults

+[mypy]
+check_untyped_defs = true
+disallow_incomplete_defs = true
+# because of django models for example
+disallow_subclassing_any = false
+disallow_untyped_calls = true
+disallow_untyped_decorators = true
+disallow_untyped_defs = true
+ignore_missing_imports = true
+python_version = 3.6
+strict_optional = true
+warn_incomplete_stub = true
+
+[mypy-isshub.*.tests.*]
+ignore_errors = True
+
+[mypy-test_testing]
+ignore_errors = True
+
+
 [flake8]
 ignore =
     # Line too long: we let black manage it
@@ -74,6 +96,8 @@ select =
     W
     # docstrings (using pydocstyle) plugin
     D
+    # mypy plugin
+    T4
     # bugbear plugin
     B
     B9
@@ -90,6 +114,10 @@ exclude =
     build/
     ci/
     test_testing.py
+per-file-ignores =
+    # ignore mypy missing annotations in tests
+    test_*:T4
+    factories.py:T4

 [pycodestyle]
 max-line-length = 99