py3: Switch almost all shebang lines to use `python3`.
This causes `upgrade-zulip-from-git`, as well as a no-option run of
`tools/build-release-tarball`, to produce a Zulip install running
Python 3, rather than Python 2. In particular this means that the
virtualenv we create, in which all application code runs, is Python 3.
One shebang line, on `zulip-ec2-configure-interfaces`, explicitly
keeps Python 2, and at least one external ops script, `wal-e`, also
still runs on Python 2. See discussion on the respective previous
commits that made those explicit. There may also be some other
third-party scripts we use, outside of this source tree and running
outside our virtualenv, that still run on Python 2.
2017-08-02 23:15:16 +02:00
|
|
|
#!/usr/bin/env python3
|
2016-04-07 07:22:04 +02:00
|
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import argparse
|
|
|
|
import subprocess
|
2019-11-13 21:55:27 +01:00
|
|
|
from typing import List
|
2016-04-07 07:22:04 +02:00
|
|
|
|
2018-08-04 22:02:09 +02:00
|
|
|
from zulint import lister
|
2016-07-24 09:38:08 +02:00
|
|
|
|
2016-07-12 19:27:13 +02:00
|
|
|
TOOLS_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
os.chdir(os.path.dirname(TOOLS_DIR))
|
|
|
|
|
2017-08-06 01:16:07 +02:00
|
|
|
sys.path.append(os.path.dirname(TOOLS_DIR))
|
2019-06-20 18:27:09 +02:00
|
|
|
from lib.test_script import assert_provisioning_status_ok
|
2017-08-06 01:16:07 +02:00
|
|
|
|
2017-08-09 02:17:30 +02:00
|
|
|
exclude = """
|
2018-07-12 10:33:58 +02:00
|
|
|
stubs/
|
2016-04-07 07:22:04 +02:00
|
|
|
""".split()
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser(description="Run mypy on files tracked by git.")
|
2017-09-26 23:10:20 +02:00
|
|
|
parser.add_argument('targets', nargs='*',
|
2017-09-26 23:28:10 +02:00
|
|
|
help="files and directories to check (default: .)")
|
2017-09-26 23:33:21 +02:00
|
|
|
parser.add_argument('--version', action='store_true',
|
2017-09-26 23:38:56 +02:00
|
|
|
help="show mypy version information and exit")
|
2017-09-26 23:10:20 +02:00
|
|
|
parser.add_argument('-m', '--modified', action='store_true',
|
2017-09-26 23:28:10 +02:00
|
|
|
help="check only modified files")
|
2017-09-26 23:30:05 +02:00
|
|
|
parser.add_argument('--scripts-only', action='store_true',
|
|
|
|
help="only check extensionless python scripts")
|
2017-09-26 23:10:20 +02:00
|
|
|
parser.add_argument('-a', '--all', action='store_true',
|
2017-09-26 23:28:10 +02:00
|
|
|
help="check all files, bypassing the default exclude list")
|
2017-09-26 23:30:05 +02:00
|
|
|
parser.add_argument('--force', action="store_true",
|
|
|
|
help="run tests despite possible provisioning problems")
|
2019-11-13 21:55:27 +01:00
|
|
|
parser.add_argument("--quiet", action="store_true",
|
|
|
|
help="suppress mypy summary output")
|
2016-04-07 07:22:04 +02:00
|
|
|
args = parser.parse_args()
|
2016-07-01 18:38:57 +02:00
|
|
|
|
2019-06-20 18:27:09 +02:00
|
|
|
assert_provisioning_status_ok(args.force)
|
2017-08-06 01:16:07 +02:00
|
|
|
|
2019-08-07 03:55:10 +02:00
|
|
|
command_name = "mypy"
|
2018-05-21 18:34:33 +02:00
|
|
|
|
2017-09-26 23:33:21 +02:00
|
|
|
# Use zulip-py3-venv's mypy if it's available.
|
|
|
|
VENV_DIR = "/srv/zulip-py3-venv"
|
2018-05-21 18:34:33 +02:00
|
|
|
MYPY_VENV_PATH = os.path.join(VENV_DIR, "bin", command_name)
|
2017-09-26 23:33:21 +02:00
|
|
|
if os.path.exists(MYPY_VENV_PATH):
|
|
|
|
mypy_command = MYPY_VENV_PATH
|
|
|
|
else:
|
2018-05-21 18:34:33 +02:00
|
|
|
mypy_command = command_name
|
2017-09-26 23:33:21 +02:00
|
|
|
|
|
|
|
if args.version:
|
2017-09-26 23:38:56 +02:00
|
|
|
print("mypy command:", mypy_command)
|
2017-09-26 23:33:21 +02:00
|
|
|
sys.exit(subprocess.call([mypy_command, "--version"]))
|
|
|
|
|
2016-04-07 07:22:04 +02:00
|
|
|
if args.all:
|
2017-08-09 02:17:30 +02:00
|
|
|
exclude = []
|
2016-04-07 07:22:04 +02:00
|
|
|
|
2016-05-24 15:42:55 +02:00
|
|
|
# find all non-excluded files in current directory
|
linter_lib: Fix mypy errors.
tools/linter_lib/pyflakes.py:35: error: Argument 3 to "run_pyflakes" has incompatible type "List[Tuple[bytes, bytes]]"; expected "List[Tuple[str, str]]"
tools/linter_lib/custom_check.py:110: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:214: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:214: error: Argument "shebang_rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:502: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:502: error: Argument "shebang_rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:519: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:706: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:728: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:738: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:779: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:779: error: Argument "length_exclude" to "RuleList" has incompatible type "Set[str]"; expected "List[str]"
tools/linter_lib/custom_check.py:803: error: Argument "length_exclude" to "RuleList" has incompatible type "Set[str]"; expected "List[str]"
tools/linter_lib/custom_check.py:805: error: Unsupported operand types for + ("List[Rule]" and "List[Dict[str, Any]]")
tools/linter_lib/custom_check.py:819: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
These were missed the `zulint` package was missing PEP 561 type
annotation markers, and if it’d had them, mypy daemon mode would’ve
required us to set `follow_imports = skip` for it.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-08-07 03:29:33 +02:00
|
|
|
files_dict = 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,
|
|
|
|
)
|
2018-03-13 21:00:49 +01:00
|
|
|
pyi_files = list(files_dict['pyi'])
|
2016-06-15 14:50:25 +02:00
|
|
|
python_files = [fpath for fpath in files_dict['py']
|
2016-07-21 21:56:18 +02:00
|
|
|
if not fpath.endswith('.py') or fpath + 'i' not in pyi_files]
|
2018-03-13 21:00:49 +01:00
|
|
|
if not python_files and not pyi_files:
|
2017-09-26 23:43:34 +02:00
|
|
|
print("There are no files to run mypy on.")
|
|
|
|
sys.exit(0)
|
2016-04-07 07:22:04 +02:00
|
|
|
|
2019-11-13 21:55:27 +01:00
|
|
|
mypy_args = [] # type: List[str]
|
|
|
|
if args.quiet:
|
|
|
|
mypy_args += ["--no-error-summary"]
|
|
|
|
mypy_args += ["--"] + python_files + pyi_files
|
2019-08-07 03:55:10 +02:00
|
|
|
rc = subprocess.call([mypy_command] + mypy_args)
|
2016-06-02 21:46:24 +02:00
|
|
|
|
2018-12-05 20:23:10 +01:00
|
|
|
if rc != 0:
|
|
|
|
print("")
|
2018-12-17 06:13:21 +01:00
|
|
|
print("See https://zulip.readthedocs.io/en/latest/testing/mypy.html for debugging tips.")
|
2018-12-05 20:23:10 +01:00
|
|
|
|
2017-09-26 23:43:34 +02:00
|
|
|
sys.exit(rc)
|