MainLoop and Event Loops

MainLoop

class urwid.MainLoop(widget: AbstractWidget, palette: Iterable[PaletteEntry] = (), screen: BaseScreen | None = None, handle_mouse: bool = True, input_filter: Callable[[list[str | tuple[str, int, int, int]], list[int]], list[str | tuple[str, int, int, int]]] | None = None, unhandled_input: Callable[[str | tuple[str, int, int, int]], bool | None] | None = None, event_loop: EventLoop | None = None, pop_ups: bool = False, *, poll_interval: float | None = None)

This is the standard main loop implementation for a single interactive session.

Parameters:
  • widget – the topmost widget used for painting the screen, stored as widget and may be modified. Must be a box widget.

  • palette – initial palette for screen

  • screen – screen to use, default is a new display.raw.Screen instance; stored as screen

  • handle_mouse – True to ask screen to process mouse events

  • input_filter – a function to filter input before sending it to widget, called from input_filter()

  • unhandled_input – a function called when input is not handled by widget, called from unhandled_input()

  • event_loop – if screen supports external an event loop it may be given here, default is a new SelectEventLoop instance; stored as event_loop

  • pop_ups – True to wrap widget with a PopUpTarget instance to allow any widget to open a pop-up anywhere on the screen; required by DropDown and other PopUpLauncher widgets

  • poll_interval – seconds between checks of watched files and call_from_thread() calls while the curses screen waits for input, except on Windows; stored as poll_interval. None, the default, checks them only after input or an alarm. See Screens Without Event Loop Support.

screen

The screen object this main loop uses for screen updates and reading input

event_loop

The event loop object this main loop uses for waiting on alarms and IO

Note

Some event_loop implementations accept an async def callback in addition to a plain callable - see the specific implementation’s own documentation for whether it does, and how it runs one. set_alarm_in(), set_alarm_at(), watch_file() and watch_pipe() all detect an async def callback and pass that detection through to event_loop; whether it actually does anything still depends on event_loop.

Set up the main loop around a top-level widget, a screen and an event loop.

Raises:
  • NotImplementedError – an event_loop is given but screen does not support external event loops.

  • ValueError – poll_interval is not None or a finite number of seconds of at least 0.1.

call_from_thread(callback: Callable[_Spec, object], /, *args: _Spec.args, **kwargs: _Spec.kwargs) → None

Run callback(*args, **kwargs) on the thread running the event loop, soon.

Safe to call from any thread, and from a signal handler. A signal handler catches the RuntimeError: the signal can arrive while the loop stops. The callback runs on the loop thread with this loop as the running loop, like an alarm callback:

  • a widget it changes is drawn on the way back to idle;

  • ExitMainLoop raised by it stops the loop;

  • any other exception is logged, and the loop goes on.

Calls run in the order they were made. Called on the loop thread itself, it defers the callback the same way instead of running it at once. Calls still queued when the loop stops are dropped. With a screen that has no event loop support, such as the curses screen, a call waits for the next input or alarm, or up to poll_interval seconds when it is set, except on Windows.

Raises:
  • TypeError – callback is an async def function, which this method cannot await.

  • RuntimeError – the loop is not running: before start() or run(), or after stop(). Also while it runs on an event loop that cannot watch files, such as AsyncioEventLoop on asyncio’s ProactorEventLoop, the default on Windows.

draw_screen() → None

Render the widgets and paint the screen.

This method is called automatically from entering_idle(), which runs whenever the event loop is about to go idle – including after handling input and after an alarm callback fires. So screen updates made from input handlers or alarm callbacks are redrawn automatically.

If you modify the widgets displayed from a callback that does not go through the event loop’s idle handling, you will need to call this method yourself to repaint the screen.

Important

Call it only from the thread running the event loop, like every other widget and screen change. Another thread hands the work over with call_from_thread() instead.

The widgets render with this loop as the running loop, also when the loop is not started.

entering_idle() → None

Call draw_screen() to update the screen when anything has changed.

This method is called whenever the event loop is about to enter the idle state.

input_filter(keys: list[str | tuple[str, int, int, int]], raw: list[int]) → list[str | tuple[str, int, int, int]]

Pass each of the input events and raw keystroke values through input_filter.

