839bbf0db4
This removes the excessively verbose lists of files to be tested, and flushes the output after every print to update the user on the current status in real time.
116 lines
4.6 KiB
Python
Executable file
116 lines
4.6 KiB
Python
Executable file
#!/usr/bin/env python
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import print_function
|
|
|
|
import os
|
|
import sys
|
|
import argparse
|
|
import subprocess
|
|
|
|
from collections import OrderedDict
|
|
from pathlib import PurePath
|
|
from server_lib 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))
|
|
|
|
exclude = """
|
|
zulip/integrations/git/zulip_git_config.py
|
|
zulip/integrations/irc/irc_mirror_backend.py
|
|
zulip/integrations/log2zulip/log2zulip
|
|
zulip/integrations/perforce/zulip_perforce_config.py
|
|
zulip/integrations/perforce/git_p4.py
|
|
zulip/integrations/svn/zulip_svn_config.py
|
|
zulip/integrations/zephyr/process_ccache
|
|
zulip/tests/__init__.py
|
|
zulip/tests/test_default_arguments.py
|
|
|
|
zulip_bots/zulip_bots/bots
|
|
zulip_bots/generate_manifest.py
|
|
zulip_bots/setup.py
|
|
zulip_bots/zulip_bots/lib.py
|
|
zulip_bots/zulip_bots/provision.py
|
|
zulip_bots/zulip_bots/run.py
|
|
zulip_bots/zulip_bots/test_lib.py
|
|
zulip_bots/zulip_bots/test_run.py
|
|
zulip_bots/zulip_bots/zulip_bot_output.py
|
|
|
|
zulip_botserver/tests/__init__.py
|
|
zulip_botserver/zulip_botserver/server.py
|
|
zulip_botserver/setup.py
|
|
""".split()
|
|
|
|
parser = argparse.ArgumentParser(description="Run mypy on files tracked by git.")
|
|
parser.add_argument('targets', nargs='*', default=[],
|
|
help="""files and directories to include in the result.
|
|
If this is not specified, the current directory is used""")
|
|
parser.add_argument('-m', '--modified', action='store_true', default=False, help='list only modified files')
|
|
parser.add_argument('-a', '--all', dest='all', action='store_true', default=False,
|
|
help="""run mypy on all python files, ignoring the exclude list.
|
|
This is useful if you have to find out which files fail mypy check.""")
|
|
parser.add_argument('--no-disallow-untyped-defs', dest='disallow_untyped_defs', action='store_false', default=True,
|
|
help="""Don't throw errors when functions are not annotated""")
|
|
parser.add_argument('--scripts-only', dest='scripts_only', action='store_true', default=False,
|
|
help="""Only type check extensionless python scripts""")
|
|
parser.add_argument('--strict-optional', dest='strict_optional', action='store_true', default=False,
|
|
help="""Use the --strict-optional flag with mypy""")
|
|
parser.add_argument('--warn-unused-ignores', dest='warn_unused_ignores', action='store_true', default=False,
|
|
help="""Use the --warn-unused-ignores flag with mypy""")
|
|
parser.add_argument('--no-ignore-missing-imports', dest='ignore_missing_imports', action='store_false', default=True,
|
|
help="""Don't use the --ignore-missing-imports flag with mypy""")
|
|
parser.add_argument('--quick', action='store_true', default=False,
|
|
help="""Use the --quick flag with mypy""")
|
|
args = parser.parse_args()
|
|
|
|
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 + ['stubs'], group_by_ftype=True,
|
|
extless_only=args.scripts_only))
|
|
pyi_files = set(files_dict['pyi'])
|
|
python_files = [fpath for fpath in files_dict['py']
|
|
if not fpath.endswith('.py') or fpath + 'i' not in pyi_files]
|
|
|
|
repo_python_files = OrderedDict([('zulip', []), ('zulip_bots', []), ('zulip_botserver', [])])
|
|
for file_path in python_files:
|
|
repo = PurePath(file_path).parts[0]
|
|
if repo in repo_python_files:
|
|
repo_python_files[repo].append(file_path)
|
|
|
|
mypy_command = "mypy"
|
|
|
|
extra_args = ["--check-untyped-defs",
|
|
"--follow-imports=silent",
|
|
"--scripts-are-modules",
|
|
"-i"]
|
|
if args.disallow_untyped_defs:
|
|
extra_args.append("--disallow-untyped-defs")
|
|
if args.warn_unused_ignores:
|
|
extra_args.append("--warn-unused-ignores")
|
|
if args.strict_optional:
|
|
extra_args.append("--strict-optional")
|
|
if args.ignore_missing_imports:
|
|
extra_args.append("--ignore-missing-imports")
|
|
if args.quick:
|
|
extra_args.append("--quick")
|
|
|
|
# run mypy
|
|
status = 0
|
|
for repo, python_files in repo_python_files.items():
|
|
print("Running mypy for `{}`.".format(repo), flush=True)
|
|
if python_files:
|
|
result = subprocess.call([mypy_command] + extra_args + python_files)
|
|
if result != 0:
|
|
status = result
|
|
else:
|
|
print("There are no files to run mypy on.")
|
|
sys.exit(status)
|