# Urwid main loop code # Copyright (C) 2004-2012 Ian Ward # Copyright (C) 2008 Walter Mundt # Copyright (C) 2009 Andrew Psaltis # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Urwid web site: https://urwid.org/ """Abstract shared code for urwid EventLoop implementation.""" from __future__ import annotations import abc import signal import typing from collections.abc import Callable if typing.TYPE_CHECKING: from types import FrameType __all__ = ("ExitMainLoop", "EventLoop") class ExitMainLoop(Exception): """ When this exception is raised within a main loop the main loop will exit cleanly. """ pass class EventLoop(abc.ABC): """ Abstract class representing an event loop to be used by :class:`MainLoop`. """ @abc.abstractmethod def alarm(self, seconds: float | int, callback: Callable[[], typing.Any]) -> typing.Any: """ Call callback() a given time from now. No parameters are passed to callback. This method has no default implementation. Returns a handle that may be passed to remove_alarm() seconds -- floating point time to wait before calling callback callback -- function to call from event loop """ @abc.abstractmethod def enter_idle(self, callback): """ Add a callback for entering idle. This method has no default implementation. Returns a handle that may be passed to remove_idle() """ @abc.abstractmethod def remove_alarm(self, handle) -> bool: """ Remove an alarm. This method has no default implementation. Returns True if the alarm exists, False otherwise """ @abc.abstractmethod def remove_enter_idle(self, handle) -> bool: """ Remove an idle callback. This method has no default implementation. Returns True if the handle was removed. """ @abc.abstractmethod def remove_watch_file(self, handle) -> bool: """ Remove an input file. This method has no default implementation. Returns True if the input file exists, False otherwise """ @abc.abstractmethod def run(self) -> None: """ Start the event loop. Exit the loop when any callback raises an exception. If ExitMainLoop is raised, exit cleanly. This method has no default implementation. """ @abc.abstractmethod def watch_file(self, fd: int, callback: Callable[[], typing.Any]): """ Call callback() when fd has some data to read. No parameters are passed to callback. This method has no default implementation. Returns a handle that may be passed to remove_watch_file() fd -- file descriptor to watch for input callback -- function to call when input is available """ def set_signal_handler( self, signum: int, handler: Callable[[int, FrameType | None], typing.Any] | int | signal.Handlers, ) -> Callable[[int, FrameType | None], typing.Any] | int | signal.Handlers | None: """ Sets the signal handler for signal signum. The default implementation of :meth:`set_signal_handler` is simply a proxy function that calls :func:`signal.signal()` and returns the resulting value. signum -- signal number handler -- function (taking signum as its single argument), or `signal.SIG_IGN`, or `signal.SIG_DFL` """ return signal.signal(signum, handler)