These values are passed to the input_filter function passed to the constructor. That function must return a list of keys to be passed to the widgets to handle. If no input_filter was defined this implementation will return all the input events.

paused() → Iterator[None]

Hand the terminal to another program for the duration of the block.

The screen is stopped on entry, which gives the terminal back its normal mode and buffer and stops reading its input, and is started again on exit, also when the block raises. On exit the mouse tracking is restored when handle_mouse is set, the screen is cleared and the screen size is read again, so the next draw repaints all of it at the terminal’s current size. A screen that is not started is left alone on both sides of the block. The screen is restarted the way start() starts it: an application that started its screen with alternate_buffer=False comes back in the alternate buffer.

Run an editor on a file:

>>> editor = shlex.split(os.environ.get("EDITOR", "")) or ["vi"]
>>> with loop.paused():
...     subprocess.run([*editor, path], check=False)

The block runs in the event loop’s thread and holds it until the block ends, so no input, alarm or watched file is handled meanwhile: the terminal belongs to the other program.

Important

Call it only from the thread running the event loop, like every other widget and screen change.

Warning

Do not use it with the web display, urwid.display.web.Screen, which has no terminal to hand over: stopping it ends the browser session, and starting it again reads a new client request from standard input.

property poll_interval: float | None

Seconds between checks of watched files while the curses screen waits for input, or None.

None checks them only after input or an alarm. A change takes effect at the next wait for input, also while the loop runs. See Screens Without Event Loop Support.

property pop_ups: bool

Return whether pop-up widgets opened via PopUpLauncher are shown automatically.

process_input(keys: Iterable[str | tuple[str, int, int, int]]) → bool

Pass keyboard input and mouse events to widget.

This method is called automatically from the run() method when there is input, but may also be called to simulate input from the user.

keys is a list of input returned from screen’s get_input() method or its event loop hook. The widgets handle it with this loop as the running loop, also when the loop is not started.

Returns:

True if any key was handled by a widget or the unhandled_input() method.

Raises:

TypeError – an item of keys is neither a key name nor a mouse event tuple.

remove_alarm(handle: Any) → bool

Remove an alarm. Return True if handle was found, False otherwise.

remove_watch_file(handle: Any) → bool

Remove a watch file. Returns True if the watch file exists, False otherwise.

remove_watch_pipe(write_fd: int) → bool

Close the read end of the pipe and remove the watch created by watch_pipe().

Returns:

True if the watch pipe exists, False otherwise

Note

You are responsible for closing the write end of the pipe.

run() → None

Start the main loop handling input events and updating the screen.

The loop will continue until an ExitMainLoop exception is raised.

If you would prefer to manage the event loop yourself, don’t use this method. Instead, call start() before starting the event loop, and stop() once it’s finished.

set_alarm_at(tm: float, callback: Callable[[Self, _T | None], Any], user_data: _T | None = None) → Any

Schedule an alarm at tm time that will call callback from the within the run() function.

Parameters:
  • tm – time to call callback e.g. time.time() + 5

  • callback – function to call with two parameters: this main loop object and user_data

  • user_data – optional user data to pass to the callback

Returns:

a handle that may be passed to remove_alarm().

Note

callback may be an async def function on an event_loop implementation that supports one; see the note on MainLoop.

Note

Exceptions raised by callback are logged with their traceback, naming the callback, and do not stop the loop. ExitMainLoop still exits the loop as usual.

set_alarm_in(sec: float, callback: Callable[[Self, _T | None], Any], user_data: _T | None = None) → Any

Schedule an alarm in sec seconds that will call callback from the within the run() method.

Parameters:
  • sec – seconds until alarm

  • callback – function to call with two parameters: this main loop object and user_data

  • user_data – optional user data to pass to the callback

Returns:

a handle that may be passed to remove_alarm().

Note

callback may be an async def function on an event_loop implementation that supports one; see the note on MainLoop.

Note

callback is called as callback(loop, user_data). Exceptions raised by callback (for example from a callback declared with the wrong signature) are logged with their traceback, naming the callback, and do not stop the loop. ExitMainLoop still exits the loop as usual.

start() → StoppingContext

Set up the main loop, hooking into the event loop where necessary.

Starts the screen if it hasn’t already been started.

If you want to control starting and stopping the event loop yourself, you should call this method before starting, and call stop once the loop has finished. You may also use this method as a context manager, which will stop the loop automatically at the end of the block:

