49
49
CACHE_PATH = ".incremental_checker_cache.json"
50
50
MYPY_REPO_URL = "https://github.com/python/mypy.git"
51
51
MYPY_TARGET_FILE = "mypy"
52
+ DAEMON_CMD = ["python3" , "-m" , "mypy.dmypy" ]
52
53
53
54
JsonDict = Dict [str , Any ]
54
55
@@ -121,23 +122,30 @@ def get_nth_commit(repo_folder_path, n: int) -> Tuple[str, str]:
121
122
def run_mypy (target_file_path : Optional [str ],
122
123
mypy_cache_path : str ,
123
124
mypy_script : Optional [str ],
124
- incremental : bool = True ,
125
+ * ,
126
+ incremental : bool = False ,
127
+ daemon : bool = False ,
125
128
verbose : bool = False ) -> Tuple [float , str ]:
126
129
"""Runs mypy against `target_file_path` and returns what mypy prints to stdout as a string.
127
130
128
131
If `incremental` is set to True, this function will use store and retrieve all caching data
129
132
inside `mypy_cache_path`. If `verbose` is set to True, this function will pass the "-v -v"
130
133
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.
131
136
"""
132
- if mypy_script is None :
133
- command = [ "python3 " , "-m" , "mypy " ]
137
+ if daemon :
138
+ command = DAEMON_CMD + [ "check " , "-q " ]
134
139
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" ])
141
149
if target_file_path is not None :
142
150
command .append (target_file_path )
143
151
start = time .time ()
@@ -148,6 +156,21 @@ def run_mypy(target_file_path: Optional[str],
148
156
return runtime , output
149
157
150
158
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
+
151
174
def load_cache (incremental_cache_path : str = CACHE_PATH ) -> JsonDict :
152
175
if os .path .exists (incremental_cache_path ):
153
176
with open (incremental_cache_path , 'r' ) as stream :
@@ -196,7 +219,9 @@ def test_incremental(commits: List[Tuple[str, str]],
196
219
temp_repo_path : str ,
197
220
target_file_path : Optional [str ],
198
221
mypy_cache_path : str ,
199
- mypy_script : Optional [str ]) -> None :
222
+ * ,
223
+ mypy_script : Optional [str ] = None ,
224
+ daemon : bool = False ) -> None :
200
225
"""Runs incremental mode on all `commits` to verify the output matches the expected output.
201
226
202
227
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]],
208
233
print ('Now testing commit {0}: "{1}"' .format (commit_id , message ))
209
234
execute (["git" , "-C" , temp_repo_path , "checkout" , commit_id ])
210
235
runtime , output = run_mypy (target_file_path , mypy_cache_path , mypy_script ,
211
- incremental = True )
236
+ incremental = True , daemon = daemon )
212
237
expected_runtime = cache [commit_id ]['runtime' ] # type: float
213
238
expected_output = cache [commit_id ]['output' ] # type: str
214
239
if output != expected_output :
@@ -278,11 +303,15 @@ def test_repo(target_repo_url: str, temp_repo_path: str,
278
303
save_cache (cache , incremental_cache_path )
279
304
280
305
# Stage 4: Rewind and re-run mypy (with incremental mode enabled)
306
+ if params .daemon :
307
+ start_daemon (mypy_cache_path , False )
281
308
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 )
283
310
284
- # Stage 5: Remove temp files
311
+ # Stage 5: Remove temp files, stop daemon
285
312
cleanup (temp_repo_path , mypy_cache_path )
313
+ if params .daemon :
314
+ stop_daemon ()
286
315
287
316
288
317
def main () -> None :
@@ -309,6 +338,8 @@ def main() -> None:
309
338
parser .add_argument ("--sample" , type = int , help = "use a random sample of size SAMPLE" )
310
339
parser .add_argument ("--seed" , type = str , help = "random seed" )
311
340
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)" )
312
343
313
344
if len (sys .argv [1 :]) == 0 :
314
345
parser .print_help ()
0 commit comments