mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
75 lines
2.3 KiB
Python
75 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
import os.path
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
|
|
# Examples:
|
|
# Cannot find implementation or library stub for module named "codeowners"
|
|
# Skipping analyzing "uwsgidecorators": module is installed, but missing library stubs or py.typed marker
|
|
PAT = re.compile('(?:library stub for module named |Skipping analyzing )"([^"]+)"')
|
|
|
|
|
|
def _format_mods(mods: list[str]) -> str:
|
|
return "".join(f' "{mod}",\n' for mod in mods)
|
|
|
|
|
|
def main() -> int:
|
|
shutil.rmtree(".mypy_cache", ignore_errors=True)
|
|
|
|
with open("pyproject.toml") as f:
|
|
contents = f.read()
|
|
msg_stubs = "missing 3rd party stubs"
|
|
before, stubs_begin, rest = contents.partition(f"# begin: {msg_stubs}\n")
|
|
_, stubs_end, rest = rest.partition(f"# end: {msg_stubs}\n")
|
|
|
|
msg_ignore = "sentry modules with typing issues"
|
|
between, ignore_begin, rest = rest.partition(f"# begin: {msg_ignore}\n")
|
|
ignore, ignore_end, rest = rest.partition(f"# end: {msg_ignore}\n")
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
cfg = os.path.join(tmpdir, "mypy.toml")
|
|
with open(cfg, "w") as f:
|
|
f.write(before + stubs_begin + stubs_end + between + ignore_begin + ignore_end + rest)
|
|
|
|
seen = set()
|
|
out = subprocess.run(("mypy", "--config", cfg, *sys.argv[1:]), capture_output=True)
|
|
for line in out.stdout.decode().splitlines():
|
|
match = PAT.search(line)
|
|
if match is not None and match[1] not in seen:
|
|
seen.add(match[1])
|
|
|
|
mods: list[str] = []
|
|
for mod in sorted(seen):
|
|
if not mods or not mod.startswith(f"{mods[-1]}."):
|
|
mods.append(mod)
|
|
mods_s = "".join(f' "{mod}.*",\n' for mod in mods)
|
|
stubs = (
|
|
f"# - add .pyi files to fixtures/stubs-for-mypy\n"
|
|
f"# - or find a 3rd party stub\n"
|
|
f"[[tool.mypy.overrides]]\n"
|
|
f"module = [\n{mods_s}]\n"
|
|
f"ignore_missing_imports = true\n"
|
|
)
|
|
with open("pyproject.toml", "w") as f:
|
|
f.write(
|
|
before
|
|
+ stubs_begin
|
|
+ stubs
|
|
+ stubs_end
|
|
+ between
|
|
+ ignore_begin
|
|
+ ignore
|
|
+ ignore_end
|
|
+ rest
|
|
)
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|