with main_loop.start():

…

Note that some event loop implementations don’t handle exceptions specially if you manage the event loop yourself. In particular, the Twisted and asyncio loops won’t stop automatically when ExitMainLoop (or anything else) is raised.

Once started, the loop is what get_running_loop() returns in the caller’s thread and task, and in everything that copies their context, and it accepts call_from_thread().

Raises:

CantUseExternalLoop – the screen does not support external event loops.

stop() → None

Clean up any hooks added to the event loop.

Only call this if you’re managing the event loop yourself, after the loop stops.

The loop stops being the running loop everywhere start() made it one, also when a cleanup step raises.

unhandled_input(data: str | tuple[str, int, int, int]) → bool | None

Call the unhandled_input function passed to the constructor with any input not handled by the widgets.

If no unhandled_input was defined then the input will be ignored.

input is the keyboard or mouse input.

The unhandled_input function should return True if it handled the input.

watch_file(fd: int, callback: Callable[[], Any]) → Any

Call callback when fd has some data to read. No parameters are passed to callback.

Returns:

a handle that may be passed to remove_watch_file().

Note

callback may be an async def function on an event_loop implementation that supports one; see the note on MainLoop.

Note

With a screen that has no event loop support, such as the curses screen, fd is checked after input or an alarm, and every poll_interval seconds when it is set, except on Windows.

watch_pipe(callback: Callable[[bytes], bool | None]) → int

Create a pipe used by another thread or subprocess to trigger callback in the main loop.

Parameters:

callback – function taking one parameter to call from within the process/thread running the main loop

This method returns a file descriptor attached to the write end of a pipe. The read end of the pipe is added to the list of files event_loop is watching. When data is written to the pipe the callback function will be called and passed a single value containing data read from the pipe.

This method may be used any time you want to update widgets from a subprocess. Another thread hands work to the loop with call_from_thread() instead.

Data may be written to the returned file descriptor with os.write(fd, data). Ensure that data is less than 512 bytes (or 4K on Linux) so that the callback will be triggered just once with the complete value of data passed in.

If the callback returns False then the watch will be removed from event_loop and the read end of the pipe will be closed. The same happens once every write end is closed: the callback then receives b"" one last time. You are responsible for closing the write end of the pipe with os.close(fd).

Note

callback may be an async def function on an event_loop implementation that supports one; see the note on MainLoop.

property widget: AbstractWidget

Property for the topmost widget used to draw the screen.

This must be a box widget.

urwid.get_running_loop() → MainLoop

Return the MainLoop running in the current thread or task.

It is the loop get_running_loop_or_none() finds.

Raises:

RuntimeError – no loop is running in the current thread or task.

urwid.get_running_loop_or_none() → MainLoop | None

Return the MainLoop running in the current thread or task, or None when there is none.

A loop is running between its start() (or run()) and its stop(). It is also the running loop inside every alarm, watch, input and render call it makes, and inside draw_screen() and process_input() called by hand. A context copied from one where the loop runs sees it too, until the loop stops.

>>> print(get_running_loop_or_none())
None

SelectEventLoop

class urwid.SelectEventLoop

Event loop based on selectors.DefaultSelector.select().

Initialize with no alarms or watched files yet.

alarm(seconds: float, callback: Callable[[], Any]) → tuple[float, int, Callable[[], Any]]

Call callback() a given time from now.

No parameters are passed to callback. Returns a handle that may be passed to remove_alarm().

Parameters:
  • seconds – floating point time to wait before calling callback

  • callback – function to call from event loop

enter_idle(callback: Callable[[], Any]) → int

Add a callback for entering idle.

Returns:

a handle that may be passed to remove_enter_idle()

remove_alarm(handle: tuple[float, int, Callable[[], Any]]) → bool

Remove an alarm.

Returns:

True if the alarm exists, False otherwise

remove_enter_idle(handle: int) → bool

Remove an idle callback.

Returns:

True if the handle was removed.

remove_watch_file(handle: int) → bool

Remove an input file.

Returns:

True if the input file exists, False otherwise

run() → None

Start the event loop.

Exit the loop when any callback raises an exception. If ExitMainLoop is raised, exit cleanly.

run_in_executor(executor: Executor, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) → Future[_T]

