mirror of
https://github.com/davidhalter/typeshed.git
synced 2025-12-09 05:24:52 +08:00
96 lines
2.9 KiB
Python
Executable File
96 lines
2.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Test runner for typeshed.
|
|
|
|
Depends on mypy being installed.
|
|
|
|
Approach:
|
|
|
|
1. Parse sys.argv
|
|
2. Compute appropriate arguments for mypy
|
|
3. Stuff those arguments into sys.argv
|
|
4. Run mypy.main('')
|
|
5. Repeat steps 2-4 for other mypy runs (e.g. --py2)
|
|
"""
|
|
|
|
import os
|
|
import re
|
|
import sys
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(description="Test runner for typeshed. Patterns are unanchored regexps on the full path.")
|
|
parser.add_argument('-v', '--verbose', action='count', default=0, help="More output")
|
|
parser.add_argument('-n', '--dry-run', action='store_true', help="Don't actually run mypy")
|
|
parser.add_argument('-x', '--exclude', type=str, nargs='*', help="Exclude pattern")
|
|
parser.add_argument('filter', type=str, nargs='*', help="Include pattern (default all)")
|
|
|
|
|
|
def log(args, *varargs):
|
|
if args.verbose >= 2:
|
|
print(*varargs)
|
|
|
|
def match(args, fn):
|
|
if not args.filter and not args.exclude:
|
|
log(args, fn, 'accept by default')
|
|
return True
|
|
if args.exclude:
|
|
for f in args.exclude:
|
|
if re.search(f, fn):
|
|
log(args, fn, 'excluded by pattern', f)
|
|
return False
|
|
if args.filter:
|
|
for f in args.filter:
|
|
if re.search(f, fn):
|
|
log(args, fn, 'accepted by pattern', f)
|
|
return True
|
|
if args.filter:
|
|
log(args, fn, 'rejected (no pattern matches)')
|
|
return False
|
|
log(args, fn, 'accepted (no exclude pattern matches)')
|
|
return True
|
|
|
|
|
|
def main():
|
|
args = parser.parse_args()
|
|
|
|
try:
|
|
from mypy.main import main as mypy_main
|
|
except ImportError:
|
|
print("Cannot import mypy. Did you install it?")
|
|
sys.exit(1)
|
|
|
|
files2 = []
|
|
files3 = []
|
|
for dir, subdirs, files in os.walk('.'):
|
|
for file in files:
|
|
if file == '__builtin__.pyi':
|
|
continue # Special case (alias for builtins.py).
|
|
if file.endswith('.pyi') or file.endswith('.py'):
|
|
full = os.path.join(dir, file)
|
|
if match(args, full):
|
|
if '/2' in dir:
|
|
files2.append(full)
|
|
if '/3' in dir or '/2and3' in dir:
|
|
files3.append(full)
|
|
if not (files2 or files3):
|
|
print('--- nothing to do ---')
|
|
code = 0
|
|
for flags, files in [([], files3), (['--py2'], files2)]:
|
|
if files:
|
|
sys.argv = ['mypy'] + flags + files
|
|
if args.verbose:
|
|
print('running', ' '.join(sys.argv))
|
|
else:
|
|
print('running mypy', ' '.join(flags), '# with', len(files), 'files')
|
|
try:
|
|
if not args.dry_run:
|
|
mypy_main('')
|
|
except SystemExit as err:
|
|
code = max(code, err.code)
|
|
if code:
|
|
print('--- exit status', code, '---')
|
|
sys.exit(code)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|