make_module_ignores.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. from __future__ import annotations
  2. import re
  3. import shutil
  4. import subprocess
  5. import sys
  6. ERROR_RE = re.compile(r".*error:.*\[([^]]+)\]$")
  7. def main() -> int:
  8. shutil.rmtree(".mypy_cache", ignore_errors=True)
  9. codes = set()
  10. filenames = set()
  11. out = subprocess.run(
  12. (sys.executable, "-m", "tools.mypy_helpers.mypy_without_ignores", *sys.argv[1:]),
  13. capture_output=True,
  14. )
  15. for line in out.stdout.decode().splitlines():
  16. filename, _, _ = line.partition(":")
  17. if filename.endswith(".py"):
  18. filenames.add(filename)
  19. match = ERROR_RE.match(line)
  20. if match is not None:
  21. codes.add(match[1])
  22. mods = []
  23. for filename in sorted(filenames):
  24. # TODO: removeprefix / removesuffix python 3.9+
  25. if filename.endswith(".py"):
  26. filename = filename[: -len(".py")]
  27. if filename.startswith("src/"):
  28. filename = filename[len("src/") :]
  29. if filename.endswith("/__init__"):
  30. filename = filename[: -len("/__init__")]
  31. mods.append(filename.replace("/", "."))
  32. mods_s = "".join(f' "{mod}",\n' for mod in mods)
  33. codes_s = "".join(f' "{code}",\n' for code in sorted(codes))
  34. generated = (
  35. f"# - remove the module from the list and fix the issues!\n"
  36. f"# - python3 -m tools.mypy_helpers.find_easiest_modules\n"
  37. f"[[tool.mypy.overrides]]\n"
  38. f"module = [\n{mods_s}]\n"
  39. f"disable_error_code = [\n{codes_s}]\n"
  40. )
  41. with open("pyproject.toml") as f:
  42. src = f.read()
  43. msg = "sentry modules with typing issues"
  44. before, begin, rest = src.partition(f"# begin: {msg}\n")
  45. _, end, rest = rest.partition(f"# end: {msg}\n")
  46. with open("pyproject.toml", "w") as f:
  47. f.write(before + begin + generated + end + rest)
  48. return 0
  49. if __name__ == "__main__":
  50. raise SystemExit(main())