testparse.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. """Tests for the mypy parser."""
  2. from __future__ import annotations
  3. import sys
  4. from pytest import skip
  5. from mypy import defaults
  6. from mypy.config_parser import parse_mypy_comments
  7. from mypy.errors import CompileError
  8. from mypy.options import Options
  9. from mypy.parse import parse
  10. from mypy.test.data import DataDrivenTestCase, DataSuite
  11. from mypy.test.helpers import assert_string_arrays_equal, find_test_files, parse_options
  12. from mypy.util import get_mypy_comments
  13. class ParserSuite(DataSuite):
  14. required_out_section = True
  15. base_path = "."
  16. files = find_test_files(pattern="parse*.test", exclude=["parse-errors.test"])
  17. if sys.version_info < (3, 10):
  18. files.remove("parse-python310.test")
  19. def run_case(self, testcase: DataDrivenTestCase) -> None:
  20. test_parser(testcase)
  21. def test_parser(testcase: DataDrivenTestCase) -> None:
  22. """Perform a single parser test case.
  23. The argument contains the description of the test case.
  24. """
  25. options = Options()
  26. options.force_uppercase_builtins = True
  27. options.hide_error_codes = True
  28. if testcase.file.endswith("python310.test"):
  29. options.python_version = (3, 10)
  30. else:
  31. options.python_version = defaults.PYTHON3_VERSION
  32. source = "\n".join(testcase.input)
  33. # Apply mypy: comments to options.
  34. comments = get_mypy_comments(source)
  35. changes, _ = parse_mypy_comments(comments, options)
  36. options = options.apply_changes(changes)
  37. try:
  38. n = parse(
  39. bytes(source, "ascii"), fnam="main", module="__main__", errors=None, options=options
  40. )
  41. a = n.str_with_options(options).split("\n")
  42. except CompileError as e:
  43. a = e.messages
  44. assert_string_arrays_equal(
  45. testcase.output, a, f"Invalid parser output ({testcase.file}, line {testcase.line})"
  46. )
  47. # The file name shown in test case output. This is displayed in error
  48. # messages, and must match the file name in the test case descriptions.
  49. INPUT_FILE_NAME = "file"
  50. class ParseErrorSuite(DataSuite):
  51. required_out_section = True
  52. base_path = "."
  53. files = ["parse-errors.test"]
  54. def run_case(self, testcase: DataDrivenTestCase) -> None:
  55. test_parse_error(testcase)
  56. def test_parse_error(testcase: DataDrivenTestCase) -> None:
  57. try:
  58. options = parse_options("\n".join(testcase.input), testcase, 0)
  59. if options.python_version != sys.version_info[:2]:
  60. skip()
  61. # Compile temporary file. The test file contains non-ASCII characters.
  62. parse(
  63. bytes("\n".join(testcase.input), "utf-8"), INPUT_FILE_NAME, "__main__", None, options
  64. )
  65. raise AssertionError("No errors reported")
  66. except CompileError as e:
  67. if e.module_with_blocker is not None:
  68. assert e.module_with_blocker == "__main__"
  69. # Verify that there was a compile error and that the error messages
  70. # are equivalent.
  71. assert_string_arrays_equal(
  72. testcase.output,
  73. e.messages,
  74. f"Invalid compiler output ({testcase.file}, line {testcase.line})",
  75. )