gbulb


Namegbulb JSON
Version 0.6.6 PyPI version JSON
download
home_pageNone
SummaryGLib event loop for Python asyncio
upload_time2024-09-13 02:59:12
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseApache 2.0
keywords gtk glib gnome asyncio tulip
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            THIS PROJECT HAS BEEN ARCHIVED
==============================

**With the release of PyGObject 3.50.0, GBulb is no longer required**. PyGObject
now contains native integration with the Python event loop. If you require
asyncio support in your GTK app, we advise upgrading your project to use the
native asyncio API of `PyGObject 3.50.0+ <https://pypi.org/project/PyGObject/>`__.

Example usage of PyGObject with native asyncio support::

    import asyncio

    import gi
    gi.require_version("Gtk", "3.0")

    from gi.events import GLibEventLoopPolicy
    from gi.repository import Gtk

    asyncio.set_event_loop_policy(GlibEventLoopPolicy())

    app = Gtk.Application(...)
    app.run()

The last published version of this project (`v0.6.6
<https://pypi.org/project/gbulb/0.6.6/>`__) is compatible with versions of
PyGObject prior to 3.50.0, and CPython 3.8-3.13.

.. |pyversions| image:: https://img.shields.io/pypi/pyversions/gbulb.svg
   :target: https://pypi.python.org/pypi/gbulb
   :alt: Python Versions

.. |version| image:: https://img.shields.io/pypi/v/gbulb.svg
   :target: https://pypi.python.org/pypi/gbulb
   :alt: PyPI Version

.. |maturity| image:: https://img.shields.io/pypi/status/gbulb.svg
   :target: https://pypi.python.org/pypi/gbulb
   :alt: Maturity

.. |license| image:: https://img.shields.io/pypi/l/gbulb.svg
   :target: https://github.com/beeware/gbulb/blob/main/LICENSE
   :alt: BSD License

.. |ci| image:: https://github.com/beeware/gbulb/workflows/CI/badge.svg?branch=main
   :target: https://github.com/beeware/gbulb/actions
   :alt: Build Status

.. |social| image:: https://img.shields.io/discord/836455665257021440?label=Discord%20Chat&logo=discord&style=plastic
   :target: https://beeware.org/bee/chat/
   :alt: Discord server

gbulb
=====

|pyversions| |version| |maturity| |license| |ci| |social|

Gbulb is a Python library that implements a `PEP 3156
<http://www.python.org/dev/peps/pep-3156/>`__ interface for the `GLib main event
loop <https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html>`__
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.

Requirements
------------

- python 3.8+
- pygobject
- glib
- gtk+3 (optional)

Usage
-----

GLib event loop
~~~~~~~~~~~~~~~

Example 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 loop
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Example 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 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.

Testing
-------

Testing GBulb requires a Linux environment that has GLib and GTK development
libraries available.

The tests folder contains a Dockerfile that defines a complete testing
environment. To use the Docker environment, run the following from the root of
the git checkout:

   $ docker buildx build --tag beeware/gbulb:latest --file ./tests/Dockerfile .
   $ docker run --rm --volume $(PWD):/home/brutus/gbulb:z -it beeware/gbulb:latest

This will drop you into an Ubuntu 24.04 shell that has Python 3.8-3.13
installed, mounting the current working directory as `/home/brutus/gbulb`. You
can use this to create virtual environments for each Python version.

Once you have an active virtual environment, run:

   (venv) $ pip install -e .[dev]
   (venv) $ pytest

to run the test suite. Alternatively, you can install tox, and then run:

   # To test a single Python version
   (venv) $ tox -e py

   # To test Python 3.10 specifically
   (venv) $ tox -e py310

   # To test all versions
   (venv) $ tox

Community
---------

gbulb is part of the `BeeWare suite`_. You can talk to the community through:

* `@pybeeware on Twitter <https://twitter.com/pybeeware>`__

* `Discord <https://beeware.org/bee/chat/>`__

* The gbulb `Github Discussions forum <https://github.com/beeware/gbulb/discussions>`__

We foster a welcoming and respectful community as described in our
`BeeWare Community Code of Conduct`_.

Contributing
------------

If you experience problems with gbulb, `log them on GitHub`_. If you
want to contribute code, please `fork the code`_ and `submit a pull request`_.

