Skip to content

Cleanup runtests.py #5011

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 12 additions & 83 deletions runtests.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
#!/usr/bin/env python3
"""Mypy test runner."""

from typing import Dict, List, Optional, Set, Iterable, Tuple

from mypy.waiter import Waiter, LazySubprocess
from mypy import util
from typing import List, Optional, Set, Iterable, Tuple

import itertools
import os
from os.path import join, isdir
import sys

from waiter import Waiter, LazySubprocess


def get_versions(): # type: () -> List[str]
def get_versions() -> List[str]:
major = sys.version_info[0]
minor = sys.version_info[1]
if major == 2:
Expand All @@ -24,9 +23,6 @@ def get_versions(): # type: () -> List[str]
return ['%d.%d' % (major, i) for i in range(minor, -1, -1)]


# Ideally, all tests would be `discover`able so that they can be driven
# (and parallelized) by an external test driver.

class Driver:

def __init__(self, *, whitelist: List[str], blacklist: List[str],
Expand Down Expand Up @@ -88,9 +84,6 @@ def add_mypy_modules(self, name: str, modules: Iterable[str], cwd: Optional[str]
def add_mypy_package(self, name: str, packagename: str, *flags: str) -> None:
self.add_mypy_cmd(name, ['-p', packagename] + list(flags))

def add_mypy_string(self, name: str, *args: str, cwd: Optional[str] = None) -> None:
self.add_mypy_cmd(name, ['-c'] + list(args), cwd=cwd)

def add_pytest(self, files: List[Tuple[str, str]], coverage: bool = True) -> None:
pytest_files = [name for kind, name in files
if self.allow('pytest {} {}'.format(kind, name))]
Expand All @@ -106,48 +99,6 @@ def add_pytest(self, files: List[Tuple[str, str]], coverage: bool = True) -> Non
passthrough=self.verbosity),
sequential=True)

def add_python(self, name: str, *args: str, cwd: Optional[str] = None) -> None:
name = 'run %s' % name
if not self.allow(name):
return
largs = list(args)
largs[0:0] = [sys.executable]
env = self.env
self.waiter.add(LazySubprocess(name, largs, cwd=cwd, env=env))

def add_python_mod(self, name: str, *args: str, cwd: Optional[str] = None,
coverage: bool = False) -> None:
name = 'run %s' % name
if not self.allow(name):
return
largs = list(args)
if coverage and self.coverage:
largs[0:0] = ['coverage', 'run', '-m']
else:
largs[0:0] = [sys.executable, '-m']
env = self.env
self.waiter.add(LazySubprocess(name, largs, cwd=cwd, env=env))

def add_python_string(self, name: str, *args: str, cwd: Optional[str] = None) -> None:
name = 'run %s' % name
if not self.allow(name):
return
largs = list(args)
largs[0:0] = [sys.executable, '-c']
env = self.env
self.waiter.add(LazySubprocess(name, largs, cwd=cwd, env=env))

def add_python2(self, name: str, *args: str, cwd: Optional[str] = None) -> None:
name = 'run2 %s' % name
if not self.allow(name):
return
largs = list(args)
python2 = util.try_find_python2_interpreter()
assert python2, "Couldn't find a Python 2.7 interpreter"
largs[0:0] = [python2]
env = self.env
self.waiter.add(LazySubprocess(name, largs, cwd=cwd, env=env))

def add_flake8(self, cwd: Optional[str] = None) -> None:
name = 'lint'
if not self.allow(name):
Expand All @@ -161,16 +112,9 @@ def list_tasks(self) -> None:
print('{id}:{task}'.format(id=id, task=task.name))


def add_basic(driver: Driver) -> None:
if False:
driver.add_mypy('file setup.py', 'setup.py')
driver.add_mypy('file runtests.py', 'runtests.py')
driver.add_mypy('legacy entry script', 'scripts/mypy')
# needs typed_ast installed:
driver.add_mypy('fast-parse', '--fast-parse', 'test-data/samples/hello.py')


