From 715925795f13b8d763df41af647b798bbe59e5b4 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 17 Nov 2021 15:43:26 +0530 Subject: [PATCH] Ignore errors in various finalizers during exit This was needed for tui loop to exit cleanly when terminal i/o breaks --- kittens/tui/handler.py | 8 +++++--- kittens/tui/loop.py | 12 +++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/kittens/tui/handler.py b/kittens/tui/handler.py index 54e83c6f1..e707cab8c 100644 --- a/kittens/tui/handler.py +++ b/kittens/tui/handler.py @@ -3,6 +3,7 @@ from collections import deque +from contextlib import suppress from time import monotonic from types import TracebackType from typing import ( @@ -94,9 +95,10 @@ class Handler: def __exit__(self, etype: type, value: Exception, tb: TracebackType) -> None: del self.debug.fobj - self.finalize() - if self._image_manager is not None: - self._image_manager.__exit__(etype, value, tb) + with suppress(Exception): + self.finalize() + if self._image_manager is not None: + self._image_manager.__exit__(etype, value, tb) def initialize(self) -> None: pass diff --git a/kittens/tui/loop.py b/kittens/tui/loop.py index b1f818683..399abba1c 100644 --- a/kittens/tui/loop.py +++ b/kittens/tui/loop.py @@ -10,7 +10,7 @@ import selectors import signal import sys import termios -from contextlib import contextmanager +from contextlib import contextmanager, suppress from enum import Enum, IntFlag, auto from functools import partial from typing import Any, Callable, Dict, Generator, List, NamedTuple, Optional @@ -102,9 +102,10 @@ class TermManager: return self def __exit__(self, *a: object) -> None: - self.reset_state_to_original() - close_tty(self.tty_fd, self.original_termios) - del self.tty_fd, self.original_termios + with suppress(Exception): + self.reset_state_to_original() + close_tty(self.tty_fd, self.original_termios) + del self.tty_fd, self.original_termios class MouseButton(IntFlag): @@ -463,7 +464,8 @@ class Loop: term_manager.extra_finalize = b''.join(self.write_buf).decode('utf-8') if tb is not None: self.return_code = 1 - self._report_error_loop(tb, term_manager) + if not handler.terminal_io_ended: + self._report_error_loop(tb, term_manager) def _report_error_loop(self, tb: str, term_manager: TermManager) -> None: self.loop_impl(UnhandledException(tb), term_manager)