From 121da4910e26be1e26e7ffc20ba90a29f1254547 Mon Sep 17 00:00:00 2001 From: Valentin Stanciu <250871+svalentin@users.noreply.github> Date: Thu, 11 May 2023 17:23:00 -0700 Subject: [PATCH 1/3] Pass log-file and timeout args to daemon as proper args 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. Lets 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. --- mypy/dmypy/client.py | 19 +++++++++++-------- mypy/dmypy_server.py | 6 +++++- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/mypy/dmypy/client.py b/mypy/dmypy/client.py index ee786fdd7436..2ab01c1ff69a 100644 --- a/mypy/dmypy/client.py +++ b/mypy/dmypy/client.py @@ -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 --)" ) @@ -608,21 +609,23 @@ 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: + # Override processed options from flags 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) diff --git a/mypy/dmypy_server.py b/mypy/dmypy_server.py index 1f038397f2ea..94aab6953530 100644 --- a/mypy/dmypy_server.py +++ b/mypy/dmypy_server.py @@ -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 From 49dff72bc6236e745365cdad8d7ec0237cfc09cc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 12 May 2023 00:27:20 +0000 Subject: [PATCH 2/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypy/dmypy_server.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mypy/dmypy_server.py b/mypy/dmypy_server.py index 94aab6953530..c742f3116402 100644 --- a/mypy/dmypy_server.py +++ b/mypy/dmypy_server.py @@ -59,9 +59,9 @@ def daemonize( pickled_options = pickle.dumps(options.snapshot()) command.append(f'--options-data="{base64.b64encode(pickled_options).decode()}"') if timeout: - command.append(f'--timeout={timeout}') + command.append(f"--timeout={timeout}") if log_file: - command.append(f'--log-file={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 From 899f01e948e53b03edf29a43cc36417c699eddd1 Mon Sep 17 00:00:00 2001 From: Valentin Stanciu <250871+svalentin@users.noreply.github.com> Date: Thu, 11 May 2023 20:36:42 -0400 Subject: [PATCH 3/3] Update client.py remove incorrect comment --- mypy/dmypy/client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mypy/dmypy/client.py b/mypy/dmypy/client.py index 2ab01c1ff69a..0e9120608509 100644 --- a/mypy/dmypy/client.py +++ b/mypy/dmypy/client.py @@ -616,7 +616,6 @@ def do_daemon(args: argparse.Namespace) -> None: os.dup2(fd, 1) if args.options_data: - # Override processed options from flags from mypy.options import Options options_dict = pickle.loads(base64.b64decode(args.options_data))