Run callable in executor.

Parameters:
  • executor – Executor to use for running the function

  • func – function to call

  • args – positional arguments to function

  • kwargs – keyword arguments to function

Returns:

future object for the function call outcome.

watch_file(fd: int, callback: Callable[[], Any]) → int

Call callback() when fd has some data to read.

No parameters are passed to callback. Returns a handle that may be passed to remove_watch_file().

Parameters:
  • fd – file descriptor to watch for input

  • callback – function to call when input is available

AsyncioEventLoop

class urwid.AsyncioEventLoop(*, loop: AbstractEventLoop | None = None, **kwargs: Any)

Event loop based on the standard library asyncio module.

Note

If you make any changes to the urwid state outside of it handling input or responding to alarms (for example, from asyncio.Task running in background), and wish the screen to be redrawn, you must call MainLoop.draw_screen() method of the main loop manually.

A good way to do this:

asyncio.get_running_loop().call_soon(main_loop.draw_screen)

Note

alarm(), watch_file() and enter_idle() accept an async def callback in addition to a plain callable. A coroutine function is scheduled as an asyncio.Task instead of being called directly.

Wrap loop, or the running asyncio event loop when none is given.

Without either, a new SelectorEventLoop is created in an asyncio.Runner owned by this instance.

alarm(seconds: float, callback: Callable[[], Any]) → asyncio.TimerHandle

Call callback() a given time from now.

No parameters are passed to callback. Returns a handle that may be passed to remove_alarm().

Parameters:
  • seconds – time in seconds to wait before calling callback

  • callback – function to call from event loop

enter_idle(callback: Callable[[], Any]) → int

Add a callback for entering idle.

Returns:

a handle that may be passed to remove_enter_idle()

remove_alarm(handle: TimerHandle) → bool

Remove an alarm.

Returns:

True if the alarm was still pending, False if it has fired or was removed already.

remove_enter_idle(handle: int) → bool

Remove an idle callback.

Returns:

True if the handle was removed.

remove_watch_file(handle: int) → bool

Remove an input file.

Returns:

True if the input file exists, False otherwise

run() → None

Start the event loop.

Exit the loop when any callback raises an exception. If ExitMainLoop is raised, exit cleanly.

Raises:

BaseException – the exception that stopped the loop, once the loop has been left.

run_in_executor(executor: Executor | None, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) → asyncio.Future[_T]

Run callable in executor.

Parameters:
  • executor – Executor to use for running the function. Default asyncio executor is used if None.

  • func – function to call

  • args – arguments to function (positional only)

  • kwargs – keyword arguments to function (keyword only)

Returns:

future object for the function call outcome.

watch_file(fd: int, callback: Callable[[], Any]) → int

Call callback() when fd has some data to read.

No parameters are passed to callback. Returns a handle that may be passed to remove_watch_file().

Parameters:
  • fd – file descriptor to watch for input

  • callback – function to call when input is available

TrioEventLoop

class urwid.TrioEventLoop

Event loop based on the trio module.

trio is an async library.

Note

alarm(), watch_file() and enter_idle() accept an async def callback in addition to a plain callable. A coroutine function is scheduled as a task in the main loop’s nursery instead of being called directly.

Initialize the Trio event loop.

alarm(seconds: float, callback: Callable[[], Any]) → trio.CancelScope

Call callback() a given time from now.

Parameters:
  • seconds – time in seconds to wait before calling the callback

  • callback – function to call from the event loop

Returns:

a handle that may be passed to remove_alarm()

No parameters are passed to the callback.

enter_idle(callback: Callable[[], Any]) → int

Call callback() when the event loop enters the idle state.

There is no such thing as being idle in a Trio event loop so we simulate it by repeatedly calling callback() with a short delay.

remove_alarm(handle: CancelScope) → bool

Remove an alarm.

Parameters:

handle – the handle of the alarm to remove

Returns:

True if the alarm was still pending, False if it has fired or was removed already

remove_enter_idle(handle: int) → bool

Remove an idle callback.

Parameters:

handle – the handle of the idle callback to remove

Returns:

True if handle was found, False otherwise.

remove_watch_file(handle: CancelScope) → bool

Remove a file descriptor being watched for input.

Parameters:

handle – the handle of the file descriptor callback to remove

