4949CACHE_PATH = ".incremental_checker_cache.json"
5050MYPY_REPO_URL = "https://github.com/python/mypy.git"
5151MYPY_TARGET_FILE = "mypy"
52+ DAEMON_CMD = ["python3" , "-m" , "mypy.dmypy" ]
5253
5354JsonDict = Dict [str , Any ]
5455
@@ -121,23 +122,30 @@ def get_nth_commit(repo_folder_path, n: int) -> Tuple[str, str]:
121122def run_mypy (target_file_path : Optional [str ],
122123 mypy_cache_path : str ,
123124 mypy_script : Optional [str ],
124- incremental : bool = True ,
125+ * ,
126+ incremental : bool = False ,
127+ daemon : bool = False ,
125128 verbose : bool = False ) -> Tuple [float , str ]:
126129 """Runs mypy against `target_file_path` and returns what mypy prints to stdout as a string.
127130
128131 If `incremental` is set to True, this function will use store and retrieve all caching data
129132 inside `mypy_cache_path`. If `verbose` is set to True, this function will pass the "-v -v"
130133 flags to mypy to make it output debugging information.
134+
135+ If `daemon` is True, we use daemon mode; the daemon must be started and stopped by the caller.
131136 """
132- if mypy_script is None :
133- command = [ "python3 " , "-m" , "mypy " ]
137+ if daemon :
138+ command = DAEMON_CMD + [ "check " , "-q " ]
134139 else :
135- command = [mypy_script ]
136- command .extend (["--cache-dir" , mypy_cache_path ])
137- if incremental :
138- command .append ("--incremental" )
139- if verbose :
140- command .extend (["-v" , "-v" ])
140+ if mypy_script is None :
141+ command = ["python3" , "-m" , "mypy" ]
142+ else :
143+ command = [mypy_script ]
144+ command .extend (["--cache-dir" , mypy_cache_path ])
145+ if incremental :
146+ command .append ("--incremental" )
147+ if verbose :
148+ command .extend (["-v" , "-v" ])
141149 if target_file_path is not None :
142150 command .append (target_file_path )
143151 start = time .time ()
@@ -148,6 +156,21 @@ def run_mypy(target_file_path: Optional[str],
148156 return runtime , output
149157
150158
159+ def start_daemon (mypy_cache_path : str , verbose : bool ) -> None :
160+ stdout , stderr , status = execute (DAEMON_CMD + ["status" ], fail_on_error = False )
161+ if status :
162+ cmd = DAEMON_CMD + ["start" , "--" , "--cache-dir" , mypy_cache_path ]
163+ if verbose :
164+ cmd .extend (["-v" , "-v" ])
165+ execute (cmd )
166+
167+
168+ def stop_daemon () -> None :
169+ stdout , stderr , status = execute (DAEMON_CMD + ["status" ], fail_on_error = False )
170+ if status == 0 :
171+ execute (DAEMON_CMD + ["stop" ])
172+
173+
151174def load_cache (incremental_cache_path : str = CACHE_PATH ) -> JsonDict :
152175 if os .path .exists (incremental_cache_path ):
153176 with open (incremental_cache_path , 'r' ) as stream :
@@ -196,7 +219,9 @@ def test_incremental(commits: List[Tuple[str, str]],
196219 temp_repo_path : str ,
197220 target_file_path : Optional [str ],
198221 mypy_cache_path : str ,
199- mypy_script : Optional [str ]) -> None :
222+ * ,
223+ mypy_script : Optional [str ] = None ,
224+ daemon : bool = False ) -> None :
200225 """Runs incremental mode on all `commits` to verify the output matches the expected output.
201226
202227 This function runs mypy on the `target_file_path` inside the `temp_repo_path`. The
@@ -208,7 +233,7 @@ def test_incremental(commits: List[Tuple[str, str]],
208233 print ('Now testing commit {0}: "{1}"' .format (commit_id , message ))
209234 execute (["git" , "-C" , temp_repo_path , "checkout" , commit_id ])
210235 runtime , output = run_mypy (target_file_path , mypy_cache_path , mypy_script ,
211- incremental = True )
236+ incremental = True , daemon = daemon )
212237 expected_runtime = cache [commit_id ]['runtime' ] # type: float
213238 expected_output = cache [commit_id ]['output' ] # type: str
214239 if output != expected_output :
@@ -278,11 +303,15 @@ def test_repo(target_repo_url: str, temp_repo_path: str,
278303 save_cache (cache , incremental_cache_path )
279304
280305 # Stage 4: Rewind and re-run mypy (with incremental mode enabled)
306+ if params .daemon :
307+ start_daemon (mypy_cache_path , False )
281308 test_incremental (commits , cache , temp_repo_path , target_file_path , mypy_cache_path ,
282- mypy_script = params .mypy_script )
309+ mypy_script = params .mypy_script , daemon = params . daemon )
283310
284- # Stage 5: Remove temp files
311+ # Stage 5: Remove temp files, stop daemon
285312 cleanup (temp_repo_path , mypy_cache_path )
313+ if params .daemon :
314+ stop_daemon ()
286315
287316
288317def main () -> None :
@@ -309,6 +338,8 @@ def main() -> None:
309338 parser .add_argument ("--sample" , type = int , help = "use a random sample of size SAMPLE" )
310339 parser .add_argument ("--seed" , type = str , help = "random seed" )
311340 parser .add_argument ("--mypy-script" , type = str , help = "alternate mypy script to run" )
341+ parser .add_argument ("--daemon" , action = 'store_true' ,
342+ help = "use mypy daemon instead of incremental (highly experimental)" )
312343
313344 if len (sys .argv [1 :]) == 0 :
314345 parser .print_help ()
0 commit comments