Package: gbulb
Gbulb is a Python library that implements aPEP 3156interface for theGLib main event
loopunder UNIX-like systems.As much as possible, except where noted below, it mimics asyncio’s interface.
If you notice any differences, please report them.Requirementspython 3.7+pygobjectglibgtk+3 (optional)UsageGLib event loopExample usage:import asyncio, gbulb
gbulb.install()
asyncio.get_event_loop().run_forever()Gtk+ event loop(suitable for GTK+ applications)Example usage:import asyncio, gbulb
gbulb.install(gtk=True)
asyncio.get_event_loop().run_forever()GApplication/GtkApplication event loopExample usage:import asyncio, gbulb
gbulb.install(gtk=True)  # only necessary if you're using GtkApplication

loop = asyncio.get_event_loop()
loop.run_forever(application=my_gapplication_object)Waiting on a signal asynchronouslySee examples/wait_signal.pyKnown issuesWindows is not supported, sorry. If you are interested in this, please help
me get it working! I don’t have Windows so I can’t test it.Divergences with PEP 3156In GLib, the concept of event loop is split in two classes: GLib.MainContext
and GLib.MainLoop.The event loop is mostly implemented by MainContext. MainLoop is just a wrapper
that implements the run() and quit() functions. MainLoop.run() atomically
acquires a MainContext and repeatedly calls MainContext.iteration() until
MainLoop.quit() is called.A MainContext is not bound to a particular thread, however it cannot be used
by multiple threads concurrently. If the context is owned by another thread,
then MainLoop.run() will block until the context is released by the other
thread.MainLoop.run() may be called recursively by the same thread (this is mainly
used for implementing modal dialogs in Gtk).The issue: given a context, GLib provides no ways to know if there is an
existing event loop running for that context. It implies the following
divergences with PEP 3156:.run_forever()and.run_until_complete()are not guaranteed to run
immediately. If the context is owned by another thread, then they will
block until the context is released by the other thread..stop()is relevant only when the currently running Glib.MainLoop object
was created by this asyncio object (i.e. by calling.run_forever()or.run_until_complete()). The event loop will quit only when it regains
control of the context. This can happen in two cases:when multiple event loop are enclosed (by creating newMainLoopobjects and calling.run()recursively)when the event loop has not even yet started because it is still
trying to acquire the contextIt would be wiser not to use any recursion at all.GLibEventLoopwill
actually prevent you from doing that (in accordance with PEP 3156), howeverGtkEventLoopwill allow you to callrun()recursively. You should also keep
in mind that enclosed loops may be started at any time by third-party code
calling GLib’s primitives.Communitygbulb is part of theBeeWare suite. You can talk to the community through:@pybeeware on TwitterDiscordThe gbulbGithub Discussions forumWe foster a welcoming and respectful community as described in ourBeeWare Community Code of Conduct.ContributingIf you experience problems with gbulb,log them on GitHub. If you
want to contribute code, pleasefork the codeandsubmit a pull request.