Returns:

True if the file descriptor was watched, False otherwise

run() → None

Start the event loop.

Exit the loop when any callback raises an exception. If ExitMainLoop is raised, exit cleanly.

async run_async() → None

Start the main loop and block asynchronously until the main loop exits.

This allows one to embed an urwid app in a Trio app even if the Trio event loop is already running. Example:

with trio.open_nursery() as nursery:
    event_loop = urwid.TrioEventLoop()

    # [...launch other async tasks in the nursery...]

    loop = urwid.MainLoop(widget, event_loop=event_loop)
    with loop.start():
        await event_loop.run_async()

    nursery.cancel_scope.cancel()
run_in_executor(executor: Executor, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) → Future[_T] | asyncio.Future[_T]

Raise NotImplementedError: use Trio’s own thread API.

Raises:

NotImplementedError – Trio runs blocking calls in threads itself; use trio.to_thread.run_sync.

watch_file(fd: int | SupportsFileno, callback: Callable[[], Any]) → trio.CancelScope

Call callback() when the given file descriptor has some data to read.

No parameters are passed to the callback.

Parameters:
  • fd – file descriptor to watch for input

  • callback – function to call when some input is available

Returns:

a handle that may be passed to remove_watch_file()

A watch already set on the descriptor is replaced, and its handle is no longer valid.

GLibEventLoop

TwistedEventLoop

class urwid.TwistedEventLoop(reactor: ReactorBase | None = None, manage_reactor: bool = True)

Event loop based on Twisted.

Initialize the event loop, wrapping reactor or Twisted’s default reactor.

Parameters:
  • reactor – reactor to use

  • manage_reactor – True if you want this event loop to run and stop the reactor.

Warning

Twisted’s reactor doesn’t like to be stopped and run again. If you need to stop and run your MainLoop, consider setting manage_reactor=False and take care of running/stopping the reactor at the beginning/ending of your program yourself.

You can also forego using MainLoop’s run() entirely, and instead call start() and stop() before and after starting the reactor.

alarm(seconds: float, callback: Callable[[], Any]) → DelayedCall

Call callback() a given time from now.

No parameters are passed to callback. Returns a handle that may be passed to remove_alarm().

Parameters:
  • seconds – floating point time to wait before calling callback

  • callback – function to call from event loop

enter_idle(callback: Callable[[], Any]) → int

Add a callback for entering idle.

Returns:

a handle that may be passed to remove_enter_idle()

handle_exit(f: Callable[_Spec, _T], enable_idle: bool = True) → Callable[_Spec, _T | None]

Wrap f so that ExitMainLoop raised inside it exits the TwistedEventLoop cleanly.

Another exception is stored and raised from run() once the reactor stops, when this loop manages the reactor. Otherwise it is logged, since run() has already returned.

f – function to be wrapped

remove_alarm(handle: DelayedCall) → bool

Remove an alarm.

Returns:

True if the alarm exists, False otherwise

remove_enter_idle(handle: int) → bool

Remove an idle callback.

Returns:

True if the handle was removed.

remove_watch_file(handle: int) → bool

Remove an input file.

Returns:

True if the input file exists, False otherwise

run() → None

Start the event loop.

Exit the loop when any callback raises an exception. If ExitMainLoop is raised, exit cleanly.

Raises:

BaseException – the exception that stopped the loop, once the loop has been left.

run_in_executor(executor: Executor, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) → Future[_T] | asyncio.Future[_T]

Raise NotImplementedError: use Twisted’s own thread pool API.

Raises:

NotImplementedError – Twisted has its own thread pool; use threads.deferToThread instead.

watch_file(fd: int, callback: Callable[[], Any]) → int

Call callback() when fd has some data to read.

No parameters are passed to callback. Returns a handle that may be passed to remove_watch_file().

Parameters:
  • fd – file descriptor to watch for input

  • callback – function to call when input is available

A watch already set on fd is replaced.

TornadoEventLoop

class urwid.TornadoEventLoop(loop: IOLoop | None = None)

This is an Urwid-specific event loop to plug into its MainLoop.

It acts as an adaptor for Tornado’s IOLoop which does all heavy lifting except idle-callbacks.

Note

alarm(), watch_file() and enter_idle() accept an async def callback in addition to a plain callable. A coroutine function is scheduled as an asyncio.Task on the IOLoop’s underlying asyncio loop instead of being called directly.

