Skip to content
UNMAINTAINED: GLib implementation of PEP 3156
Python Dockerfile Makefile
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
examples Fix gtk example Mar 14, 2016
gbulb Python 3.7 support for GLibBaseEventLoop._make_ssl_transport() Aug 9, 2018
tests Allow multiple invocations of the event loop when a SIGINT occurs. Fixes Oct 28, 2017
.drone.yml
.gitignore
AUTHORS.rst Add Brecht to the contributors list. Jan 19, 2017
CHANGELOG.md 0.6.1. Aug 10, 2018
LICENSE Add a LICENSE file. Oct 28, 2017
MANIFEST.in Add a LICENSE file. Oct 28, 2017
README.md Update README.md Jan 8, 2019
setup.py 0.6.1. Aug 10, 2018

README.md

gbulb - a PEP 3156 event loop based on GLib

Please note that this project is unmaintained. If you are interested in taking ownership, please discuss on https://github.com/nathan-hoad/gbulb/issues/32

Build Status

Gbulb is a Python library that implements a PEP 3156 interface for the GLib main event loop under UNIX-like systems.

As much as possible, except where noted below, it mimics asyncio's interface. If you notice any differences, please report them.

Nathan Hoad

Licence

Apache 2.0

Homepage

https://github.com/nathan-hoad/gbulb

Requirements

  • python3.5+
  • pygobject
  • glib
  • gtk+3 (optional)

Usage

GLib event loop

    import asyncio, gbulb
    gbulb.install()
    asyncio.get_event_loop().run_forever()

Gtk+ event loop (suitable for GTK+ applications)

    import asyncio, gbulb
    gbulb.install(gtk=True)
    asyncio.get_event_loop().run_forever()

GApplication/GtkApplication event loop

    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 asynchronously

See examples/wait_signal.py

Known issues

  • Windows 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 3156

In 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:

    1. when multiple event loop are enclosed (by creating new MainLoop objects and calling .run() recursively)
    2. when the event loop has not even yet started because it is still trying to acquire the context

It would be wiser not to use any recursion at all. GLibEventLoop will actually prevent you from doing that (in accordance with PEP 3156), however GtkEventLoop will allow you to call run() recursively. You should also keep in mind that enclosed loops may be started at any time by third-party code calling GLib's primitives.

You can’t perform that action at this time.