Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rules documentation improvements #248

Merged
merged 15 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ Pairs well with flake8-bugbear.
Some checks are incorporated into [ruff](https://github.com/astral-sh/ruff).

This plugin was previously known as flake8-trio, and there was a separate small plugin known as flake8-async for asyncio. But this plugin was a superset of the checks in flake8-async, and support for anyio was added, so it's now named flake8-async to more properly convey its usage. At the same time all error codes were renamed from TRIOxxx to ASYNCxxx, as was previously used by the old flake8-async.

## Rules
https://flake8-async.readthedocs.io/en/latest/rules.html
131 changes: 131 additions & 0 deletions docs/glossary.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
********
Glossary
********

.. _cancel_scope:

cancel scope
------------
A cancel scope is a context manager which can request the library cancels
whatever task is executing in the body of the ``with`` (or ``async with``)
block. A cancel scope is the key component of a :ref:`timeout context <timeout_context>`,
and used in :ref:`TaskGroups / Nurseries <taskgroup_nursery>` to cancel any remaining child tasks if one raises an
exception.

* Trio has an explicit :class:`trio.CancelScope` type, and `general documentation
<https://trio.readthedocs.io/en/stable/reference-core.html#cancellation-and-timeouts>`__
about cancellation and timeouts.

* AnyIO similarly has :class:`anyio.CancelScope` and `documentation
<https://anyio.readthedocs.io/en/stable/cancellation.html>`__ of cancellation handling.

* asyncio does not have an explicit cancel-scope type, but incorporates similar semantics
in :func:`asyncio.timeout` and :class:`asyncio.TaskGroup` and has `some documentation
<https://docs.python.org/3/library/asyncio-task.html#task-cancellation>`__.


.. _timeout_context:

timeout context
---------------
A context manager that enforces a timeout on a block of code, by cancelling it
after a specified duration or at a preset time. The timeout can also be
rescheduled after creation. They are internally implemented with a :ref:`cancel scope <cancel_scope>`,
which in anyio & trio can be directly initialized with a deadline.

* Trio has :func:`trio.move_on_after`, :func:`trio.move_on_at`,
:func:`trio.fail_after`, :func:`trio.fail_at`, and :class:`trio.CancelScope`
(`docs <https://trio.readthedocs.io/en/stable/reference-core.html#cancellation-and-timeouts>`__)

* AnyIO has :func:`anyio.move_on_after`, :func:`anyio.fail_after`, and :class:`anyio.CancelScope`
(`docs <https://anyio.readthedocs.io/en/stable/cancellation.html>`__)

* asyncio has :func:`asyncio.timeout` and :func:`asyncio.timeout_at`
(`docs <https://docs.python.org/3/library/asyncio-task.html#timeouts>`__)


.. _taskgroup_nursery:

TaskGroup / Nursery
-------------------

A collection of child Tasks that can run concurrently. Internally contains a
:ref:`cancel scope <cancel_scope>` for canceling any remaining child tasks if
one raises an exception.

* Trio has :class:`trio.Nursery`, created with :func:`trio.open_nursery`
(`docs <https://trio.readthedocs.io/en/stable/reference-core.html#tasks-let-you-do-multiple-things-at-once>`__)

* AnyIO has :class:`anyio.abc.TaskGroup`, created with :func:`anyio.create_task_group`
(`docs <https://anyio.readthedocs.io/en/stable/tasks.html>`__)

* asyncio has :class:`asyncio.TaskGroup` since python 3.11
(`docs <https://docs.python.org/3/library/asyncio-task.html#asyncio.TaskGroup>`__)


.. _cancellation:
.. _cancelled:

Cancelled / CancelledError
--------------------------

Handling cancellation is very sensitive, and you generally never want to catch a
cancellation exception without letting it propagate to the library.

General documentation on cancellation in the different async libraries:

* `Trio <https://trio.readthedocs.io/en/stable/reference-core.html#cancellation-and-timeouts>`__
* `AnyIO <https://anyio.readthedocs.io/en/stable/cancellation.html>`__
* `asyncio <https://docs.python.org/3/library/asyncio-task.html#task-cancellation>`__

Exception classes:

* :class:`trio.Cancelled`
* :func:`anyio.get_cancelled_exc_class`
* :class:`asyncio.CancelledError`

.. _checkpoint:

Checkpoint
----------
Checkpoints are points where the async backend checks for cancellation and
can switch which task is running, in an ``await``, ``async for``, or ``async with``
expression. Regular checkpoints can be important for both performance and correctness.

Trio has extensive and detailed documentation on the concept of
:external+trio:ref:`checkpoints <checkpoints>`, and guarantees that all async
functions defined by Trio will either checkpoint or raise an exception when
``await``-ed. ``async for`` on Trio iterables will checkpoint before each
iteration, and when exhausting the iterator, and ``async with`` will checkpoint
on at least one of enter/exit.

asyncio does not place any guarantees on if or when asyncio functions will
checkpoint. This means that enabling and adhering to :ref:`ASYNC91x <ASYNC910>`
will still not guarantee checkpoints.

For anyio it will depend on the current backend.

When using Trio (or an AnyIO library that people might use on Trio), it can be
very helpful to ensure that your own code adheres to the same guarantees as
Trio. For this we supply the :ref:`ASYNC91x <ASYNC910>` rules. To make it
possible to reason the rules will also assume that all other async functions
also adhere to those rules. This means you must be careful if you're using
3rd-party async libraries.

To insert a checkpoint with no other side effects, you can use
:func:`trio.lowlevel.checkpoint`/:func:`anyio.lowlevel.checkpoint`/:func:`asyncio.sleep(0)
<asyncio.sleep>`

.. _channel_stream_queue:

Channel / Stream / Queue
------------------------
Interfaces used for communicating between tasks, processes, the network, etc.

.. anyio streams is a :doc: and not a :label:, so we can't link with intersphinx :(

.. _anyio_streams: https://anyio.readthedocs.io/en/stable/streams.html#streams

* Trio has :ref:`channels <channels>` for python objects and :ref:`streams <abstract-stream-api>` for bytes.
* AnyIO has ``byte`` and ``object`` `streams <anyio_streams>`_
* asyncio has :ref:`queues <asyncio-queues>` for python objects and :ref:`streams <asyncio-streams>` for bytes.
8 changes: 5 additions & 3 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ flake8-async
############


A highly opinionated flake8 plugin for problems related to `Trio <https://github.com/python-trio/trio>`_, `AnyIO <https://github.com/agronholm/anyio>`_, or `asyncio <https://docs.python.org/3/library/asyncio.html>`_.
A highly opinionated flake8 plugin for problems related to `Trio <https://github.com/python-trio/trio>`__, `AnyIO <https://github.com/agronholm/anyio>`__, or `asyncio <https://docs.python.org/3/library/asyncio.html>`__.


This can include anything from outright bugs, to pointless/dead code,
Expand All @@ -17,10 +17,10 @@ a misunderstanding.


The plugin may well be too noisy or pedantic depending on your requirements or opinions, in which case you should consider :ref:`disable` for those rules.
Pairs well with flake8-bugbear.
Pairs well with `flake8-bugbear <https://github.com/PyCQA/flake8-bugbear>`__.


Some rules are incorporated into `ruff <https://docs.astral.sh/ruff/rules/#flake8-async-async>`_.
Some rules are incorporated into `ruff <https://docs.astral.sh/ruff/rules/#flake8-async-async>`__.


We previously maintained separate flake8-async and flake8-trio plugins, but merged both into this plugin under the more general "flake8-async" name after flake8-trio grew support for anyio and asyncio and became a superset of the former flake8-async. All flake8-trio error codes were renamed from TRIOxxx to ASYNCxxx and the flake8-trio package is now deprecated.
Expand All @@ -33,6 +33,7 @@ Contents:

usage
rules
glossary
changelog
contributing

Expand All @@ -46,5 +47,6 @@ Indices and tables
* :ref:`search`
* :doc:`usage`
* :doc:`rules`
* :doc:`glossary`
* :doc:`changelog`
* :doc:`contributing`
Loading
Loading