Files
zulip/tools/run-mypy
Eklavya Sharma 05046d9288 bugdown's codehilite.py: Fix annotations in python 3 mode.
Many stubs in xml.etree.ElementTree use Union[str, bytes] as
return type.  Mypy wants us to correctly handle each case.  This
is correct, but not useful for us since we know that we'll always
get str.  So force the return value to text_type, to supress mypy
errors.
2016-07-07 09:52:24 -07:00

133 lines
4.7 KiB
Python
Executable File

#!/usr/bin/env python
from __future__ import print_function
import os
from os.path import dirname, abspath
import sys
import lister
import argparse
import subprocess
import six
exclude_common = """
api/integrations/asana/zulip_asana_config.py
api/integrations/basecamp/zulip_basecamp_config.py
api/integrations/codebase/zulip_codebase_config.py
api/integrations/git/zulip_git_config.py
api/integrations/hg/zulip-changegroup.py
api/integrations/perforce/git_p4.py
api/integrations/perforce/zulip_change-commit.py
api/integrations/perforce/zulip_perforce_config.py
api/integrations/svn/zulip_svn_config.py
api/integrations/trac/zulip_trac_config.py
api/integrations/trac/zulip_trac.py
bots/jabber_mirror_backend.py
bots/zephyr_mirror_backend.py
tools/deprecated/finbot/monthdelta.py
tools/deprecated/finbot/money.py
tools/deprecated/generate-activity-metrics.py
zproject/settings.py
zproject/test_settings.py
zerver/tests/test_bugdown.py
zerver/tests/test_email_mirror.py
zerver/tests/test_decorators.py
zerver/tests/test_upload.py
zerver/tests/test_messages.py
zerver/tests/test_narrow.py
""".split()
exclude_py2 = []
exclude_py3 = """
zerver/lib/actions.py
zerver/lib/bugdown/__init__.py
zerver/lib/ccache.py
zerver/lib/debug.py
zerver/lib/email_mirror.py
zerver/lib/notifications.py
zerver/lib/tornado_ioloop_logging.py
zerver/management/commands/create_stream.py
zerver/management/commands/email-mirror.py
zerver/management/commands/enqueue_file.py
zerver/management/commands/rename_stream.py
zerver/management/commands/runtornado.py
zerver/tests/test_i18n.py
zerver/views/__init__.py
zerver/views/messages.py
zerver/views/webhooks/beanstalk.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('--linecoverage-report', dest='linecoverage_report', action='store_true', default=False,
help="""run the linecoverage report to see annotation coverage""")
parser.add_argument('--disallow-untyped-defs', dest='disallow_untyped_defs', action='store_true', default=False,
help="""throw errors when functions are not annotated""")
group = parser.add_mutually_exclusive_group()
group.add_argument('--py2', default=False, action='store_true', help="Use Python 2 mode")
group.add_argument('--py3', default=False, action='store_true', help="Use Python 3 mode")
args = parser.parse_args()
if args.py2:
py_version = 2
elif args.py3:
py_version = 3
else:
py_version = 2
if args.all:
exclude = []
elif py_version == 2:
exclude = exclude_common + exclude_py2
else:
exclude = exclude_common + exclude_py3
# find all non-excluded files in current directory
files_dict = lister.list_files(targets=args.targets, ftypes=['py', 'pyi'], use_shebang=False,
modified_only=args.modified, exclude = exclude + ['stubs'],
group_by_ftype=True)
pyi_files = set(files_dict['pyi'])
python_files = [fpath for fpath in files_dict['py']
if fpath.endswith('.py') and fpath + 'i' not in pyi_files]
# Use zulip-py3-venv's mypy if it's available and we're on python 2
PY3_VENV_DIR = "/srv/zulip-py3-venv"
MYPY_VENV_PATH = os.path.join(PY3_VENV_DIR, "bin", "mypy")
if six.PY2 and os.path.exists(MYPY_VENV_PATH):
mypy_command = MYPY_VENV_PATH
print("Using mypy from", mypy_command)
else:
mypy_command = "mypy"
extra_args = ["--fast-parser", "--silent-imports", "--check-untyped-defs"]
if py_version == 2:
extra_args.append("--py2")
if args.linecoverage_report:
extra_args.append("--linecoverage-report")
extra_args.append("linecoverage-report")
if args.disallow_untyped_defs:
extra_args.append("--disallow-untyped-defs")
# run mypy
if python_files:
rc = subprocess.call([mypy_command] + extra_args + python_files)
if args.linecoverage_report:
# Move the coverage report to where coveralls will look for it.
try:
os.rename('linecoverage-report/coverage.txt', '.coverage')
except OSError:
# maybe mypy crashed; exit with its error code
pass
sys.exit(rc)
else:
print("There are no files to run mypy on.")