| """Test cases for invoking mypyc on the command line. |
| |
| These are slow -- do not add test cases unless you have a very good reason to do so. |
| """ |
| |
| from __future__ import annotations |
| |
| import glob |
| import os |
| import os.path |
| import re |
| import subprocess |
| import sys |
| |
| from mypy.test.config import test_temp_dir |
| from mypy.test.data import DataDrivenTestCase |
| from mypy.test.helpers import normalize_error_messages |
| from mypyc.test.testutil import MypycDataSuite, assert_test_output |
| |
| files = ["commandline.test"] |
| |
| |
| base_path = os.path.join(os.path.dirname(__file__), "..", "..") |
| |
| python3_path = sys.executable |
| |
| |
| class TestCommandLine(MypycDataSuite): |
| files = files |
| base_path = test_temp_dir |
| optional_out = True |
| |
| def run_case(self, testcase: DataDrivenTestCase) -> None: |
| # Parse options from test case description (arguments must not have spaces) |
| text = "\n".join(testcase.input) |
| m = re.search(r"# *cmd: *(.*)", text) |
| assert m is not None, 'Test case missing "# cmd: <files>" section' |
| args = m.group(1).split() |
| |
| # Write main program to run (not compiled) |
| program = "_%s.py" % testcase.name |
| program_path = os.path.join(test_temp_dir, program) |
| with open(program_path, "w") as f: |
| f.write(text) |
| |
| env = os.environ.copy() |
| env["PYTHONPATH"] = base_path |
| |
| out = b"" |
| try: |
| # Compile program |
| cmd = subprocess.run( |
| [sys.executable, "-m", "mypyc", *args], |
| stdout=subprocess.PIPE, |
| stderr=subprocess.STDOUT, |
| cwd="tmp", |
| env=env, |
| ) |
| if "ErrorOutput" in testcase.name or cmd.returncode != 0: |
| out += cmd.stdout |
| elif "WarningOutput" in testcase.name: |
| # Strip out setuptools build related output since we're only |
| # interested in the messages emitted during compilation. |
| messages, _, _ = cmd.stdout.partition(b"running build_ext") |
| out += messages |
| |
| if cmd.returncode == 0: |
| # Run main program |
| out += subprocess.check_output([python3_path, program], cwd="tmp") |
| finally: |
| suffix = "pyd" if sys.platform == "win32" else "so" |
| so_paths = glob.glob(f"tmp/**/*.{suffix}", recursive=True) |
| for path in so_paths: |
| os.remove(path) |
| |
| # Strip out 'tmp/' from error message paths in the testcase output, |
| # due to a mismatch between this test and mypy's test suite. |
| expected = [x.replace("tmp/", "") for x in testcase.output] |
| |
| # Verify output |
| actual = normalize_error_messages(out.decode().splitlines()) |
| assert_test_output(testcase, actual, "Invalid output", expected=expected) |