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.
24
35Notes:
46 - Only Linux is supported for now (TODO: add support for other profilers)
4143TARGET_DIR = "mypy.profile.tmpdir"
4244
4345
44- def _profile_self_check (target_dir : str ) -> None :
46+ def _profile_type_check (target_dir : str , code : str | None ) -> None :
4547 cache_dir = os .path .join (target_dir , ".mypy_cache" )
4648 if os .path .exists (cache_dir ):
4749 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
50+ args = []
51+ if code is None :
52+ args .extend (["--config-file" , "mypy_self_check.ini" ])
53+ for pat in "mypy/*.py" , "mypy/*/*.py" , "mypyc/*.py" , "mypyc/test/*.py" :
54+ args .extend (glob .glob (pat ))
55+ else :
56+ args .extend (["-c" , code ])
57+ check_cmd = ["python" , "-m" , "mypy" ] + args
58+ cmdline = ["perf" , "record" , "-g" ] + check_cmd
5359 t0 = time .time ()
5460 subprocess .run (cmdline , cwd = target_dir , check = True )
5561 elapsed = time .time () - t0
5662 print (f"{ elapsed :.2f} s elapsed" )
5763
5864
59- def profile_self_check (target_dir : str ) -> None :
65+ def profile_type_check (target_dir : str , code : str | None ) -> None :
6066 try :
61- _profile_self_check (target_dir )
67+ _profile_type_check (target_dir , code )
6268 except subprocess .CalledProcessError :
6369 print ("\n Profiling failed! You may missing some permissions." )
6470 print ("\n This may help (note that it has security implications):" )
@@ -92,7 +98,7 @@ def main() -> None:
9298 check_requirements ()
9399
94100 parser = argparse .ArgumentParser (
95- description = "Compile mypy and profile self checking using 'perf'."
101+ description = "Compile mypy and profile type checking using 'perf' (by default, self check) ."
96102 )
97103 parser .add_argument (
98104 "--multi-file" ,
@@ -102,9 +108,17 @@ def main() -> None:
102108 parser .add_argument (
103109 "--skip-compile" , action = "store_true" , help = "use compiled mypy from previous run"
104110 )
111+ parser .add_argument (
112+ "-c" ,
113+ metavar = "CODE" ,
114+ default = None ,
115+ type = str ,
116+ help = "profile type checking Python code fragment instead of mypy self-check" ,
117+ )
105118 args = parser .parse_args ()
106119 multi_file : bool = args .multi_file
107120 skip_compile : bool = args .skip_compile
121+ code : str | None = args .c
108122
109123 target_dir = TARGET_DIR
110124
@@ -116,7 +130,7 @@ def main() -> None:
116130 elif not os .path .isdir (target_dir ):
117131 sys .exit ("error: Can't find compile mypy from previous run -- can't use --skip-compile" )
118132
119- profile_self_check (target_dir )
133+ profile_type_check (target_dir , code )
120134
121135 print ()
122136 print ('NOTE: Compile CPython using CFLAGS="-O2 -g -fno-omit-frame-pointer" for good results' )
0 commit comments