Wrap loop, or Tornado’s current IOLoop when none is given.

alarm(seconds: float, callback: Callable[[], Any]) → object

Schedule callback to run after seconds and return a handle for remove_alarm().

enter_idle(callback: Callable[[], Any]) → int

Add a callback for entering idle.

Returns:

a handle that may be passed to remove_enter_idle()

handle_exit(f: Callable[_Spec, _T]) → Callable[_Spec, _T | Literal[False] | None]

Wrap f so that a raised exception stops the loop instead of propagating.

remove_alarm(handle: object) → bool

Cancel an alarm scheduled by alarm(), returning whether it was still pending.

remove_enter_idle(handle: int) → bool

Remove an idle callback.

Returns:

True if the handle was removed.

remove_watch_file(handle: int) → bool

Stop watching a file descriptor registered by watch_file(), returning whether it was watched.

run() → None

Start the event loop and run it until ExitMainLoop is raised.

Raises:

BaseException – the exception that stopped the loop, once the loop has been left.

run_in_executor(executor: Executor, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) → asyncio.Future[_T]

Run callable in executor.

Parameters:
  • executor – Executor to use for running the function

  • func – function to call

  • args – arguments to function (positional only)

  • kwargs – keyword arguments to function (keyword only)

Returns:

future object for the function call outcome.

watch_file(fd: int, callback: Callable[[], Any]) → int

Call callback whenever fd is readable and return a handle for remove_watch_file().

A watch already set on fd is replaced, and its handle is no longer valid.

ZMQEventLoop

class urwid.ZMQEventLoop

This class is an urwid event loop for ZeroMQ applications.

It is very similar to SelectEventLoop, supporting the usual alarm() events and file watching (watch_file()) capabilities, but also incorporates the ability to watch zmq queues for events (watch_queue()).

Note

alarm(), watch_file(), watch_queue() and enter_idle() accept an async def callback in addition to a plain callable. ZMQEventLoop runs on top of an asyncio loop (via zmq.asyncio.Poller), so a coroutine function is scheduled as a background task there instead of being called directly, the same way it would be on any other asyncio-backed event loop.

Initialize with a fresh zmq poller and no alarms or watched queues yet.

alarm(seconds: float, callback: Callable[[], Any]) → ZMQAlarmHandle

Call callback a given time from now.

No parameters are passed to callback. Returns a handle that may be passed to remove_alarm().

Parameters:
  • seconds (float) – floating point time to wait before calling callback.

  • callback – function to call from event loop.

enter_idle(callback: Callable[[], Any]) → int

Add a callback to be executed when the event loop detects it is idle.

Returns:

a handle that may be passed to remove_enter_idle().

remove_alarm(handle: ZMQAlarmHandle) → bool

Remove an alarm.

Returns:

True if the alarm exists, False otherwise.

remove_enter_idle(handle: int) → bool

Remove an idle callback.

Returns:

True if handle was removed, False otherwise.

remove_watch_file(handle: int | SupportsFileno) → bool

Remove a file from background polling.

handle may be the object given to watch_file() or, for an ordinary file, its descriptor number. A zmq socket is named by the socket object itself.

Returns:

True if the file was being monitored, False otherwise.

remove_watch_queue(handle: Socket[Any]) → bool

Remove a queue from background polling.

Returns:

True if the queue was being monitored, False otherwise.

run() → None

Start the event loop.

Exit the loop when any callback raises an exception. If ExitMainLoop is raised, exit cleanly.

Raises:

BaseException – the exception that stopped the loop, once the loop has been left.

run_in_executor(executor: Executor, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) → Future[_T]

Run callable in executor.

Parameters:
  • executor – Executor to use for running the function

  • func – function to call

  • args – positional arguments to function

  • kwargs – keyword arguments to function

Returns:

future object for the function call outcome.

watch_file(fd: int | SupportsFileno, callback: Callable[[], typing.Any], flags: int = <PollEvent.POLLIN: 1>) → int | SupportsFileno

Call callback when fd has some data to read.

No parameters are passed to the callback. The flags are as for watch_queue().

Note

For a zmq socket, this method and watch_queue() set the same watch. Calling this method on a watched socket replaces its callback and flags, while watch_queue() refuses a watched socket. Either remove_watch_file() or remove_watch_queue() removes it.

