aiologic


Nameaiologic JSON
Version 0.15.0 PyPI version JSON
download
home_pageNone
SummaryGIL-powered* locking library for Python
upload_time2025-11-05 11:28:39
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseNone
keywords anyio async async-await asyncio concurrency eventlet gevent greenlet library locking mypy python synchronization thread-safety threading trio
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ..
  SPDX-FileCopyrightText: 2024 Ilya Egorov <0x42005e1f@gmail.com>
  SPDX-License-Identifier: CC-BY-4.0

.. role:: class(literal)
.. role:: exc(literal)
.. role:: mod(literal)

========
aiologic
========

.. badges-start-marker

|pypi-dw| |pypi-impl| |pypi-pyv| |pypi-types|

.. |pypi-dw| image:: https://img.shields.io/pypi/dw/aiologic
  :target: https://pypistats.org/packages/aiologic
  :alt:
.. |pypi-impl| image:: https://img.shields.io/pypi/implementation/aiologic
  :target: #features
  :alt:
.. |pypi-pyv| image:: https://img.shields.io/pypi/pyversions/aiologic
  :target: #features
  :alt:
.. |pypi-types| image:: https://img.shields.io/pypi/types/aiologic
  :target: #features
  :alt:

.. badges-end-marker

.. description-start-marker

**aiologic** is a locking library for tasks synchronization and their
communication. It provides primitives that are both *async-aware* and
*thread-aware*, and can be used for interaction between:

- async codes (async <-> async) in one thread as regular async primitives
- async codes (async <-> async) in multiple threads (!)
- async code and sync one (async <-> sync) in one thread (!)
- async code and sync one (async <-> sync) in multiple threads (!)
- sync codes (sync <-> sync) in one thread as regular sync primitives
- sync codes (sync <-> sync) in multiple threads as regular sync primitives

Let's take a look at the example:

.. code:: python

    import asyncio

    from threading import Thread

    import aiologic

    lock = aiologic.Lock()


    async def func(i: int, j: int) -> None:
        print(f"thread={i} task={j} start")

        async with lock:
            await asyncio.sleep(1)

        print(f"thread={i} task={j} end")


    async def main(i: int) -> None:
        await asyncio.gather(func(i, 0), func(i, 1))


    Thread(target=asyncio.run, args=[main(0)]).start()
    Thread(target=asyncio.run, args=[main(1)]).start()

It prints something like this:

.. code-block::

    thread=0 task=0 start
    thread=1 task=0 start
    thread=0 task=1 start
    thread=1 task=1 start
    thread=0 task=0 end
    thread=1 task=0 end
    thread=0 task=1 end
    thread=1 task=1 end

As you can see, tasks from different event loops are all able to acquire
:class:`aiologic.Lock`. In the same case if you use :class:`asyncio.Lock`, it
will raise a :exc:`RuntimeError`. And :class:`threading.Lock` will cause a
deadlock.

.. description-end-marker

Features
========

.. features-start-marker

* Python 3.8+ support
* `CPython <https://www.python.org/>`__ and `PyPy <https://pypy.org/>`__
  support
* `Pickling <https://docs.python.org/3/library/pickle.html>`__ and `weakrefing
  <https://docs.python.org/3/library/weakref.html>`__ support
* Cancellation and timeouts support
* Optional `Trio-style checkpoints <https://trio.readthedocs.io/en/stable/
  reference-core.html#checkpoints>`__:

  * enabled by default for Trio itself
  * disabled by default for all others

* Only one checkpoint per asynchronous call:

  * exactly one context switch if checkpoints are enabled
  * zero or one context switch if checkpoints are disabled

* Fairness wherever possible (with some caveats)
* Thread-safety wherever possible
* Lock-free implementation (with some exceptions)
* Bundled stub files

Synchronization primitives:

* Events: one-time, reusable, and countdown
* Barriers: single-use, cyclic, and reusable
* Semaphores: counting, bounded, and binary
* Capacity limiters: borrowable, and reentrant
* Locks: ownable, and reentrant
* `Readers-writer locks (external) <https://gist.github.com/x42005e1f/
  a50d0744013b7bbbd7ded608d6a3845b>`__
* Condition variables

Communication primitives:

* Queues: FIFO, LIFO, and priority

Non-blocking primitives:

* Flags
* Resource guards

Supported concurrency libraries:

.. libraries-start-marker

* `asyncio`_, `curio`_, `trio`_, and `anyio`_ (coroutine-based)
* `eventlet`_, and `gevent`_ (greenlet-based)
* `threading`_ (thread-based)

