-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Expand file tree
/
Copy pathlog_trace_check.py
More file actions
85 lines (67 loc) · 2.56 KB
/
log_trace_check.py
File metadata and controls
85 lines (67 loc) · 2.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
"""Compile mypy using mypyc with trace logging enabled, and collect a trace.
The trace log can be used to analyze low-level performance bottlenecks.
By default does a self check as the workload.
This works on all supported platforms, unlike some of our other performance tools.
"""
from __future__ import annotations
import argparse
import glob
import os
import shutil
import subprocess
import sys
import time
from perf_compare import build_mypy, clone
# Generated files, including binaries, go under this directory to avoid overwriting user state.
TARGET_DIR = "mypy.log_trace.tmpdir"
def perform_type_check(target_dir: str, code: str | None) -> None:
cache_dir = os.path.join(target_dir, ".mypy_cache")
if os.path.exists(cache_dir):
shutil.rmtree(cache_dir)
args = []
if code is None:
args.extend(["--config-file", "mypy_self_check.ini"])
for pat in "mypy/*.py", "mypy/*/*.py", "mypyc/*.py", "mypyc/test/*.py":
args.extend(glob.glob(pat))
else:
args.extend(["-c", code])
check_cmd = ["python", "-m", "mypy"] + args
t0 = time.time()
subprocess.run(check_cmd, cwd=target_dir, check=True)
elapsed = time.time() - t0
print(f"{elapsed:.2f}s elapsed")
def main() -> None:
parser = argparse.ArgumentParser(
description="Compile mypy and collect a trace log while type checking (by default, self check)."
)
parser.add_argument(
"--multi-file",
action="store_true",
help="compile mypy into one C file per module (to reduce RAM use during compilation)",
)
parser.add_argument(
"--skip-compile", action="store_true", help="use compiled mypy from previous run"
)
parser.add_argument(
"-c",
metavar="CODE",
default=None,
type=str,
help="type check Python code fragment instead of mypy self-check",
)
args = parser.parse_args()
multi_file: bool = args.multi_file
skip_compile: bool = args.skip_compile
code: str | None = args.c
target_dir = TARGET_DIR
if not skip_compile:
clone(target_dir, "HEAD")
print(f"Building mypy in {target_dir} with trace logging enabled...")
build_mypy(target_dir, multi_file, log_trace=True, opt_level="0")
elif not os.path.isdir(target_dir):
sys.exit("error: Can't find compile mypy from previous run -- can't use --skip-compile")
perform_type_check(target_dir, code)
trace_fnam = os.path.join(target_dir, "mypyc_trace.txt")
print(f"Generated event trace log in {trace_fnam}")
if __name__ == "__main__":
main()