1
- """Compile mypy using mypyc and profile self-check using perf.
1
+ """Compile mypy using mypyc and profile type checking using perf.
2
+
3
+ By default does a self check.
2
4
3
5
Notes:
4
6
- Only Linux is supported for now (TODO: add support for other profilers)
23
25
CFLAGS="-O2 -g -fno-omit-frame-pointer"
24
26
"""
25
27
28
+ from __future__ import annotations
29
+
26
30
import argparse
27
31
import glob
28
32
import os
41
45
TARGET_DIR = "mypy.profile.tmpdir"
42
46
43
47
44
- def _profile_self_check (target_dir : str ) -> None :
48
+ def _profile_type_check (target_dir : str , code : str | None ) -> None :
45
49
cache_dir = os .path .join (target_dir , ".mypy_cache" )
46
50
if os .path .exists (cache_dir ):
47
51
shutil .rmtree (cache_dir )
48
- files = []
49
- for pat in "mypy/*.py" , "mypy/*/*.py" , "mypyc/*.py" , "mypyc/test/*.py" :
50
- files .extend (glob .glob (pat ))
51
- self_check_cmd = ["python" , "-m" , "mypy" , "--config-file" , "mypy_self_check.ini" ] + files
52
- cmdline = ["perf" , "record" , "-g" ] + self_check_cmd
52
+ args = []
53
+ if code is None :
54
+ args .extend (["--config-file" , "mypy_self_check.ini" ])
55
+ for pat in "mypy/*.py" , "mypy/*/*.py" , "mypyc/*.py" , "mypyc/test/*.py" :
56
+ args .extend (glob .glob (pat ))
57
+ else :
58
+ args .extend (["-c" , code ])
59
+ check_cmd = ["python" , "-m" , "mypy" ] + args
60
+ cmdline = ["perf" , "record" , "-g" ] + check_cmd
53
61
t0 = time .time ()
54
62
subprocess .run (cmdline , cwd = target_dir , check = True )
55
63
elapsed = time .time () - t0
56
64
print (f"{ elapsed :.2f} s elapsed" )
57
65
58
66
59
- def profile_self_check (target_dir : str ) -> None :
67
+ def profile_type_check (target_dir : str , code : str | None ) -> None :
60
68
try :
61
- _profile_self_check (target_dir )
69
+ _profile_type_check (target_dir , code )
62
70
except subprocess .CalledProcessError :
63
71
print ("\n Profiling failed! You may missing some permissions." )
64
72
print ("\n This may help (note that it has security implications):" )
@@ -92,7 +100,7 @@ def main() -> None:
92
100
check_requirements ()
93
101
94
102
parser = argparse .ArgumentParser (
95
- description = "Compile mypy and profile self checking using 'perf'."
103
+ description = "Compile mypy and profile type checking using 'perf' (by default, self check) ."
96
104
)
97
105
parser .add_argument (
98
106
"--multi-file" ,
@@ -102,9 +110,17 @@ def main() -> None:
102
110
parser .add_argument (
103
111
"--skip-compile" , action = "store_true" , help = "use compiled mypy from previous run"
104
112
)
113
+ parser .add_argument (
114
+ "-c" ,
115
+ metavar = "CODE" ,
116
+ default = None ,
117
+ type = str ,
118
+ help = "profile type checking Python code fragment instead of mypy self-check" ,
119
+ )
105
120
args = parser .parse_args ()
106
121
multi_file : bool = args .multi_file
107
122
skip_compile : bool = args .skip_compile
123
+ code : str | None = args .c
108
124
109
125
target_dir = TARGET_DIR
110
126
@@ -116,7 +132,7 @@ def main() -> None:
116
132
elif not os .path .isdir (target_dir ):
117
133
sys .exit ("error: Can't find compile mypy from previous run -- can't use --skip-compile" )
118
134
119
- profile_self_check (target_dir )
135
+ profile_type_check (target_dir , code )
120
136
121
137
print ()
122
138
print ('NOTE: Compile CPython using CFLAGS="-O2 -g -fno-omit-frame-pointer" for good results' )
0 commit comments