Skip to content

Commit 52b3e53

Browse files
committed
Allow testsuite to run in parallel
1 parent fcc7a45 commit 52b3e53

File tree

8 files changed

+45
-27
lines changed

8 files changed

+45
-27
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ python:
77

88
install: python setup.py install
99

10-
script: bash travis.sh
10+
script: python travis.py

mypy/build.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ def build(program_path: str,
133133
if TEST_BUILTINS in flags:
134134
# Use stub builtins (to speed up test cases and to make them easier to
135135
# debug).
136-
lib_path.insert(0, os.path.join('mypy', 'test', 'data', 'lib-stub'))
136+
lib_path.insert(0, os.path.join(os.path.dirname(__file__), 'test', 'data', 'lib-stub'))
137137
elif program_path:
138138
# Include directory of the program file in the module search path.
139139
lib_path.insert(
@@ -179,8 +179,8 @@ def build(program_path: str,
179179
def default_data_dir(bin_dir: str) -> str:
180180
# TODO fix this logic
181181
if not bin_dir:
182-
# Default to current directory.
183-
return ''
182+
# Default to directory containing this file's parent.
183+
return os.path.dirname(os.path.dirname(__file__))
184184
base = os.path.basename(bin_dir)
185185
dir = os.path.dirname(bin_dir)
186186
if (sys.platform == 'win32' and base.lower() == 'mypy'

mypy/myunit.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import os
12
import sys
23
import re
4+
import tempfile
35
import time
46
import traceback
57

@@ -91,18 +93,28 @@ def __init__(self, name: str, suite: 'Suite' = None,
9193
self.func = func
9294
self.name = name
9395
self.suite = suite
96+
self.old_cwd = None # type: str
97+
self.tmpdir = None # type: tempfile.TemporaryDirectory
9498

9599
def run(self) -> None:
96100
if self.func:
97101
self.func()
98102

99103
def set_up(self) -> None:
104+
self.old_cwd = os.getcwd()
105+
self.tmpdir = tempfile.TemporaryDirectory(prefix='mypy-test-', dir=os.path.abspath('tmp-test-dirs'))
106+
os.chdir(self.tmpdir.name)
107+
os.mkdir('tmp')
100108
if self.suite:
101109
self.suite.set_up()
102110

103111
def tear_down(self) -> None:
104112
if self.suite:
105113
self.suite.tear_down()
114+
os.chdir(self.old_cwd)
115+
self.tmpdir.cleanup()
116+
self.old_cwd = None
117+
self.tmpdir = None
106118

107119

108120
class Suite:

mypy/test/config.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@
1313
'Test data prefix ({}) not set correctly'.format(test_data_prefix)
1414

1515
# Temp directory used for the temp files created when running test cases.
16-
test_temp_dir = os.path.join(PREFIX, 'tmp')
17-
18-
if not os.path.isdir(test_temp_dir):
19-
os.mkdir(test_temp_dir)
20-
21-
assert os.path.isdir(test_temp_dir), \
22-
'Test temp dir ({}) not set correctly'.format(test_temp_dir)
16+
# This is *within* the tempfile.TemporaryDirectory that is chroot'ed per testcase.
17+
# It is also hard-coded in numerous places, so don't change it.
18+
test_temp_dir = 'tmp'

mypy/test/testpythoneval.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
# Path to Python 3 interpreter
3333
python3_path = sys.executable
3434

35-
default_python2_interpreter = 'python'
35+
default_python2_interpreter = 'python2'
3636

3737

3838
class PythonEvaluationSuite(Suite):
@@ -68,25 +68,24 @@ def test_python_evaluation(testcase):
6868
with open(program_path, 'w') as file:
6969
for s in testcase.input:
7070
file.write('{}\n'.format(s))
71-
# Set up module path.
72-
typing_path = os.path.join(os.getcwd(), 'lib-typing', '3.2')
73-
assert os.path.isdir(typing_path)
74-
env = os.environ.copy()
75-
env['PYTHONPATH'] = os.pathsep.join([typing_path, os.getcwd()])
7671
# Type check the program.
72+
# This uses the same PYTHONPATH as the current process.
7773
process = subprocess.Popen([python3_path,
78-
os.path.join(os.getcwd(), 'scripts', 'mypy')] + args + [program],
74+
os.path.join(testcase.old_cwd, 'scripts', 'mypy')] + args + [program],
7975
stdout=subprocess.PIPE,
8076
stderr=subprocess.STDOUT,
81-
cwd=test_temp_dir,
82-
env=env)
77+
cwd=test_temp_dir)
8378
outb = process.stdout.read()
8479
# Split output into lines.
8580
out = [s.rstrip('\n\r') for s in str(outb, 'utf8').splitlines()]
8681
if not process.wait():
87-
if py2:
88-
typing_path = os.path.join(os.getcwd(), 'lib-typing', '2.7')
89-
env['PYTHONPATH'] = typing_path
82+
# Set up module path for the execution.
83+
# This needs the typing module but *not* the mypy module.
84+
vers_dir = '2.7' if py2 else '3.2'
85+
typing_path = os.path.join(testcase.old_cwd, 'lib-typing', vers_dir)
86+
assert os.path.isdir(typing_path)
87+
env = os.environ.copy()
88+
env['PYTHONPATH'] = typing_path
9089
process = subprocess.Popen([interpreter, program],
9190
stdout=subprocess.PIPE,
9291
stderr=subprocess.STDOUT,

mypy/test/teststubgen.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import os.path
44
import random
55
import shutil
6+
import sys
7+
import tempfile
68
import time
79

810
import typing
@@ -102,9 +104,15 @@ def cases(self):
102104

103105

104106
def test_stubgen(testcase):
107+
if 'stubgen-test-path' not in sys.path:
108+
sys.path.insert(0, 'stubgen-test-path')
109+
os.mkdir('stubgen-test-path')
105110
source = '\n'.join(testcase.input)
106-
name = 'prog%d' % random.randrange(1000 * 1000 * 1000)
107-
path = '%s.py' % name
111+
handle = tempfile.NamedTemporaryFile(prefix='prog_', suffix='.py', dir='stubgen-test-path')
112+
assert os.path.isabs(handle.name)
113+
path = os.path.basename(handle.name)
114+
name = path[:-3]
115+
path = os.path.join('stubgen-test-path', path)
108116
out_dir = '_out'
109117
os.mkdir(out_dir)
110118
try:
@@ -127,7 +135,7 @@ def test_stubgen(testcase):
127135
testcase.file, testcase.line))
128136
finally:
129137
shutil.rmtree(out_dir)
130-
os.remove(path)
138+
handle.close()
131139

132140

133141
def reset_importlib_caches():

mypy/waiter.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ def __init__(self, limit=0) -> None:
4444
# Note: only count CPUs we are allowed to use. It is a
4545
# major mistake to count *all* CPUs on the machine.
4646
limit = len(sched_getaffinity(0))
47-
limit = 1
4847
self.limit = limit
4948
assert limit > 0
5049
print('%-8s %d' % ('PARALLEL', limit))

tmp-test-dirs/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# This directory is used to store temporary directories for the testsuite.
2+
# If anything manages to exist here, it means python crashed instead of
3+
# calling tempfile.TemporaryDirectory's cleanup while unwinding.
4+
# Therefore, don't actually provide any ignore patterns.

0 commit comments

Comments
 (0)