def add_selftypecheck(driver: Driver) -> None:
driver.add_mypy('file runtests.py', 'runtests.py')
driver.add_mypy('file waiter.py', 'waiter.py')
driver.add_mypy_package('package mypy', 'mypy', '--config-file', 'mypy_self_check.ini')


Expand All @@ -188,16 +132,6 @@ def file_to_module(file: str) -> str:
return rv


def add_imports(driver: Driver) -> None:
# Make sure each module can be imported originally.
# There is currently a bug in mypy where a module can pass typecheck
# because of *implicit* imports from other modules.
for f in find_files('mypy', suffix='.py'):
mod = file_to_module(f)
if not mod.endswith('.__main__'):
driver.add_python_string('import %s' % mod, 'import %s' % mod)


def test_path(*names: str):
return [os.path.join('mypy', 'test', '{}.py'.format(name))
for name in names]
Expand Down Expand Up @@ -235,11 +169,10 @@ def test_path(*names: str):
'teststubgen',
)

for f in find_files('mypy', prefix='test', suffix='.py'):
assert f in PYTEST_FILES + SLOW_FILES, f


def add_pytest(driver: Driver) -> None:
for f in find_files('mypy', prefix='test', suffix='.py'):
assert f in PYTEST_FILES + SLOW_FILES, f
driver.add_pytest([('unit-test', name) for name in PYTEST_FILES] +
[('integration', name) for name in SLOW_FILES])

Expand All @@ -248,8 +181,7 @@ def add_stubs(driver: Driver) -> None:
# We only test each module in the one version mypy prefers to find.
# TODO: test stubs for other versions, especially Python 2 stubs.

modules = set() # type: Set[str]
modules.add('typing')
modules = {'typing'}
# TODO: This should also test Python 2, and pass pyversion accordingly.
for version in ["2and3", "3", "3.3", "3.4", "3.5"]:
for stub_type in ['builtins', 'stdlib', 'third_party']:
Expand Down Expand Up @@ -280,12 +212,11 @@ def add_stdlibsamples(driver: Driver) -> None:

def add_samples(driver: Driver) -> None:
for f in find_files(os.path.join('test-data', 'samples'), suffix='.py'):
mypy_args = ['--no-strict-optional']
if f == os.path.join('test-data', 'samples', 'crawl2.py'):
# This test requires 3.5 for async functions
driver.add_mypy_cmd('file {}'.format(f), ['--python-version=3.5',
'--no-strict-optional', f])
else:
driver.add_mypy('file %s' % f, '--no-strict-optional', f)
mypy_args.append('--python-version=3.5')
driver.add_mypy_cmd('file {}'.format(f), mypy_args + [f])


def usage(status: int) -> None:
Expand Down Expand Up @@ -425,9 +356,7 @@ def main() -> None:

driver.add_flake8()
add_pytest(driver)
add_basic(driver)
add_selftypecheck(driver)
add_imports(driver)
add_stubs(driver)
add_stdlibsamples(driver)
add_samples(driver)
Expand Down
16 changes: 1 addition & 15 deletions mypy/waiter.py → waiter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,14 @@
from multiprocessing import cpu_count
import pipes
import re
from subprocess import Popen, STDOUT, DEVNULL
from subprocess import Popen, STDOUT
import sys
import tempfile
import time
import json
from collections import defaultdict


class WaiterError(Exception):
pass


class LazySubprocess:
"""Wrapper around a subprocess that runs a test task."""

Expand Down Expand Up @@ -401,16 +397,6 @@ def parse_test_stats_from_output(output: str, fail_type: Optional[str]) -> Tuple
return (sum(c for k, c in counts.items() if k != 'deselected'),
counts.get('failed', 0))

# myunit
m = re.search('^([0-9]+)/([0-9]+) test cases failed(, ([0-9]+) skipped)?.$', output,
re.MULTILINE)
if m:
return int(m.group(2)), int(m.group(1))
m = re.search('^([0-9]+) test cases run(, ([0-9]+) skipped)?, all passed.$', output,
re.MULTILINE)
if m:
return int(m.group(1)), 0

# Couldn't find test counts, so fall back to single test per tasks.
if fail_type is not None:
return 1, 1
Expand Down