testdiff.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. """Test cases for AST diff (used for fine-grained incremental checking)"""
  2. from __future__ import annotations
  3. import os
  4. from mypy import build
  5. from mypy.defaults import PYTHON3_VERSION
  6. from mypy.errors import CompileError
  7. from mypy.modulefinder import BuildSource
  8. from mypy.nodes import MypyFile
  9. from mypy.options import Options
  10. from mypy.server.astdiff import compare_symbol_table_snapshots, snapshot_symbol_table
  11. from mypy.test.config import test_temp_dir
  12. from mypy.test.data import DataDrivenTestCase, DataSuite
  13. from mypy.test.helpers import assert_string_arrays_equal, parse_options
  14. class ASTDiffSuite(DataSuite):
  15. files = ["diff.test"]
  16. def run_case(self, testcase: DataDrivenTestCase) -> None:
  17. first_src = "\n".join(testcase.input)
  18. files_dict = dict(testcase.files)
  19. second_src = files_dict["tmp/next.py"]
  20. options = parse_options(first_src, testcase, 1)
  21. messages1, files1 = self.build(first_src, options)
  22. messages2, files2 = self.build(second_src, options)
  23. a = []
  24. if messages1:
  25. a.extend(messages1)
  26. if messages2:
  27. a.append("== next ==")
  28. a.extend(messages2)
  29. assert (
  30. files1 is not None and files2 is not None
  31. ), "cases where CompileError occurred should not be run"
  32. prefix = "__main__"
  33. snapshot1 = snapshot_symbol_table(prefix, files1["__main__"].names)
  34. snapshot2 = snapshot_symbol_table(prefix, files2["__main__"].names)
  35. diff = compare_symbol_table_snapshots(prefix, snapshot1, snapshot2)
  36. for trigger in sorted(diff):
  37. a.append(trigger)
  38. assert_string_arrays_equal(
  39. testcase.output, a, f"Invalid output ({testcase.file}, line {testcase.line})"
  40. )
  41. def build(self, source: str, options: Options) -> tuple[list[str], dict[str, MypyFile] | None]:
  42. options.use_builtins_fixtures = True
  43. options.show_traceback = True
  44. options.cache_dir = os.devnull
  45. options.python_version = PYTHON3_VERSION
  46. options.allow_empty_bodies = True
  47. try:
  48. result = build.build(
  49. sources=[BuildSource("main", None, source)],
  50. options=options,
  51. alt_lib_path=test_temp_dir,
  52. )
  53. except CompileError as e:
  54. # TODO: Is it okay to return None?
  55. return e.messages, None
  56. return result.errors, result.files