Skip to content

suspend

dev_tool.tui.suspend

log = logging.getLogger(__name__) module-attribute

HAS_JOB_CONTROL = hasattr(signal, 'SIGTSTP') and hasattr(signal, 'SIGCONT') module-attribute

INPUT_POLL_SECONDS = 0.1 module-attribute

TerminalSuspension

A class that keeps terminal state correct across Ctrl+Z and fg.

A blessed terminal applies cbreak mode, the alternate screen and cursor visibility once, when its context is entered. Suspending the process hands the terminal back to the shell, which restores the modes it wants and never reinstates the application's, so a resumed application is left in canonical mode and receives no keystrokes until Enter is pressed. The alternate screen is reverted before the process stops, and a resume is recorded so the caller can enter its terminal context again.

The constructor for the TerminalSuspension class.

Parameters:

  • terminal (Terminal) –

    The blessed Terminal instance.

Source code in dev_tool/tui/suspend.py
def __init__(self, terminal: Terminal) -> None:
    """
    The constructor for the TerminalSuspension class.

    :param terminal: The blessed Terminal instance.
    """

    self.handlers: dict[int, Any] = {}
    self.resumed = False
    self.terminal = terminal

handlers = {} instance-attribute

resumed = False instance-attribute

terminal = terminal instance-attribute

__enter__

The context manager entry method that installs the handlers.

Returns:

  • Self –

    The TerminalSuspension instance.

Source code in dev_tool/tui/suspend.py
def __enter__(self) -> Self:
    """
    The context manager entry method that installs the handlers.

    :return: The TerminalSuspension instance.
    """

    self.install()
    return self

__exit__

The context manager exit method that restores the handlers.

Parameters:

  • exc_type (type[BaseException] | None) –

    The exception type, if an exception was raised.

  • exc_val (BaseException | None) –

    The exception value, if an exception was raised.

  • traceback (object) –

    The traceback, if an exception was raised.

Source code in dev_tool/tui/suspend.py
def __exit__(
    self,
    exc_type: type[BaseException] | None,
    exc_val: BaseException | None,
    traceback: object
) -> None:
    """
    The context manager exit method that restores the handlers.

    :param exc_type: The exception type, if an exception was raised.
    :param exc_val: The exception value, if an exception was raised.
    :param traceback: The traceback, if an exception was raised.
    """

    self.restore()

acknowledge

A method that consumes a recorded resume.

Returns:

  • bool –

    True if the application was resumed since the last call.

Source code in dev_tool/tui/suspend.py
def acknowledge(self) -> bool:
    """
    A method that consumes a recorded resume.

    :return: True if the application was resumed since the last call.
    """

    resumed = self.resumed
    self.resumed = False

    return resumed

install

A method that installs the suspend and continue handlers.

Source code in dev_tool/tui/suspend.py
def install(self) -> None:
    """A method that installs the suspend and continue handlers."""

    if not HAS_JOB_CONTROL:
        return

    handlers = (
        (signal.SIGTSTP, self._handle_suspend),
        (signal.SIGCONT, self._handle_continue)
    )

    for code, handler in handlers:
        try:
            previous = signal.getsignal(code)
            signal.signal(code, handler)
        except (OSError, ValueError):
            log.debug(f'Unable to install a handler for signal {code}')
            continue

        self.handlers[code] = previous

restore

A method that restores the handlers that were replaced.

Source code in dev_tool/tui/suspend.py
def restore(self) -> None:
    """A method that restores the handlers that were replaced."""

    for code, handler in self.handlers.items():
        try:
            signal.signal(code, handler)
        except (OSError, ValueError):
            log.debug(f'Unable to restore the handler for signal {code}')

    self.handlers.clear()

restore_terminal

A function that reverts the alternate screen and cursor visibility.

Parameters:

  • terminal (Terminal) –

    The blessed Terminal instance.

Source code in dev_tool/tui/suspend.py
def restore_terminal(terminal: Terminal) -> None:
    """
    A function that reverts the alternate screen and cursor visibility.

    :param terminal: The blessed Terminal instance.
    """

    sequence = terminal.normal_cursor + terminal.exit_fullscreen
    print(sequence, end='', flush=True)  # noqa: T201