.. _asyncio: https://docs.python.org/3/library/asyncio.html
.. _curio: https://curio.readthedocs.io
.. _trio: https://trio.readthedocs.io
.. _anyio: https://anyio.readthedocs.io
.. _eventlet: https://eventlet.readthedocs.io
.. _gevent: https://www.gevent.org/
.. _threading: https://docs.python.org/3/library/threading.html

.. libraries-end-marker

All synchronization, communication, and non-blocking primitives are implemented
entirely on effectively atomic operations, which gives `an incredible speedup
on PyPy <https://gist.github.com/x42005e1f/149d3994d5f7bd878def71d5404e6ea4>`__
compared to alternatives from the :mod:`threading` module. All this works
because of GIL, but per-object locks also ensure that `the same operations are
still atomic <https://peps.python.org/pep-0703/#container-thread-safety>`__, so
aiologic also works when running in a `free-threaded mode <https://
docs.python.org/3.13/whatsnew/3.13.html#free-threaded-cpython>`__.

.. features-end-marker

Installation
============

.. installation-start-marker

Install from `PyPI <https://pypi.org/project/aiologic/>`__ (stable):

.. code:: console

    pip install aiologic

Or from `GitHub <https://github.com/x42005e1f/aiologic>`__ (latest):

.. code:: console

    pip install git+https://github.com/x42005e1f/aiologic.git

You can also use other package managers, such as `uv <https://github.com/
astral-sh/uv>`__.

.. installation-end-marker

Documentation
=============

Read the Docs: https://aiologic.readthedocs.io (official)

DeepWiki: https://deepwiki.com/x42005e1f/aiologic (AI generated)

Communication channels
======================

GitHub Discussions: https://github.com/x42005e1f/aiologic/discussions (ideas,
questions)

GitHub Issues: https://github.com/x42005e1f/aiologic/issues (bug tracker)

You can also send an email to 0x42005e1f@gmail.com with any feedback.

Support
=======

If you like aiologic and want to support its development, please star `its
repository on GitHub <https://github.com/x42005e1f/aiologic>`__.

.. image:: https://starchart.cc/x42005e1f/aiologic.svg?variant=adaptive
  :target: https://starchart.cc/x42005e1f/aiologic

License
=======

.. license-start-marker

The aiologic library is `REUSE-compliant <https://api.reuse.software/info/
github.com/x42005e1f/aiologic>`__ and is offered under multiple licenses:

* All original source code is licensed under `ISC`_.
* All original test code is licensed under `0BSD`_.
* All documentation is licensed under `CC-BY-4.0`_.
* All configuration is licensed under `CC0-1.0`_.

For more accurate information, check the individual files.

.. _ISC: https://choosealicense.com/licenses/isc/
.. _0BSD: https://choosealicense.com/licenses/0bsd/
.. _CC-BY-4.0: https://choosealicense.com/licenses/cc-by-4.0/
.. _CC0-1.0: https://choosealicense.com/licenses/cc0-1.0/

