AstraLuma / gpotato

a PEP 3156 event loop based on GLib
2 stars 0 forks source link

gpotato - a PEP 3156 event loop based on GLib

Build Status

Gpotato is a python library that implements a PEP 3156 interface for the GLib main event loop. It is designed to be used together with the asyncio module.

The code needs to be thoroughly tested, it should be considered as unstable for the moment.

This is a fork of the gbulb project.

Licence

Apache 2.0

Homepage

https://github.com/astronouth7303/gpotato

Requirements

Usage

GLib event loop

import asyncio, gpotato
asyncio.set_event_loop_policy(gpotato.GLibEventLoopPolicy())

Gtk+ event loop (suitable for GTK+ applications)

import asyncio, gpotato
asyncio.set_event_loop_policy(gpotato.GtkEventLoopPolicy())

GApplication/GtkApplication event loop

import asyncio, gpotato
asyncio.set_event_loop_policy(gpotato.GApplicationEventLoopPolicy())

loop = asyncio.get_event_loop()
loop.run_forever(application = my_gapplication_object)

Known issues

Divergences with PEP 3156

In GLib, the concept of event loop is split in two classes: GLib.MainContext and GLib.MainLoop.

The thing 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 is 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:

It should be wiser not to use any recursion at all. GLibEventLoop will actually prevent you from doing that (in accordance with PEP 3156). However you should keep in mind that enclosed loops may be started at any time by third-party code calling directly GLib's primitives.