test_commandline.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. """Test cases for invoking mypyc on the command line.
  2. These are slow -- do not add test cases unless you have a very good reason to do so.
  3. """
  4. from __future__ import annotations
  5. import glob
  6. import os
  7. import os.path
  8. import re
  9. import subprocess
  10. import sys
  11. from mypy.test.config import test_temp_dir
  12. from mypy.test.data import DataDrivenTestCase
  13. from mypy.test.helpers import normalize_error_messages
  14. from mypyc.test.testutil import MypycDataSuite, assert_test_output
  15. files = ["commandline.test"]
  16. base_path = os.path.join(os.path.dirname(__file__), "..", "..")
  17. python3_path = sys.executable
  18. class TestCommandLine(MypycDataSuite):
  19. files = files
  20. base_path = test_temp_dir
  21. optional_out = True
  22. def run_case(self, testcase: DataDrivenTestCase) -> None:
  23. # Parse options from test case description (arguments must not have spaces)
  24. text = "\n".join(testcase.input)
  25. m = re.search(r"# *cmd: *(.*)", text)
  26. assert m is not None, 'Test case missing "# cmd: <files>" section'
  27. args = m.group(1).split()
  28. # Write main program to run (not compiled)
  29. program = "_%s.py" % testcase.name
  30. program_path = os.path.join(test_temp_dir, program)
  31. with open(program_path, "w") as f:
  32. f.write(text)
  33. env = os.environ.copy()
  34. env["PYTHONPATH"] = base_path
  35. out = b""
  36. try:
  37. # Compile program
  38. cmd = subprocess.run(
  39. [sys.executable, "-m", "mypyc", *args],
  40. stdout=subprocess.PIPE,
  41. stderr=subprocess.STDOUT,
  42. cwd="tmp",
  43. env=env,
  44. )
  45. if "ErrorOutput" in testcase.name or cmd.returncode != 0:
  46. out += cmd.stdout
  47. elif "WarningOutput" in testcase.name:
  48. # Strip out setuptools build related output since we're only
  49. # interested in the messages emitted during compilation.
  50. messages, _, _ = cmd.stdout.partition(b"running build_ext")
  51. out += messages
  52. if cmd.returncode == 0:
  53. # Run main program
  54. out += subprocess.check_output([python3_path, program], cwd="tmp")
  55. finally:
  56. suffix = "pyd" if sys.platform == "win32" else "so"
  57. so_paths = glob.glob(f"tmp/**/*.{suffix}", recursive=True)
  58. for path in so_paths:
  59. os.remove(path)
  60. # Strip out 'tmp/' from error message paths in the testcase output,
  61. # due to a mismatch between this test and mypy's test suite.
  62. expected = [x.replace("tmp/", "") for x in testcase.output]
  63. # Verify output
  64. actual = normalize_error_messages(out.decode().splitlines())
  65. assert_test_output(testcase, actual, "Invalid output", expected=expected)