From fca0999814bb5620d2ca592db5c0f6c50a790491 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 30 Aug 2022 19:35:17 +0530 Subject: [PATCH] Eureka! Figured out why libedit is breaking in prewarm on macOS via launchd The prewarm zygote imports the world. shell.py had a top level import for readline. Which means readline was being imported pre-fork. And of course as is traditional with Apple libedit is not fork safe. Probably because it initializes its internal IO routines based on the stdio handles at time of import which are the handles kitty gets from launchd --- kittens/ask/main.py | 9 --------- kittens/tui/path_completer.py | 4 ---- kitty/shell.py | 5 ++++- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/kittens/ask/main.py b/kittens/ask/main.py index be87f19ea..332fad47e 100644 --- a/kittens/ask/main.py +++ b/kittens/ask/main.py @@ -476,15 +476,6 @@ def main(args: List[str]) -> Response: loop.loop(phandler) return {'items': items, 'response': phandler.response} - rd = getattr(sys, 'kitty_run_data') - if 'prewarmed' in rd and 'launched_by_launch_services' in rd: - # bloody libedit doesnt work in the prewarmed process run from launch - # services for reasons I really dont care enough to investigate - loop = Loop() - phandler = Password(cli_opts, prompt, is_password=False, initial_text=cli_opts.default or '') - loop.loop(phandler) - return {'items': items, 'response': phandler.response} - import readline as rl readline = rl from kitty.shell import init_readline diff --git a/kittens/tui/path_completer.py b/kittens/tui/path_completer.py index c78e09372..363dd7de1 100644 --- a/kittens/tui/path_completer.py +++ b/kittens/tui/path_completer.py @@ -3,7 +3,6 @@ import os -import sys from typing import Any, Callable, Dict, Generator, Optional, Sequence, Tuple from kitty.fast_data_types import wcswidth @@ -149,9 +148,6 @@ class PathCompleter: def get_path(prompt: str = '> ') -> str: - rd = getattr(sys, 'kitty_run_data') - if 'prewarmed' in rd and 'launched_by_launch_services' in rd: - return input(prompt) return PathCompleter(prompt).input() diff --git a/kitty/shell.py b/kitty/shell.py index be266406b..0b5188e2e 100644 --- a/kitty/shell.py +++ b/kitty/shell.py @@ -2,7 +2,6 @@ # License: GPL v3 Copyright: 2018, Kovid Goyal import os -import readline import shlex import sys import traceback @@ -39,6 +38,7 @@ def match_commands() -> Tuple[str, ...]: @run_once def init_readline() -> None: + import readline global is_libedit with suppress(OSError): readline.read_init_file() @@ -90,6 +90,7 @@ class Completer: self.history_path = os.path.join(ddir, 'shell.history') def complete(self, text: str, state: int) -> Optional[str]: + import readline if state == 0: line = readline.get_line_buffer() cmdline = shlex.split(line) @@ -102,6 +103,7 @@ class Completer: return None def __enter__(self) -> 'Completer': + import readline with suppress(Exception): readline.read_history_file(self.history_path) readline.set_completer(self.complete) @@ -110,6 +112,7 @@ class Completer: return self def __exit__(self, *a: Any) -> None: + import readline readline.write_history_file(self.history_path)