From 87bcb3cdf859e949d070e0082e9ebc0ef16769a8 Mon Sep 17 00:00:00 2001
From: jakkdl
Date: Wed, 22 May 2024 12:46:31 +0200
Subject: [PATCH] bump version, add changelog entry. Various small improvements
to docs/usage.
---
docs/changelog.rst | 5 ++
docs/index.rst | 2 +-
docs/rules.rst | 22 +++++++
docs/usage.rst | 121 +++++++++++++++++++++++++++++----------
flake8_async/__init__.py | 2 +-
5 files changed, 120 insertions(+), 32 deletions(-)
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 9251246..9e50f04 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -4,6 +4,11 @@ Changelog
*[CalVer, YY.month.patch](https://calver.org/)*
+24.5.3
+======
+- Rename config option ``trio200-blocking-calls`` to :ref:`async200-blocking-calls`.
+- ``trio200-blocking-calls`` is now deprecated.
+
24.5.2
======
- ASYNC101 now also warns on anyio & asyncio taskgroups.
diff --git a/docs/index.rst b/docs/index.rst
index c610291..af37fab 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -16,7 +16,7 @@ to likely performance issues, to minor points of idiom that might signal
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.
+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.
diff --git a/docs/rules.rst b/docs/rules.rst
index 26e5dca..0964146 100644
--- a/docs/rules.rst
+++ b/docs/rules.rst
@@ -16,7 +16,13 @@ General rules
- **ASYNC110**: ``while : await [trio/anyio].sleep()`` should be replaced by a ``[trio/anyio].Event``.
- **ASYNC111**: Variable, from context manager opened inside nursery, passed to ``start[_soon]`` might be invalidly accessed while in use, due to context manager closing before the nursery. This is usually a bug, and nurseries should generally be the inner-most context manager.
- **ASYNC112**: Nursery body with only a call to ``nursery.start[_soon]`` and not passing itself as a parameter can be replaced with a regular function call.
+
+ .. _async113:
+
- **ASYNC113**: Using :meth:`trio.Nursery.start_soon` in ``__aenter__`` doesn't wait for the task to begin. Consider replacing with ``nursery.start``.
+
+ .. _async114:
+
- **ASYNC114**: Startable function (i.e. has a ``task_status`` keyword parameter) not in ``--startable-in-context-manager`` parameter list, please add it so ASYNC113 can catch errors when using it.
- **ASYNC115**: Replace ``[trio/anyio].sleep(0)`` with the more suggestive ``[trio/anyio].lowlevel.checkpoint()``.
- **ASYNC116**: ``[trio/anyio].sleep()`` with >24 hour interval should usually be ``[trio/anyio].sleep_forever()``.
@@ -33,6 +39,7 @@ Blocking sync calls in async functions
Note: 22X, 23X and 24X has not had asyncio-specific suggestions written.
+.. _async200:
- **ASYNC200**: User-configured error for blocking sync calls in async functions. Does nothing by default, see :ref:`async200-blocking-calls` for how to configure it.
- **ASYNC210**: Sync HTTP call in async function, use ``httpx.AsyncClient``. This and the other ASYNC21x checks look for usage of ``urllib3`` and ``httpx.Client``, and recommend using ``httpx.AsyncClient`` as that's the largest http client supporting anyio/trio.
@@ -55,11 +62,26 @@ Optional rules disabled by default
.. _async900:
- **ASYNC900**: Async generator without ``@asynccontextmanager`` not allowed. You might want to enable this on a codebase since async generators are inherently unsafe and cleanup logic might not be performed. See https://github.com/python-trio/flake8-async/issues/211 and https://discuss.python.org/t/using-exceptiongroup-at-anthropic-experience-report/20888/6 for discussion.
+
+ .. _async910:
+
- **ASYNC910**: Exit or ``return`` from async function with no guaranteed checkpoint or exception since function definition. You might want to enable this on a codebase to make it easier to reason about checkpoints, and make the logic of ASYNC911 correct.
+
+ .. _async911:
+
- **ASYNC911**: Exit, ``yield`` or ``return`` from async iterable with no guaranteed checkpoint since possible function entry (yield or function definition)
Checkpoints are ``await``, ``async for``, and ``async with`` (on one of enter/exit).
- **ASYNC912**: A timeout/cancelscope has checkpoints, but they're not guaranteed to run. Similar to ASYNC100, but it does not warn on trivial cases where there is no checkpoint at all. It instead shares logic with ASYNC910 and ASYNC911 for parsing conditionals and branches.
+.. _autofix-support:
+
+Autofix support
+===============
+The following rules support :ref:`autofixing `.
+- ASYNC100
+- ASYNC910
+- ASYNC911
+
Removed rules
================
diff --git a/docs/usage.rst b/docs/usage.rst
index 78aba3b..c351c48 100644
--- a/docs/usage.rst
+++ b/docs/usage.rst
@@ -2,7 +2,9 @@
Installation
************
-.. code-block:: console
+Install from `PyPI `__
+
+.. code-block:: sh
pip install flake8-async
@@ -23,7 +25,7 @@ install and run through flake8
install and run with pre-commit
===============================
-If you use `pre-commit `_, you can use it with flake8-async by
+If you use `pre-commit `__, you can use it with flake8-async by
adding the following to your ``.pre-commit-config.yaml``:
.. code-block:: yaml
@@ -38,6 +40,8 @@ adding the following to your ``.pre-commit-config.yaml``:
This is often considerably faster for large projects, because ``pre-commit``
can avoid running ``flake8-async`` on unchanged files.
+``flake8-async`` does not retain any memory between files, they are parsed completely independently.
+
Afterwards, run
.. code-block:: sh
@@ -45,10 +49,12 @@ Afterwards, run
pip install pre-commit flake8-async
pre-commit run .
+.. _run_standalone:
+
install and run as standalone
=============================
-If inside a git repository, running without arguments will run it against all ``*.py`` files in the repository.
+If inside a git repository, running without arguments will run it against all ``*.py`` files in the repository tree.
.. code-block:: sh
@@ -81,7 +87,7 @@ Run through ruff
================
`Ruff `_ is a linter and formatter that reimplements a lot of rules from various flake8 plugins.
-They currently only support a small subset of the rules though, see https://github.com/astral-sh/ruff/issues/8451 for current status and https://docs.astral.sh/ruff/rules/#flake8-async-async for documentation.
+They currently only support a small subset of the ``flake8-async`` rules though, see https://github.com/astral-sh/ruff/issues/8451 for current status and https://docs.astral.sh/ruff/rules/#flake8-async-async for documentation.
*************
Configuration
@@ -105,60 +111,110 @@ config files since flake8>=6, as flake8 tries to validate correct
configuration with a regex. We have decided not to conform to this, as it
would be a breaking change for end-users requiring them to update ``noqa``\ s
and configurations, we think the ``ASYNC`` code is much more readable than
-e.g. ``ASYxxx``, and ruff does not enforce such a limit. The easiest option
-for users hitting this error is to instead use the ``--disable`` option as
-documented `below <#--disable>`__. See further discussion and other
+e.g. ``ASYxxx``, and ruff does not enforce such a limit.
+The easiest option for users hitting this error is to instead use the :ref:`disable`
+option.
+See further discussion and other
workarounds in https://github.com/python-trio/flake8-async/issues/230.
+.. _enable:
-``--enable``
+``enable``
------------
-Comma-separated list of error codes to enable, similar to flake8 --select but is additionally more performant as it will disable non-enabled visitors from running instead of just silencing their errors.
+Comma-separated list of error codes to enable, similar to flake8 --select but is additionally more performant as it will disable non-enabled visitors from running instead of just silencing their errors. Defaults to "ASYNC".
+
+Example
+^^^^^^^
+.. code-block:: none
-.. _--disable:
+ enable=ASYNC1,ASYNC200
-``--disable``
+.. _disable:
+
+``disable``
-------------
Comma-separated list of error codes to disable, similar to flake8 ``--ignore`` but is additionally more performant as it will disable non-enabled visitors from running instead of just silencing their errors. It will also bypass errors introduced in flake8>=6, see above.
+This is parsed after :ref:`enable`, so if a rule is both "enabled" and "disabled" it will be disabled.
+Defaults to "ASYNC9".
+
+Example
+^^^^^^^
+.. code-block:: none
+
+ disable=ASYNC91,ASYNC117
-``--autofix``
+.. _autofix:
+
+``autofix``
-------------
-Comma-separated list of error-codes to enable autofixing for if implemented. Requires running as a standalone program. Pass ``--autofix=ASYNC`` to enable all autofixes.
+Comma-separated list of error-codes to enable autofixing for if implemented.
+Requires :ref:`running as a standalone program `.
+Only a subset of rules support autofixing, see :ref:`this list `.
+Pass ``--autofix=ASYNC`` to enable all available autofixes.
+
+Defaults to an empty list.
+Example
+^^^^^^^
+.. code-block:: none
-``--error-on-autofix``
+ autofix=ASYNC
+
+
+``error-on-autofix``
----------------------
-Whether to also print an error message for autofixed errors.
+Whether to also print an error message for autofixed errors. Defaults to ``False``
+
+Example
+^^^^^^^
+.. code-block:: none
+
+ error-on-autofix=True
Modifying rule behaviour
========================
-.. _--anyio:
+.. _anyio:
-``--anyio``
+``anyio``
-----------
-Change the default library to be anyio instead of trio. If trio is imported it will assume both are available and print suggestions with [anyio/trio].
+Change the default library to be anyio instead of trio. This is mostly used for the sake of printing suggestions in error messages, but may affect some logic. If additional libraries are imported other than the default then rules will assume multiple are available simultaneously. It is currently not possible to set multiple default libraries, other than `anyio`+`asyncio`.
+
+Example
+^^^^^^^
+.. code-block:: none
-``--asyncio``
+ anyio=True
+
+.. _asyncio:
+
+``asyncio``
-------------
-Set default library to be ``asyncio``. See :ref:`--anyio`
+Set default library to be ``asyncio``. See :ref:`anyio`
+
+Example
+^^^^^^^
+.. code-block:: none
+
+ asyncio=True
``no-checkpoint-warning-decorators``
------------------------------------
-Comma-separated list of decorators to disable checkpointing checks for, turning off ASYNC910 and ASYNC911 warnings for functions decorated with any decorator matching any in the list. Matching is done with `fnmatch `_. Defaults to disabling for ``asynccontextmanager``.
+Comma-separated list of decorators to disable checkpointing checks for, turning off :ref:`ASYNC910 ` and :ref:`ASYNC911 ` warnings for functions decorated with any decorator matching any in the list. Matching is done with `fnmatch `_. Defaults to disabling for ``asynccontextmanager``.
Decorators-to-match must be identifiers or dotted names only (not PEP-614 expressions), and will match against the name only - e.g. ``foo.bar`` matches ``foo.bar``, ``foo.bar()``, and ``foo.bar(args, here)``, etc.
-For example:
+Example
+^^^^^^^
-::
+.. code-block:: none
no-checkpoint-warning-decorators =
mydecorator,
@@ -171,9 +227,13 @@ For example:
Comma-separated list of methods which should be used with ``.start()`` when opening a context manager,
in addition to the default ``trio.run_process``, ``trio.serve_tcp``, ``trio.serve_ssl_over_tcp``, and
-``trio.serve_listeners``. Names must be valid identifiers as per ``str.isidentifier()``. For example:
+``trio.serve_listeners``. Names must be valid identifiers as per ``str.isidentifier()``.
+Used by :ref:`ASYNC113 `, and :ref:`ASYNC114 ` will warn when encountering methods not in the list.
+
+Example
+^^^^^^^
-::
+.. code-block:: none
startable-in-context-manager =
myfun,
@@ -182,15 +242,16 @@ in addition to the default ``trio.run_process``, ``trio.serve_tcp``, ``trio.serv
.. _async200-blocking-calls:
``async200-blocking-calls``
----------------------------
+-----------------------------
-Comma-separated list of pairs of values separated by ``->`` (optional whitespace stripped), where the first is a pattern for a call that should raise an error if found inside an async function, and the second is what should be suggested to use instead. It uses fnmatch as per `no-checkpoint-warning-decorators`_ for matching. The part after ``->`` is not used by the checker other than when printing the error, so you could add extra info there if you want.
+Comma-separated list of pairs of values separated by ``->`` (optional whitespace stripped), where the first is a pattern for a call that should raise :ref:`ASYNC200 ` if found inside an async function, and the second is what should be suggested to use instead. It uses fnmatch as per `no-checkpoint-warning-decorators`_ for matching. The part after ``->`` is not used by the checker other than when printing the error, so you could add extra info there if you want.
The format of the error message is ``User-configured blocking sync call {0} in async function, consider replacing with {1}.``, where ``{0}`` is the pattern the call matches and ``{1}`` is the suggested replacement.
-Example:
+Example
+^^^^^^^
-::
+.. code-block:: none
async200-blocking-calls =
my_blocking_call -> async.alternative,
@@ -201,7 +262,7 @@ Example:
Specified patterns must not have parentheses, and will only match when the pattern is the name of a call, so given the above configuration
-::
+.. code-block:: python
async def my_function():
my_blocking_call() # this would raise an error
diff --git a/flake8_async/__init__.py b/flake8_async/__init__.py
index 8fe89fa..525f55d 100644
--- a/flake8_async/__init__.py
+++ b/flake8_async/__init__.py
@@ -38,7 +38,7 @@
# CalVer: YY.month.patch, e.g. first release of July 2022 == "22.7.1"
-__version__ = "24.5.2"
+__version__ = "24.5.3"
# taken from https://github.com/Zac-HD/shed