From ad20e5896560fd6a38ac9cf0bc4d01c52dbe6ed9 Mon Sep 17 00:00:00 2001 From: Eric Arellano Date: Mon, 13 May 2019 18:11:41 -0700 Subject: [PATCH] Setup MyPy config and enforce types for build-support scripts (#7704) ### Problem We would like to use type hints throughout our code base, per https://github.com/pantsbuild/pants/issues/6742. However, we must configure it with sensible defaults to make it easier to use and to provide a consistent interface for developers. We should also enforce as much type safety as we can via our `pre-commit` check. ### Solution * Add new `mypy.ini` file with fairly loose defaults that are good for first time codebases. Eventually, we will want to do things like require all functions to be typed, but for now we loosen our expectations. * Link to the config file in `pants.ini`, along with using the most modern MyPy release which gives us the `strict_equality` check. * Run `mypy.py` over the build-support scripts, which are fully typed. * Acts as a proof of concept for how this will be integrated into CI. ### Result `./pants mypy` is now a bit more useful on our codebase, even though it will still fail because of pre-existing issues. Further, the build-support folder will not have any typing regressions now. --- build-support/githooks/pre-commit | 6 ++++ build-support/mypy/mypy.ini | 50 +++++++++++++++++++++++++++++++ pants.ini | 4 +++ 3 files changed, 60 insertions(+) create mode 100644 build-support/mypy/mypy.ini diff --git a/build-support/githooks/pre-commit b/build-support/githooks/pre-commit index a8c0a5781ddf..0ff354815498 100755 --- a/build-support/githooks/pre-commit +++ b/build-support/githooks/pre-commit @@ -58,6 +58,12 @@ if git rev-parse --verify "${MERGE_BASE}" &>/dev/null; then # quite often with a pexrc available. echo "* Checking lint" && ./pants --exclude-target-regexp='testprojects/.*' --changed-parent="${MERGE_BASE}" lint || exit 1 + echo "* Checking types (for build-support)" + # NB: This task requires Python 3, so we must temporarily override any intepreter constraints + # set by ci.sh, specifically it setting constraints to Python 2, because those constraints may + # cause a select-interpreter failure. + PANTS_PYTHON_SETUP_INTERPRETER_CONSTRAINTS="['CPython>=3.6']" ./pants mypy 'build-support::' || exit 1 + if git diff "${MERGE_BASE}" --name-only | grep '\.rs$' > /dev/null; then echo "* Checking formatting of rust files" && ./build-support/bin/check_rust_formatting.sh || exit 1 # Clippy happens on a different Travis CI shard because of separate caching concerns. diff --git a/build-support/mypy/mypy.ini b/build-support/mypy/mypy.ini new file mode 100644 index 000000000000..676a6b88f061 --- /dev/null +++ b/build-support/mypy/mypy.ini @@ -0,0 +1,50 @@ +[mypy] +# Refer to https://mypy.readthedocs.io/en/latest/command_line.html for the definition of each +# of these options. MyPy is frequently updated, so this file should be periodically reviewed +# for any new behavior that we can opt-in to. +# +# In general, we would like to be as strict as possible, but currently keep most checks turned off +# because our codebase has so little type coverage. As we add more types, these options should be +# re-evaluated and made more strict where possible. + +# Optionals +no_implicit_optional = True + +# Untyped. Eventually we should turn on as many of these as possible, but for now we turn them +# off to allow an incremental migration. +check_untyped_defs = False +disallow_untyped_calls = False +disallow_untyped_defs = False +disallow_untyped_decorators = False +disallow_incomplete_defs = False + +# Dynamic typing +disallow_any_unimported = False +disallow_any_expr = False +disallow_any_decorated = False +disallow_any_explicit = False +disallow_any_generics = False +disallow_subclassing_any = False + +# Strictness +strict_equality = False + +# Warnings +warn_unused_ignores = True +warn_no_return = True +warn_return_any = True +warn_redundant_casts = True + +# Error output +show_column_numbers = True +show_traceback = True + +# Imports. See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports. +ignore_missing_imports = True +follow_imports = normal +follow_imports_for_stubs = False + +# Ignore complaints about our dynamic programming +# TODO: write a plugin that teaches MyPy how these work! +# See https://mypy-lang.blogspot.com/2019/03/extending-mypy-with-plugins.html. +always_true = enum,datatype diff --git a/pants.ini b/pants.ini index 323f268c40f7..b281d6a1f24f 100644 --- a/pants.ini +++ b/pants.ini @@ -299,6 +299,10 @@ skip: True [pycheck-context-manager] skip: True +[mypy] +mypy_version: 0.701 +config_file: build-support/mypy/mypy.ini + [scala] version: 2.12