Skip to content

Commit

Permalink
Pass log-file and timeout args to daemon as proper args (#15227)
Browse files Browse the repository at this point in the history
Currently, when starting the mypy daemon, we're passing the timeout and
log_file as part of the pickled options. This can cause problems if the
daemon has issues with the pickling. In this case we won't be able to
log what the problem was.
Let's pass the log_file and timeout as first class args. This also has
the advantage that we can now start the daemon in the foreground with
these args from the command line in a human writeable way.
  • Loading branch information
svalentin authored May 16, 2023
1 parent 16667f3 commit ce2c918
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 9 deletions.
18 changes: 10 additions & 8 deletions mypy/dmypy/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ def __init__(self, prog: str) -> None:
p.add_argument(
"--timeout", metavar="TIMEOUT", type=int, help="Server shutdown timeout (in seconds)"
)
p.add_argument("--log-file", metavar="FILE", type=str, help="Direct daemon stdout/stderr to FILE")
p.add_argument(
"flags", metavar="FLAG", nargs="*", type=str, help="Regular mypy flags (precede with --)"
)
Expand Down Expand Up @@ -608,21 +609,22 @@ def do_daemon(args: argparse.Namespace) -> None:
# Lazy import so this import doesn't slow down other commands.
from mypy.dmypy_server import Server, process_start_options

if args.log_file:
sys.stdout = sys.stderr = open(args.log_file, "a", buffering=1)
fd = sys.stdout.fileno()
os.dup2(fd, 2)
os.dup2(fd, 1)

if args.options_data:
from mypy.options import Options

options_dict, timeout, log_file = pickle.loads(base64.b64decode(args.options_data))
options_dict = pickle.loads(base64.b64decode(args.options_data))
options_obj = Options()
options = options_obj.apply_changes(options_dict)
if log_file:
sys.stdout = sys.stderr = open(log_file, "a", buffering=1)
fd = sys.stdout.fileno()
os.dup2(fd, 2)
os.dup2(fd, 1)
else:
options = process_start_options(args.flags, allow_sources=False)
timeout = args.timeout
Server(options, args.status_file, timeout=timeout).serve()

Server(options, args.status_file, timeout=args.timeout).serve()


@action(help_parser)
Expand Down
6 changes: 5 additions & 1 deletion mypy/dmypy_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,12 @@ def daemonize(
It also pickles the options to be unpickled by mypy.
"""
command = [sys.executable, "-m", "mypy.dmypy", "--status-file", status_file, "daemon"]
pickled_options = pickle.dumps((options.snapshot(), timeout, log_file))
pickled_options = pickle.dumps(options.snapshot())
command.append(f'--options-data="{base64.b64encode(pickled_options).decode()}"')
if timeout:
command.append(f"--timeout={timeout}")
if log_file:
command.append(f"--log-file={log_file}")
info = STARTUPINFO()
info.dwFlags = 0x1 # STARTF_USESHOWWINDOW aka use wShowWindow's value
info.wShowWindow = 0 # SW_HIDE aka make the window invisible
Expand Down

0 comments on commit ce2c918

Please sign in to comment.