"""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: " 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)