.. license-end-marker

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "aiologic",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "anyio, async, async-await, asyncio, concurrency, eventlet, gevent, greenlet, library, locking, mypy, python, synchronization, thread-safety, threading, trio",
    "author": null,
    "author_email": "Ilya Egorov <0x42005e1f@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/85/ae/93a6dcdcffc15c890fc3d899e62f3a16eefb507553c6e531f26cbe5799da/aiologic-0.15.0.tar.gz",
    "platform": null,
    "description": "..\n  SPDX-FileCopyrightText: 2024 Ilya Egorov <0x42005e1f@gmail.com>\n  SPDX-License-Identifier: CC-BY-4.0\n\n.. role:: class(literal)\n.. role:: exc(literal)\n.. role:: mod(literal)\n\n========\naiologic\n========\n\n.. badges-start-marker\n\n|pypi-dw| |pypi-impl| |pypi-pyv| |pypi-types|\n\n.. |pypi-dw| image:: https://img.shields.io/pypi/dw/aiologic\n  :target: https://pypistats.org/packages/aiologic\n  :alt:\n.. |pypi-impl| image:: https://img.shields.io/pypi/implementation/aiologic\n  :target: #features\n  :alt:\n.. |pypi-pyv| image:: https://img.shields.io/pypi/pyversions/aiologic\n  :target: #features\n  :alt:\n.. |pypi-types| image:: https://img.shields.io/pypi/types/aiologic\n  :target: #features\n  :alt:\n\n.. badges-end-marker\n\n.. description-start-marker\n\n**aiologic** is a locking library for tasks synchronization and their\ncommunication. It provides primitives that are both *async-aware* and\n*thread-aware*, and can be used for interaction between:\n\n- async codes (async <-> async) in one thread as regular async primitives\n- async codes (async <-> async) in multiple threads (!)\n- async code and sync one (async <-> sync) in one thread (!)\n- async code and sync one (async <-> sync) in multiple threads (!)\n- sync codes (sync <-> sync) in one thread as regular sync primitives\n- sync codes (sync <-> sync) in multiple threads as regular sync primitives\n\nLet's take a look at the example:\n\n.. code:: python\n\n    import asyncio\n\n    from threading import Thread\n\n    import aiologic\n\n    lock = aiologic.Lock()\n\n\n    async def func(i: int, j: int) -> None:\n        print(f\"thread={i} task={j} start\")\n\n        async with lock:\n            await asyncio.sleep(1)\n\n        print(f\"thread={i} task={j} end\")\n\n\n    async def main(i: int) -> None:\n        await asyncio.gather(func(i, 0), func(i, 1))\n\n\n    Thread(target=asyncio.run, args=[main(0)]).start()\n    Thread(target=asyncio.run, args=[main(1)]).start()\n\nIt prints something like this:\n\n.. code-block::\n\n    thread=0 task=0 start\n    thread=1 task=0 start\n    thread=0 task=1 start\n    thread=1 task=1 start\n    thread=0 task=0 end\n    thread=1 task=0 end\n    thread=0 task=1 end\n    thread=1 task=1 end\n\nAs you can see, tasks from different event loops are all able to acquire\n:class:`aiologic.Lock`. In the same case if you use :class:`asyncio.Lock`, it\nwill raise a :exc:`RuntimeError`. And :class:`threading.Lock` will cause a\ndeadlock.\n\n.. description-end-marker\n\nFeatures\n========\n\n.. features-start-marker\n\n* Python 3.8+ support\n* `CPython <https://www.python.org/>`__ and `PyPy <https://pypy.org/>`__\n  support\n* `Pickling <https://docs.python.org/3/library/pickle.html>`__ and `weakrefing\n  <https://docs.python.org/3/library/weakref.html>`__ support\n* Cancellation and timeouts support\n* Optional `Trio-style checkpoints <https://trio.readthedocs.io/en/stable/\n  reference-core.html#checkpoints>`__:\n\n  * enabled by default for Trio itself\n  * disabled by default for all others\n\n* Only one checkpoint per asynchronous call:\n\n  * exactly one context switch if checkpoints are enabled\n  * zero or one context switch if checkpoints are disabled\n\n* Fairness wherever possible (with some caveats)\n* Thread-safety wherever possible\n* Lock-free implementation (with some exceptions)\n* Bundled stub files\n\nSynchronization primitives:\n\n* Events: one-time, reusable, and countdown\n* Barriers: single-use, cyclic, and reusable\n* Semaphores: counting, bounded, and binary\n* Capacity limiters: borrowable, and reentrant\n* Locks: ownable, and reentrant\n* `Readers-writer locks (external) <https://gist.github.com/x42005e1f/\n  a50d0744013b7bbbd7ded608d6a3845b>`__\n* Condition variables\n\nCommunication primitives:\n\n* Queues: FIFO, LIFO, and priority\n\nNon-blocking primitives:\n\n* Flags\n* Resource guards\n\nSupported concurrency libraries:\n\n.. libraries-start-marker\n\n* `asyncio`_, `curio`_, `trio`_, and `anyio`_ (coroutine-based)\n* `eventlet`_, and `gevent`_ (greenlet-based)\n* `threading`_ (thread-based)\n\n.. _asyncio: https://docs.python.org/3/library/asyncio.html\n.. _curio: https://curio.readthedocs.io\n.. _trio: https://trio.readthedocs.io\n.. _anyio: https://anyio.readthedocs.io\n.. _eventlet: https://eventlet.readthedocs.io\n.. _gevent: https://www.gevent.org/\n.. _threading: https://docs.python.org/3/library/threading.html\n\n.. libraries-end-marker\n\nAll synchronization, communication, and non-blocking primitives are implemented\nentirely on effectively atomic operations, which gives `an incredible speedup\non PyPy <https://gist.github.com/x42005e1f/149d3994d5f7bd878def71d5404e6ea4>`__\ncompared to alternatives from the :mod:`threading` module. All this works\nbecause of GIL, but per-object locks also ensure that `the same operations are\nstill atomic <https://peps.python.org/pep-0703/#container-thread-safety>`__, so\naiologic also works when running in a `free-threaded mode <https://\ndocs.python.org/3.13/whatsnew/3.13.html#free-threaded-cpython>`__.\n\n.. features-end-marker\n\nInstallation\n============\n\n.. installation-start-marker\n\nInstall from `PyPI <https://pypi.org/project/aiologic/>`__ (stable):\n\n.. code:: console\n\n    pip install aiologic\n\nOr from `GitHub <https://github.com/x42005e1f/aiologic>`__ (latest):\n\n.. code:: console\n\n    pip install git+https://github.com/x42005e1f/aiologic.git\n\nYou can also use other package managers, such as `uv <https://github.com/\nastral-sh/uv>`__.\n\n.. installation-end-marker\n\nDocumentation\n=============\n\nRead the Docs: https://aiologic.readthedocs.io (official)\n\nDeepWiki: https://deepwiki.com/x42005e1f/aiologic (AI generated)\n\nCommunication channels\n======================\n\nGitHub Discussions: https://github.com/x42005e1f/aiologic/discussions (ideas,\nquestions)\n\nGitHub Issues: https://github.com/x42005e1f/aiologic/issues (bug tracker)\n\nYou can also send an email to 0x42005e1f@gmail.com with any feedback.\n\nSupport\n=======\n\nIf you like aiologic and want to support its development, please star `its\nrepository on GitHub <https://github.com/x42005e1f/aiologic>`__.\n\n.. image:: https://starchart.cc/x42005e1f/aiologic.svg?variant=adaptive\n  :target: https://starchart.cc/x42005e1f/aiologic\n\nLicense\n=======\n\n.. license-start-marker\n\nThe aiologic library is `REUSE-compliant <https://api.reuse.software/info/\ngithub.com/x42005e1f/aiologic>`__ and is offered under multiple licenses:\n\n* All original source code is licensed under `ISC`_.\n* All original test code is licensed under `0BSD`_.\n* All documentation is licensed under `CC-BY-4.0`_.\n* All configuration is licensed under `CC0-1.0`_.\n\nFor more accurate information, check the individual files.\n\n.. _ISC: https://choosealicense.com/licenses/isc/\n.. _0BSD: https://choosealicense.com/licenses/0bsd/\n.. _CC-BY-4.0: https://choosealicense.com/licenses/cc-by-4.0/\n.. _CC0-1.0: https://choosealicense.com/licenses/cc0-1.0/\n\n.. license-end-marker\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "GIL-powered* locking library for Python",
    "version": "0.15.0",
    "project_urls": {
        "Changelog": "https://aiologic.readthedocs.io/latest/changelog.html",
        "Documentation": "https://aiologic.readthedocs.io",
        "Homepage": "https://github.com/x42005e1f/aiologic"
    },
    "split_keywords": [
        "anyio",
        " async",
        " async-await",
        " asyncio",
        " concurrency",
        " eventlet",
        " gevent",
        " greenlet",
        " library",
        " locking",
        " mypy",
        " python",
        " synchronization",
        " thread-safety",
        " threading",
        " trio"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "21bd1666bf801f84e6f18872653a5884a7d15d7dbcae307899f5603b11d1438b",
                "md5": "4fe9b80267a085f954ea3a06ffa73936",
                "sha256": "35f9f906bd80424b39c475b3b7f8dd853ee279a176b73b9bc290a41feb1b0db7"
            },
            "downloads": -1,
            "filename": "aiologic-0.15.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "4fe9b80267a085f954ea3a06ffa73936",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 124401,
            "upload_time": "2025-11-05T11:28:38",
            "upload_time_iso_8601": "2025-11-05T11:28:38.259138Z",
            "url": "https://files.pythonhosted.org/packages/21/bd/1666bf801f84e6f18872653a5884a7d15d7dbcae307899f5603b11d1438b/aiologic-0.15.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "85ae93a6dcdcffc15c890fc3d899e62f3a16eefb507553c6e531f26cbe5799da",
                "md5": "0ed63a0c6f8d4c40abe3fe04d1f6f84f",
                "sha256": "2aa851d2298588f9bfa543a425773e8c3e07069f96c09ccc7106c0dd899fe5fd"
            },
            "downloads": -1,
            "filename": "aiologic-0.15.0.tar.gz",
            "has_sig": false,
            "md5_digest": "0ed63a0c6f8d4c40abe3fe04d1f6f84f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 210766,
            "upload_time": "2025-11-05T11:28:39",
            "upload_time_iso_8601": "2025-11-05T11:28:39.744573Z",
            "url": "https://files.pythonhosted.org/packages/85/ae/93a6dcdcffc15c890fc3d899e62f3a16eefb507553c6e531f26cbe5799da/aiologic-0.15.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-11-05 11:28:39",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "x42005e1f",
    "github_project": "aiologic",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "aiologic"
}
        
Elapsed time: 1.86054s