1
1
"""Server for mypy daemon mode.
2
2
3
- Only supports UNIX-like systems.
4
-
5
3
This implements a daemon process which keeps useful state in memory
6
4
to enable fine-grained incremental reprocessing of changes.
7
5
"""
8
6
7
+ import argparse
9
8
import base64
9
+ import io
10
10
import json
11
11
import os
12
12
import pickle
29
29
from mypy .modulefinder import BuildSource , compute_search_paths
30
30
from mypy .options import Options
31
31
from mypy .typestate import reset_global_state
32
+ from mypy .util import redirect_stderr , redirect_stdout
32
33
from mypy .version import __version__
33
34
34
35
@@ -270,11 +271,19 @@ def cmd_stop(self) -> Dict[str, object]:
270
271
def cmd_run (self , version : str , args : Sequence [str ]) -> Dict [str , object ]:
271
272
"""Check a list of files, triggering a restart if needed."""
272
273
try :
273
- sources , options = mypy .main .process_options (
274
- ['-i' ] + list (args ),
275
- require_targets = True ,
276
- server_options = True ,
277
- fscache = self .fscache )
274
+ # Process options can exit on improper arguments, so we need to catch that and
275
+ # capture stderr so the client can report it
276
+ stderr = io .StringIO ()
277
+ stdout = io .StringIO ()
278
+ with redirect_stderr (stderr ):
279
+ with redirect_stdout (stdout ):
280
+ sources , options = mypy .main .process_options (
281
+ ['-i' ] + list (args ),
282
+ require_targets = True ,
283
+ server_options = True ,
284
+ fscache = self .fscache ,
285
+ program = 'mypy-daemon' ,
286
+ header = argparse .SUPPRESS )
278
287
# Signal that we need to restart if the options have changed
279
288
if self .options_snapshot != options .snapshot ():
280
289
return {'restart' : 'configuration changed' }
@@ -288,6 +297,8 @@ def cmd_run(self, version: str, args: Sequence[str]) -> Dict[str, object]:
288
297
return {'restart' : 'plugins changed' }
289
298
except InvalidSourceList as err :
290
299
return {'out' : '' , 'err' : str (err ), 'status' : 2 }
300
+ except SystemExit as e :
301
+ return {'out' : stdout .getvalue (), 'err' : stderr .getvalue (), 'status' : e .code }
291
302
return self .check (sources )
292
303
293
304
def cmd_check (self , files : Sequence [str ]) -> Dict [str , object ]:
0 commit comments