.. _BeeWare suite: http://beeware.org
.. _BeeWare Community Code of Conduct: http://beeware.org/community/behavior/
.. _log them on Github: https://github.com/beeware/gbulb/issues
.. _fork the code: https://github.com/beeware/gbulb
.. _submit a pull request: https://github.com/beeware/gbulb/pulls

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "gbulb",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "Russell Keith-Magee <russell@keith-magee.com>",
    "keywords": "gtk, glib, gnome, asyncio, tulip",
    "author": null,
    "author_email": "Russell Keith-Magee <russell@keith-magee.com>, Nathan Hoad <nathan@getoffmalawn.com>",
    "download_url": "https://files.pythonhosted.org/packages/6c/f4/742e5e1534780e6661623ea1df58c9e86650c484297759051fc9c0ee336b/gbulb-0.6.6.tar.gz",
    "platform": null,
    "description": "THIS PROJECT HAS BEEN ARCHIVED\n==============================\n\n**With the release of PyGObject 3.50.0, GBulb is no longer required**. PyGObject\nnow contains native integration with the Python event loop. If you require\nasyncio support in your GTK app, we advise upgrading your project to use the\nnative asyncio API of `PyGObject 3.50.0+ <https://pypi.org/project/PyGObject/>`__.\n\nExample usage of PyGObject with native asyncio support::\n\n    import asyncio\n\n    import gi\n    gi.require_version(\"Gtk\", \"3.0\")\n\n    from gi.events import GLibEventLoopPolicy\n    from gi.repository import Gtk\n\n    asyncio.set_event_loop_policy(GlibEventLoopPolicy())\n\n    app = Gtk.Application(...)\n    app.run()\n\nThe last published version of this project (`v0.6.6\n<https://pypi.org/project/gbulb/0.6.6/>`__) is compatible with versions of\nPyGObject prior to 3.50.0, and CPython 3.8-3.13.\n\n.. |pyversions| image:: https://img.shields.io/pypi/pyversions/gbulb.svg\n   :target: https://pypi.python.org/pypi/gbulb\n   :alt: Python Versions\n\n.. |version| image:: https://img.shields.io/pypi/v/gbulb.svg\n   :target: https://pypi.python.org/pypi/gbulb\n   :alt: PyPI Version\n\n.. |maturity| image:: https://img.shields.io/pypi/status/gbulb.svg\n   :target: https://pypi.python.org/pypi/gbulb\n   :alt: Maturity\n\n.. |license| image:: https://img.shields.io/pypi/l/gbulb.svg\n   :target: https://github.com/beeware/gbulb/blob/main/LICENSE\n   :alt: BSD License\n\n.. |ci| image:: https://github.com/beeware/gbulb/workflows/CI/badge.svg?branch=main\n   :target: https://github.com/beeware/gbulb/actions\n   :alt: Build Status\n\n.. |social| image:: https://img.shields.io/discord/836455665257021440?label=Discord%20Chat&logo=discord&style=plastic\n   :target: https://beeware.org/bee/chat/\n   :alt: Discord server\n\ngbulb\n=====\n\n|pyversions| |version| |maturity| |license| |ci| |social|\n\nGbulb is a Python library that implements a `PEP 3156\n<http://www.python.org/dev/peps/pep-3156/>`__ interface for the `GLib main event\nloop <https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html>`__\nunder UNIX-like systems.\n\nAs much as possible, except where noted below, it mimics asyncio's interface.\nIf you notice any differences, please report them.\n\nRequirements\n------------\n\n- python 3.8+\n- pygobject\n- glib\n- gtk+3 (optional)\n\nUsage\n-----\n\nGLib event loop\n~~~~~~~~~~~~~~~\n\nExample usage::\n\n    import asyncio, gbulb\n    gbulb.install()\n    asyncio.get_event_loop().run_forever()\n\nGtk+ event loop *(suitable for GTK+ applications)*\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nExample usage::\n\n    import asyncio, gbulb\n    gbulb.install(gtk=True)\n    asyncio.get_event_loop().run_forever()\n\nGApplication/GtkApplication event loop\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nExample usage::\n\n    import asyncio, gbulb\n    gbulb.install(gtk=True)  # only necessary if you're using GtkApplication\n\n    loop = asyncio.get_event_loop()\n    loop.run_forever(application=my_gapplication_object)\n\nWaiting on a signal asynchronously\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSee examples/wait_signal.py\n\nKnown issues\n------------\n\n- Windows is not supported, sorry. If you are interested in this, please help\n  me get it working! I don't have Windows so I can't test it.\n\nDivergences with PEP 3156\n-------------------------\n\nIn GLib, the concept of event loop is split in two classes: GLib.MainContext\nand GLib.MainLoop.\n\nThe event loop is mostly implemented by MainContext. MainLoop is just a wrapper\nthat implements the run() and quit() functions. MainLoop.run() atomically\nacquires a MainContext and repeatedly calls MainContext.iteration() until\nMainLoop.quit() is called.\n\nA MainContext is not bound to a particular thread, however it cannot be used\nby multiple threads concurrently. If the context is owned by another thread,\nthen MainLoop.run() will block until the context is released by the other\nthread.\n\nMainLoop.run() may be called recursively by the same thread (this is mainly\nused for implementing modal dialogs in Gtk).\n\nThe issue: given a context, GLib provides no ways to know if there is an\nexisting event loop running for that context. It implies the following\ndivergences with PEP 3156:\n\n- ``.run_forever()`` and ``.run_until_complete()`` are not guaranteed to run\n  immediately. If the context is owned by another thread, then they will\n  block until the context is released by the other thread.\n\n- ``.stop()`` is relevant only when the currently running Glib.MainLoop object\n  was created by this asyncio object (i.e. by calling ``.run_forever()`` or\n  ``.run_until_complete()``). The event loop will quit only when it regains\n  control of the context. This can happen in two cases:\n\n  1. when multiple event loop are enclosed (by creating new ``MainLoop``\n     objects and calling ``.run()`` recursively)\n  2. when the event loop has not even yet started because it is still\n     trying to acquire the context\n\nIt would be wiser not to use any recursion at all. ``GLibEventLoop`` will\nactually prevent you from doing that (in accordance with PEP 3156), however\n``GtkEventLoop`` will allow you to call ``run()`` recursively. You should also keep\nin mind that enclosed loops may be started at any time by third-party code\ncalling GLib's primitives.\n\nTesting\n-------\n\nTesting GBulb requires a Linux environment that has GLib and GTK development\nlibraries available.\n\nThe tests folder contains a Dockerfile that defines a complete testing\nenvironment. To use the Docker environment, run the following from the root of\nthe git checkout:\n\n   $ docker buildx build --tag beeware/gbulb:latest --file ./tests/Dockerfile .\n   $ docker run --rm --volume $(PWD):/home/brutus/gbulb:z -it beeware/gbulb:latest\n\nThis will drop you into an Ubuntu 24.04 shell that has Python 3.8-3.13\ninstalled, mounting the current working directory as `/home/brutus/gbulb`. You\ncan use this to create virtual environments for each Python version.\n\nOnce you have an active virtual environment, run:\n\n   (venv) $ pip install -e .[dev]\n   (venv) $ pytest\n\nto run the test suite. Alternatively, you can install tox, and then run:\n\n   # To test a single Python version\n   (venv) $ tox -e py\n\n   # To test Python 3.10 specifically\n   (venv) $ tox -e py310\n\n   # To test all versions\n   (venv) $ tox\n\nCommunity\n---------\n\ngbulb is part of the `BeeWare suite`_. You can talk to the community through:\n\n* `@pybeeware on Twitter <https://twitter.com/pybeeware>`__\n\n* `Discord <https://beeware.org/bee/chat/>`__\n\n* The gbulb `Github Discussions forum <https://github.com/beeware/gbulb/discussions>`__\n\nWe foster a welcoming and respectful community as described in our\n`BeeWare Community Code of Conduct`_.\n\nContributing\n------------\n\nIf you experience problems with gbulb, `log them on GitHub`_. If you\nwant to contribute code, please `fork the code`_ and `submit a pull request`_.\n\n.. _BeeWare suite: http://beeware.org\n.. _BeeWare Community Code of Conduct: http://beeware.org/community/behavior/\n.. _log them on Github: https://github.com/beeware/gbulb/issues\n.. _fork the code: https://github.com/beeware/gbulb\n.. _submit a pull request: https://github.com/beeware/gbulb/pulls\n",
    "bugtrack_url": null,
    "license": "Apache 2.0",
    "summary": "GLib event loop for Python asyncio",
    "version": "0.6.6",
    "project_urls": {
        "Funding": "https://beeware.org/contributing/membership/",
        "Homepage": "https://github.com/beeware/gbulb",
        "Source": "https://github.com/beeware/gbulb",
        "Tracker": "https://github.com/beeware/gbulb/issues"
    },
    "split_keywords": [
        "gtk",
        " glib",
        " gnome",
        " asyncio",
        " tulip"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f68e8055b9cc6c47e125b4758d716e12dfbf5f146a83d6e1f0417a3c8d4be269",
                "md5": "c35ddbb378d301c5fcc0bdf5ad6b4231",
                "sha256": "4cd003a1bc98a8923ea45b746a6cf69b745a6bfa9f061f8d4edbb628c9702ace"
            },
            "downloads": -1,
            "filename": "gbulb-0.6.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c35ddbb378d301c5fcc0bdf5ad6b4231",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 19484,
            "upload_time": "2024-09-13T02:59:09",
            "upload_time_iso_8601": "2024-09-13T02:59:09.580271Z",
            "url": "https://files.pythonhosted.org/packages/f6/8e/8055b9cc6c47e125b4758d716e12dfbf5f146a83d6e1f0417a3c8d4be269/gbulb-0.6.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6cf4742e5e1534780e6661623ea1df58c9e86650c484297759051fc9c0ee336b",
                "md5": "a4a3c7321e4ef2b0aeec34aeb6c3b21d",
                "sha256": "b66bb1637e956a605636ac2820747583983715a87742beaddeb2e41da37b5154"
            },
            "downloads": -1,
            "filename": "gbulb-0.6.6.tar.gz",
            "has_sig": false,
            "md5_digest": "a4a3c7321e4ef2b0aeec34aeb6c3b21d",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 33326,
            "upload_time": "2024-09-13T02:59:12",
            "upload_time_iso_8601": "2024-09-13T02:59:12.461195Z",
            "url": "https://files.pythonhosted.org/packages/6c/f4/742e5e1534780e6661623ea1df58c9e86650c484297759051fc9c0ee336b/gbulb-0.6.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-09-13 02:59:12",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "beeware",
    "github_project": "gbulb",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "gbulb"
}
        
Elapsed time: 0.32533s