Skip to content

Commit bd94dff

Browse files
authored
[mypyc] Split a bunch of logic in test_run into another method (#7749)
A similar refactor is going to be needed for doing multi-stage testing and this separates the reindentation noise from real changes.
1 parent 0f4bf10 commit bd94dff

File tree

1 file changed

+132
-129
lines changed

1 file changed

+132
-129
lines changed

mypyc/test/test_run.py

Lines changed: 132 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
)
4646
"""
4747

48+
WORKDIR = 'build'
49+
4850

4951
def run_setup(script_name: str, script_args: List[str]) -> bool:
5052
"""Run a setup script in a somewhat controlled environment.
@@ -102,143 +104,144 @@ class TestRun(MypycDataSuite):
102104
separate = False
103105

104106
def run_case(self, testcase: DataDrivenTestCase) -> None:
105-
bench = testcase.config.getoption('--bench', False) and 'Benchmark' in testcase.name
106-
107107
# setup.py wants to be run from the root directory of the package, which we accommodate
108108
# by chdiring into tmp/
109109
with use_custom_builtins(os.path.join(self.data_prefix, ICODE_GEN_BUILTINS), testcase), (
110110
chdir_manager('tmp')):
111-
text = '\n'.join(testcase.input)
112-
113-
options = Options()
114-
options.use_builtins_fixtures = True
115-
options.show_traceback = True
116-
options.strict_optional = True
117-
# N.B: We try to (and ought to!) run with the current
118-
# version of python, since we are going to link and run
119-
# against the current version of python.
120-
# But a lot of the tests use type annotations so we can't say it is 3.5.
121-
options.python_version = max(sys.version_info[:2], (3, 6))
122-
options.export_types = True
123-
options.preserve_asts = True
124-
125-
# Avoid checking modules/packages named 'unchecked', to provide a way
126-
# to test interacting with code we don't have types for.
127-
options.per_module_options['unchecked.*'] = {'follow_imports': 'error'}
128-
129-
workdir = 'build'
130-
os.mkdir(workdir)
131-
132-
source_path = 'native.py'
133-
with open(source_path, 'w', encoding='utf-8') as f:
134-
f.write(text)
135-
with open('interpreted.py', 'w', encoding='utf-8') as f:
136-
f.write(text)
137-
138-
shutil.copyfile(TESTUTIL_PATH, 'testutil.py')
139-
140-
source = build.BuildSource(source_path, 'native', text)
141-
sources = [source]
142-
module_names = ['native']
143-
module_paths = [os.path.abspath('native.py')]
144-
145-
# Hard code another module name to compile in the same compilation unit.
146-
to_delete = []
147-
for fn, text in testcase.files:
148-
fn = os.path.relpath(fn, test_temp_dir)
149-
150-
if os.path.basename(fn).startswith('other'):
151-
name = os.path.basename(fn).split('.')[0]
152-
module_names.append(name)
153-
sources.append(build.BuildSource(fn, name, text))
154-
to_delete.append(fn)
155-
module_paths.append(os.path.abspath(fn))
156-
157-
shutil.copyfile(fn,
158-
os.path.join(os.path.dirname(fn), name + '_interpreted.py'))
159-
160-
for source in sources:
161-
options.per_module_options.setdefault(source.module, {})['mypyc'] = True
162-
163-
groups = construct_groups(sources, self.separate, len(module_names) > 1)
164-
165-
try:
166-
result = emitmodule.parse_and_typecheck(
167-
sources=sources,
168-
options=options,
169-
alt_lib_path='.')
170-
errors = Errors()
171-
compiler_options = CompilerOptions(multi_file=self.multi_file)
172-
ir, cfiles = emitmodule.compile_modules_to_c(
173-
result,
174-
compiler_options=compiler_options,
175-
errors=errors,
176-
groups=groups,
177-
)
178-
if errors.num_errors:
179-
errors.flush_errors()
180-
assert False, "Compile error"
181-
except CompileError as e:
182-
for line in e.messages:
183-
print(line)
184-
assert False, 'Compile error'
185-
186-
# Check that serialization works on this IR
187-
check_serialization_roundtrip(ir)
188-
189-
setup_file = os.path.abspath(os.path.join(workdir, 'setup.py'))
190-
# We pass the C file information to the build script via setup.py unfortunately
191-
with open(setup_file, 'w', encoding='utf-8') as f:
192-
f.write(setup_format.format(module_paths, self.separate, cfiles))
193-
194-
if not run_setup(setup_file, ['build_ext', '--inplace']):
195-
if testcase.config.getoption('--mypyc-showc'):
196-
show_c(cfiles)
197-
assert False, "Compilation failed"
198-
199-
# Assert that an output file got created
200-
suffix = 'pyd' if sys.platform == 'win32' else 'so'
201-
assert glob.glob('native.*.{}'.format(suffix))
202-
203-
for p in to_delete:
204-
os.remove(p)
205-
206-
driver_path = 'driver.py'
207-
env = os.environ.copy()
208-
env['MYPYC_RUN_BENCH'] = '1' if bench else '0'
209-
210-
# XXX: This is an ugly hack.
211-
if 'MYPYC_RUN_GDB' in os.environ:
212-
if platform.system() == 'Darwin':
213-
subprocess.check_call(['lldb', '--', sys.executable, driver_path], env=env)
214-
assert False, ("Test can't pass in lldb mode. (And remember to pass -s to "
215-
"pytest)")
216-
elif platform.system() == 'Linux':
217-
subprocess.check_call(['gdb', '--args', sys.executable, driver_path], env=env)
218-
assert False, ("Test can't pass in gdb mode. (And remember to pass -s to "
219-
"pytest)")
220-
else:
221-
assert False, 'Unsupported OS'
222-
223-
proc = subprocess.Popen([sys.executable, driver_path], stdout=subprocess.PIPE,
224-
stderr=subprocess.STDOUT, env=env)
225-
output = proc.communicate()[0].decode('utf8')
226-
outlines = output.splitlines()
111+
os.mkdir(WORKDIR)
112+
self.run_case_inner(testcase)
113+
114+
def run_case_inner(self, testcase: DataDrivenTestCase) -> None:
115+
bench = testcase.config.getoption('--bench', False) and 'Benchmark' in testcase.name
116+
117+
text = '\n'.join(testcase.input)
118+
119+
options = Options()
120+
options.use_builtins_fixtures = True
121+
options.show_traceback = True
122+
options.strict_optional = True
123+
# N.B: We try to (and ought to!) run with the current
124+
# version of python, since we are going to link and run
125+
# against the current version of python.
126+
# But a lot of the tests use type annotations so we can't say it is 3.5.
127+
options.python_version = max(sys.version_info[:2], (3, 6))
128+
options.export_types = True
129+
options.preserve_asts = True
130+
131+
# Avoid checking modules/packages named 'unchecked', to provide a way
132+
# to test interacting with code we don't have types for.
133+
options.per_module_options['unchecked.*'] = {'follow_imports': 'error'}
134+
135+
source_path = 'native.py'
136+
with open(source_path, 'w', encoding='utf-8') as f:
137+
f.write(text)
138+
with open('interpreted.py', 'w', encoding='utf-8') as f:
139+
f.write(text)
140+
141+
shutil.copyfile(TESTUTIL_PATH, 'testutil.py')
142+
143+
source = build.BuildSource(source_path, 'native', text)
144+
sources = [source]
145+
module_names = ['native']
146+
module_paths = [os.path.abspath('native.py')]
147+
148+
# Hard code another module name to compile in the same compilation unit.
149+
to_delete = []
150+
for fn, text in testcase.files:
151+
fn = os.path.relpath(fn, test_temp_dir)
152+
153+
if os.path.basename(fn).startswith('other'):
154+
name = os.path.basename(fn).split('.')[0]
155+
module_names.append(name)
156+
sources.append(build.BuildSource(fn, name, text))
157+
to_delete.append(fn)
158+
module_paths.append(os.path.abspath(fn))
159+
160+
shutil.copyfile(fn,
161+
os.path.join(os.path.dirname(fn), name + '_interpreted.py'))
162+
163+
for source in sources:
164+
options.per_module_options.setdefault(source.module, {})['mypyc'] = True
165+
166+
groups = construct_groups(sources, self.separate, len(module_names) > 1)
227167