Parameters:
  • fd – The file-like object, or fileno to monitor. A zmq socket is watched for its 0MQ events, as by watch_queue(). Its fileno() is the socket’s notification descriptor and does not name the same watch.

  • callback – The function to call when the file has data available.

  • flags (int) – The condition to monitor on the file (defaults to POLLIN).

Returns:

a handle that may be passed to remove_watch_file().

watch_queue(queue: zmq.Socket[typing.Any], callback: Callable[[], typing.Any], flags: int = <PollEvent.POLLIN: 1>) → zmq.Socket[Any]

Call callback when zmq queue becomes ready to read or write.

flags controls the condition: POLLIN (the default) watches for data to read, POLLOUT watches for availability to write. No parameters are passed to the callback. Returns a handle that may be passed to remove_watch_queue().

Parameters:
  • queue – The zmq queue to poll.

  • callback – The function to call when the poll is successful.

  • flags (int) – The condition to monitor on the queue (defaults to POLLIN).

Raises:

ValueError – queue is already being watched, by this method or by watch_file().

GuardedEventLoop

class urwid.GuardedEventLoop(loop: EventLoop, on_error: Callable[[Exception], object])

Event loop that passes the exceptions of its callbacks to a handler.

It registers every callback on another event loop. Without it, an exception raised by a callback stops the event loop, which ends every application that runs on it. Give each MainLoop that shares one event loop its own wrapper: an exception in one application’s input handler, alarm or redraw then reaches that application’s handler, and the event loop and the other applications go on.

The handler receives every Exception, ExitMainLoop included, and decides what ends: usually the application whose callback raised. A BaseException that is not an Exception, such as KeyboardInterrupt, is not caught. An exception the handler raises goes to the wrapped event loop.

The wrapper suits a screen that hands its input to the event loop, such as urwid.display.websocket.Screen.

A handler that records the errors, and stops the loop on ExitMainLoop:

>>> import urwid
>>> errors = []
>>> def on_error(exc):
...     errors.append(type(exc).__name__)
...     if isinstance(exc, urwid.ExitMainLoop):
...         raise exc
>>> def stop():
...     raise urwid.ExitMainLoop
>>> loop = GuardedEventLoop(urwid.SelectEventLoop(), on_error)
>>> _ = loop.alarm(0, lambda: 1 / 0)
>>> _ = loop.alarm(0.01, stop)
>>> loop.run()
>>> errors
['ZeroDivisionError', 'ExitMainLoop']

Wrap loop with on_error as the handler.

Parameters:
  • loop – the event loop that runs the callbacks; it may be shared with other wrappers.

  • on_error – called with each exception a callback raised.

alarm(seconds: float, callback: Callable[[], Any]) → Any

Call callback on the wrapped loop seconds from now.

Returns:

the wrapped loop’s handle, for remove_alarm().

enter_idle(callback: Callable[[], Any]) → Any

Call callback whenever the wrapped loop enters idle.

Returns:

the wrapped loop’s handle, for remove_enter_idle().

property loop: EventLoop

Return the wrapped event loop.

remove_alarm(handle: Any) → bool

Remove an alarm from the wrapped loop.

Returns:

whether the alarm was pending.

remove_enter_idle(handle: Any) → bool

Remove an idle callback from the wrapped loop.

Returns:

whether the callback was registered.

remove_watch_file(handle: Any) → bool

Stop watching a file.

Returns:

whether the file was watched.

run() → None

Run the wrapped event loop.

run_in_executor(executor: Executor, func: Callable[_Spec, _T], *args: _Spec.args, **kwargs: _Spec.kwargs) → Future[_T] | asyncio.Future[_T]

Run func in executor through the wrapped loop.

Raises:

NotImplementedError – the wrapped loop cannot run callables in an executor.

set_signal_handler(signum: int, handler: Callable[[int, FrameType | None], Any] | int | signal.Handlers) → Callable[[int, FrameType | None], Any] | int | signal.Handlers | None

Set the handler of signal signum through the wrapped loop.

watch_file(fd: int, callback: Callable[[], Any]) → Any

Call callback whenever fd is readable.

Returns:

the wrapped loop’s handle, for remove_watch_file().