Files
zulip/tools/run-mypy
Tim Abbott 3003517430 docs: Move mypy documentation from contributing to testing.
The testing section is more appropriate, since it's fundamentally part
of our CI system.

While we're at it, fix the fact that we were linking to GitHub, not
ReadTheDocs, in the run-mypy output.
2018-12-16 21:52:53 -08:00

97 lines
3.3 KiB
Python
Executable File

#!/usr/bin/env python3
import os
import sys
import argparse
import subprocess
from zulint import lister
from typing import cast, Dict, List
TOOLS_DIR = os.path.dirname(os.path.abspath(__file__))
os.chdir(os.path.dirname(TOOLS_DIR))
sys.path.append(os.path.dirname(TOOLS_DIR))
from lib.test_script import get_provisioning_status
exclude = """
stubs/
""".split()
parser = argparse.ArgumentParser(description="Run mypy on files tracked by git.")
parser.add_argument('targets', nargs='*',
help="files and directories to check (default: .)")
parser.add_argument('--version', action='store_true',
help="show mypy version information and exit")
parser.add_argument('--quick', action='store_true',
help="pass --quick to mypy")
parser.add_argument('-m', '--modified', action='store_true',
help="check only modified files")
parser.add_argument('--no-daemon', action='store_true',
help="Start and run the mypy fine-grained incremental daemon")
parser.add_argument('--scripts-only', action='store_true',
help="only check extensionless python scripts")
parser.add_argument('-a', '--all', action='store_true',
help="check all files, bypassing the default exclude list")
parser.add_argument('--force', action="store_true",
help="run tests despite possible provisioning problems")
args = parser.parse_args()
if not args.force:
ok, msg = get_provisioning_status()
if not ok:
print(msg)
print('If you really know what you are doing, use --force to run anyway.')
sys.exit(1)
command_name = "mypy" if (args.no_daemon or args.version) else "dmypy"
# Use zulip-py3-venv's mypy if it's available.
VENV_DIR = "/srv/zulip-py3-venv"
MYPY_VENV_PATH = os.path.join(VENV_DIR, "bin", command_name)
if os.path.exists(MYPY_VENV_PATH):
mypy_command = MYPY_VENV_PATH
else:
mypy_command = command_name
if args.version:
print("mypy command:", mypy_command)
sys.exit(subprocess.call([mypy_command, "--version"]))
if args.all:
exclude = []
# find all non-excluded files in current directory
files_dict = cast(Dict[str, List[str]],
lister.list_files(targets=args.targets, ftypes=['py', 'pyi'],
use_shebang=True, modified_only=args.modified,
exclude=exclude, group_by_ftype=True,
extless_only=args.scripts_only))
pyi_files = list(files_dict['pyi'])
python_files = [fpath for fpath in files_dict['py']
if not fpath.endswith('.py') or fpath + 'i' not in pyi_files]
if not python_files and not pyi_files:
print("There are no files to run mypy on.")
sys.exit(0)
extra_args = []
if args.quick:
extra_args.append("--quick")
mypy_args = extra_args + python_files + pyi_files
if args.no_daemon:
rc = subprocess.call([mypy_command] + mypy_args)
else:
rc = subprocess.call([mypy_command, "status"], stdout=subprocess.PIPE)
if rc != 0:
print("Starting mypy daemon, this will take a minute...")
sys.stdout.flush()
rc = subprocess.call([mypy_command, 'run', '--'] + mypy_args)
if rc != 0:
print("")
print("See https://zulip.readthedocs.io/en/latest/testing/mypy.html for debugging tips.")
sys.exit(rc)