168+
try:
169+
result = emitmodule.parse_and_typecheck(
170+
sources=sources,
171+
options=options,
172+
alt_lib_path='.')
173+
errors = Errors()
174+
compiler_options = CompilerOptions(multi_file=self.multi_file)
175+
ir, cfiles = emitmodule.compile_modules_to_c(
176+
result,
177+
compiler_options=compiler_options,
178+
errors=errors,
179+
groups=groups,
180+
)
181+
if errors.num_errors:
182+
errors.flush_errors()
183+
assert False, "Compile error"
184+
except CompileError as e:
185+
for line in e.messages:
186+
print(line)
187+
assert False, 'Compile error'
188+
189+
# Check that serialization works on this IR
190+
check_serialization_roundtrip(ir)
191+
192+
setup_file = os.path.abspath(os.path.join(WORKDIR, 'setup.py'))
193+
# We pass the C file information to the build script via setup.py unfortunately
194+
with open(setup_file, 'w', encoding='utf-8') as f:
195+
f.write(setup_format.format(module_paths, self.separate, cfiles))
196+
197+
if not run_setup(setup_file, ['build_ext', '--inplace']):
228198
if testcase.config.getoption('--mypyc-showc'):
229199
show_c(cfiles)
230-
if proc.returncode != 0:
231-
print()
232-
print('*** Exit status: %d' % proc.returncode)
233-
234-
# Verify output.
235-
if bench:
236-
print('Test output:')
237-
print(output)
200+
assert False, "Compilation failed"
201+
202+
# Assert that an output file got created
203+
suffix = 'pyd' if sys.platform == 'win32' else 'so'
204+
assert glob.glob('native.*.{}'.format(suffix))
205+
206+
for p in to_delete:
207+
os.remove(p)
208+
209+
driver_path = 'driver.py'
210+
env = os.environ.copy()
211+
env['MYPYC_RUN_BENCH'] = '1' if bench else '0'
212+
213+
# XXX: This is an ugly hack.
214+
if 'MYPYC_RUN_GDB' in os.environ:
215+
if platform.system() == 'Darwin':
216+
subprocess.check_call(['lldb', '--', sys.executable, driver_path], env=env)
217+
assert False, ("Test can't pass in lldb mode. (And remember to pass -s to "
218+
"pytest)")
219+
elif platform.system() == 'Linux':
220+
subprocess.check_call(['gdb', '--args', sys.executable, driver_path], env=env)
221+
assert False, ("Test can't pass in gdb mode. (And remember to pass -s to "
222+
"pytest)")
238223
else:
239-
assert_test_output(testcase, outlines, 'Invalid output')
240-
241-
assert proc.returncode == 0
224+
assert False, 'Unsupported OS'
225+
226+
proc = subprocess.Popen([sys.executable, driver_path], stdout=subprocess.PIPE,
227+
stderr=subprocess.STDOUT, env=env)
228+
output = proc.communicate()[0].decode('utf8')
229+
outlines = output.splitlines()
230+
231+
if testcase.config.getoption('--mypyc-showc'):
232+
show_c(cfiles)
233+
if proc.returncode != 0:
234+
print()
235+
print('*** Exit status: %d' % proc.returncode)
236+
237+
# Verify output.
238+
if bench:
239+
print('Test output:')
240+
print(output)
241+
else:
242+
assert_test_output(testcase, outlines, 'Invalid output')
243+
244+
assert proc.returncode == 0
242245

243246

244247
# Run the main multi-module tests in multi-file compliation mode

0 commit comments

Comments
 (0)