Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b775b51

Browse files
hughhan1msullivan
authored andcommitted
Update analysis, refcount, and exceptions tests (mypyc/mypyc#354)
Additionally, refactor Genops tests by moving shared functions into testutil.py.
1 parent 1910ed6 commit b775b51

8 files changed

Lines changed: 348 additions & 149 deletions

File tree

mypyc/test/test_analysis.py

Lines changed: 11 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,17 @@
11
"""Test runner for data-flow analysis test cases."""
22

33
import os.path
4-
import re
5-
import shutil
6-
from typing import List, Set
74

8-
from mypy import build
9-
from mypy.test.data import parse_test_cases, DataDrivenTestCase
5+
from mypy.test.data import DataDrivenTestCase
106
from mypy.test.config import test_temp_dir
117
from mypy.errors import CompileError
12-
from mypy.options import Options
13-
from mypy import experiments
148

159
from mypyc import analysis
16-
from mypyc import genops
1710
from mypyc import exceptions
18-
from mypyc.ops import format_func, Register, Value
11+
from mypyc.ops import format_func, is_empty_module_top_level
1912
from mypyc.test.testutil import (
20-
ICODE_GEN_BUILTINS, use_custom_builtins, MypycDataSuite, assert_test_output
13+
ICODE_GEN_BUILTINS, use_custom_builtins, MypycDataSuite, build_ir_for_single_file,
14+
assert_test_output, remove_comment_lines
2115
)
2216

2317
files = [
@@ -34,35 +28,18 @@ def run_case(self, testcase: DataDrivenTestCase) -> None:
3428
"""Perform a data-flow analysis test case."""
3529

3630
with use_custom_builtins(os.path.join(self.data_prefix, ICODE_GEN_BUILTINS), testcase):
37-
program_text = '\n'.join(testcase.input)
38-
39-
options = Options()
40-
options.use_builtins_fixtures = True
41-
options.show_traceback = True
42-
options.python_version = (3, 6)
43-
options.export_types = True
44-
45-
source = build.BuildSource('main', '__main__', program_text)
4631
try:
47-
# Construct input as a single single.
48-
# Parse and type check the input program.
49-
result = build.build(sources=[source],
50-
options=options,
51-
alt_lib_path=test_temp_dir)
32+
ir = build_ir_for_single_file(testcase.input)
5233
except CompileError as e:
5334
actual = e.messages
5435
else:
55-
if result.errors:
56-
actual = result.errors
57-
else:
58-
modules = genops.build_ir([result.files['__main__']], result.types)
59-
module = modules[0][1]
60-
assert len(module.functions) == 2, (
61-
"Only 1 function definition expected per test case")
62-
fn = module.functions[0]
36+
actual = []
37+
for fn in ir:
38+
if is_empty_module_top_level(fn):
39+
# Skip trivial module top levels that only return.
40+
continue
6341
exceptions.insert_exception_handling(fn)
64-
actual = format_func(fn)
65-
actual = actual[actual.index('L0:'):]
42+
actual.extend(format_func(fn))
6643
cfg = analysis.get_cfg(fn.blocks)
6744

6845
args = set(reg for reg, i in fn.env.indexes.items() if i < len(fn.args))
@@ -85,7 +62,6 @@ def run_case(self, testcase: DataDrivenTestCase) -> None:
8562
else:
8663
assert False, 'No recognized _AnalysisName suffix in test case'
8764

88-
actual.append('')
8965
for key in sorted(analysis_result.before.keys(),
9066
key=lambda x: (x[0].label, x[1])):
9167
pre = ', '.join(sorted(reg.name

mypyc/test/test_exceptions.py

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,18 @@
44
"""
55

66
import os.path
7-
from typing import List
87

98
from mypy.test.config import test_temp_dir
10-
from mypy.test.data import parse_test_cases, DataDrivenTestCase, DataSuite
9+
from mypy.test.data import DataDrivenTestCase
1110
from mypy.errors import CompileError
1211

13-
from mypyc.ops import format_func
12+
from mypyc.ops import format_func, is_empty_module_top_level
1413
from mypyc.exceptions import insert_exception_handling
1514
from mypyc.refcount import insert_ref_count_opcodes
1615
from mypyc.test.testutil import (
17-
ICODE_GEN_BUILTINS,
18-
build_ir_for_single_file,
19-
use_custom_builtins,
20-
MypycDataSuite,
21-
assert_test_output,
16+
ICODE_GEN_BUILTINS, use_custom_builtins, MypycDataSuite, build_ir_for_single_file,
17+
assert_test_output, remove_comment_lines
2218
)
23-
from mypyc.test.config import test_data_prefix
2419

2520
files = [
2621
'exceptions.test'
@@ -32,20 +27,23 @@ class TestExceptionTransform(MypycDataSuite):
3227
base_path = test_temp_dir
3328

3429
def run_case(self, testcase: DataDrivenTestCase) -> None:
35-
"""Perform a reference count opcode insertion transform test case."""
30+
"""Perform a runtime checking transformation test case."""
31+
with use_custom_builtins(os.path.join(self.data_prefix, ICODE_GEN_BUILTINS), testcase):
32+
expected_output = remove_comment_lines(testcase.output)
3633

37-
with use_custom_builtins(os.path.join(test_data_prefix, ICODE_GEN_BUILTINS), testcase):
3834
try:
3935
ir = build_ir_for_single_file(testcase.input)
4036
except CompileError as e:
4137
actual = e.messages
4238
else:
43-
# Expect one function + module top level function.
44-
assert len(ir) == 2, "Only 1 function definition expected per test case"
45-
fn = ir[0]
46-
insert_exception_handling(fn)
47-
insert_ref_count_opcodes(fn)
48-
actual = format_func(fn)
49-
actual = actual[actual.index('L0:'):]
50-
51-
assert_test_output(testcase, actual, 'Invalid source code output')
39+
actual = []
40+
for fn in ir:
41+
if is_empty_module_top_level(fn):
42+
# Skip trivial module top levels that only return.
43+
continue
44+
insert_exception_handling(fn)
45+
insert_ref_count_opcodes(fn)
46+
actual.extend(format_func(fn))
47+
48+
assert_test_output(testcase, actual, 'Invalid source code output',
49+
expected_output)

mypyc/test/test_genops.py

Lines changed: 11 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,15 @@
11
"""Test cases for IR generation."""
22

33
import os.path
4-
import re
5-
import shutil
6-
from typing import List
74

8-
from mypy import build
9-
from mypy.test.data import parse_test_cases, DataDrivenTestCase, DataSuite
105
from mypy.test.config import test_temp_dir
6+
from mypy.test.data import DataDrivenTestCase
117
from mypy.errors import CompileError
12-
from mypy.options import Options
13-
from mypy import experiments
14-
15-
from mypyc import genops
16-
from mypyc.ops import format_func, FuncIR, is_empty_module_top_level
178

9+
from mypyc.ops import format_func, is_empty_module_top_level
1810
from mypyc.test.testutil import (
19-
ICODE_GEN_BUILTINS, use_custom_builtins, MypycDataSuite, assert_test_output
11+
ICODE_GEN_BUILTINS, use_custom_builtins, MypycDataSuite, build_ir_for_single_file,
12+
assert_test_output, remove_comment_lines
2013
)
2114

2215
files = [
@@ -46,60 +39,17 @@ def run_case(self, testcase: DataDrivenTestCase) -> None:
4639
with use_custom_builtins(os.path.join(self.data_prefix, ICODE_GEN_BUILTINS), testcase):
4740
expected_output = remove_comment_lines(testcase.output)
4841

49-
program_text = '\n'.join(testcase.input)
50-
51-
options = Options()
52-
options.use_builtins_fixtures = True
53-
options.show_traceback = True
54-
options.strict_optional = True
55-
options.python_version = (3, 6)
56-
options.export_types = True
57-
58-
source = build.BuildSource('main', '__main__', program_text)
5942
try:
60-
# Construct input as a single single.
61-
# Parse and type check the input program.
62-
result = build.build(sources=[source],
63-
options=options,
64-
alt_lib_path=test_temp_dir)
43+
ir = build_ir_for_single_file(testcase.input)
6544
except CompileError as e:
6645
actual = e.messages
6746
else:
68-
if result.errors:
69-
actual = result.errors
70-
else:
71-
modules = genops.build_ir([result.files['__main__']], result.types)
72-
module = modules[0][1]
73-
actual = []
74-
for fn in module.functions:
75-
if is_empty_module_top_level(fn):
76-
# Skip trivial module top levels that only return.
77-
continue
78-
actual.extend(format_func(fn))
47+
actual = []
48+
for fn in ir:
49+
if is_empty_module_top_level(fn):
50+
# Skip trivial module top levels that only return.
51+
continue
52+
actual.extend(format_func(fn))
7953

8054
assert_test_output(testcase, actual, 'Invalid source code output',
8155
expected_output)
82-
83-
84-
# TODO: Use these to filter things?
85-
def get_func_names(expected: List[str]) -> List[str]:
86-
res = []
87-
for s in expected:
88-
m = re.match(r'def ([_a-zA-Z0-9.*$]+)\(', s)
89-
if m:
90-
res.append(m.group(1))
91-
return res
92-
93-
94-
def remove_comment_lines(a: List[str]) -> List[str]:
95-
"""Return a copy of array with comments removed.
96-
97-
Lines starting with '--' (but not with '---') are removed.
98-
"""
99-
r = []
100-
for s in a:
101-
if s.strip().startswith('--') and not s.strip().startswith('---'):
102-
pass
103-
else:
104-
r.append(s)
105-
return r

mypyc/test/test_refcount.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,16 @@
55
"""
66

77
import os.path
8-
from typing import List
98

109
from mypy.test.config import test_temp_dir
11-
from mypy.test.data import parse_test_cases, DataDrivenTestCase
10+
from mypy.test.data import DataDrivenTestCase
1211
from mypy.errors import CompileError
1312

14-
from mypyc.ops import format_func
13+
from mypyc.ops import format_func, is_empty_module_top_level
1514
from mypyc.refcount import insert_ref_count_opcodes
1615
from mypyc.test.testutil import (
17-
ICODE_GEN_BUILTINS,
18-
build_ir_for_single_file,
19-
use_custom_builtins,
20-
MypycDataSuite,
21-
assert_test_output
16+
ICODE_GEN_BUILTINS, use_custom_builtins, MypycDataSuite, build_ir_for_single_file,
17+
assert_test_output, remove_comment_lines
2218
)
2319

2420
files = [
@@ -32,19 +28,22 @@ class TestRefCountTransform(MypycDataSuite):
3228
optional_out = True
3329

3430
def run_case(self, testcase: DataDrivenTestCase) -> None:
35-
"""Perform a reference count opcode insertion transform test case."""
36-
31+
"""Perform a runtime checking transformation test case."""
3732
with use_custom_builtins(os.path.join(self.data_prefix, ICODE_GEN_BUILTINS), testcase):
33+
expected_output = remove_comment_lines(testcase.output)
34+
3835
try:
3936
ir = build_ir_for_single_file(testcase.input)
4037
except CompileError as e:
4138
actual = e.messages
4239
else:
43-
# Expect one function + module top level function.
44-
assert len(ir) == 2, "Only 1 function definition expected per test case"
45-
fn = ir[0]
46-
insert_ref_count_opcodes(fn)
47-
actual = format_func(fn)
48-
actual = actual[actual.index('L0:'):]
49-
50-
assert_test_output(testcase, actual, 'Invalid source code output')
40+
actual = []
41+
for fn in ir:
42+
if is_empty_module_top_level(fn):
43+
# Skip trivial module top levels that only return.
44+
continue
45+
insert_ref_count_opcodes(fn)
46+
actual.extend(format_func(fn))
47+
48+
assert_test_output(testcase, actual, 'Invalid source code output',
49+
expected_output)

mypyc/test/testutil.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import contextlib
44
import os.path
5+
import re
56
import shutil
67
from typing import List, Callable, Iterator, Optional
78

@@ -136,6 +137,29 @@ def assert_test_output(testcase: DataDrivenTestCase, actual: List[str],
136137
'{} ({}, line {})'.format(message, testcase.file, testcase.line))
137138

138139

140+
def get_func_names(expected: List[str]) -> List[str]:
141+
res = []
142+
for s in expected:
143+
m = re.match(r'def ([_a-zA-Z0-9.*$]+)\(', s)
144+
if m:
145+
res.append(m.group(1))
146+
return res
147+
148+
149+
def remove_comment_lines(a: List[str]) -> List[str]:
150+
"""Return a copy of array with comments removed.
151+
152+
Lines starting with '--' (but not with '---') are removed.
153+
"""
154+
r = []
155+
for s in a:
156+
if s.strip().startswith('--') and not s.strip().startswith('---'):
157+
pass
158+
else:
159+
r.append(s)
160+
return r
161+
162+
139163
def print_with_line_numbers(s: str) -> None:
140164
lines = s.splitlines()
141165
for i, line in enumerate(lines):

0 commit comments

Comments
 (0)