Skip to content

async102 & async120 no longer requires cancelscope to have a timeout #380

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

Merged
merged 5 commits into from
May 7, 2025
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 4 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ Changelog

`CalVer, YY.month.patch <https://calver.org/>`_

25.5.2
======
- :ref:`ASYNC120 <async120>` no longer requires cancel scopes to have a timeout. https://github.com/python-trio/flake8-async/issues/272
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's give the url some link text, e.g. (issue #272)


25.5.1
======
- Fixed :ref:`ASYNC113 <async113>` false alarms if the ``start_soon`` calls are in a nursery cm that was closed before the yield point.
Expand Down
2 changes: 1 addition & 1 deletion docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ adding the following to your ``.pre-commit-config.yaml``:
minimum_pre_commit_version: '2.9.0'
repos:
- repo: https://github.com/python-trio/flake8-async
rev: 25.5.1
rev: 25.5.2
hooks:
- id: flake8-async
# args: ["--enable=ASYNC100,ASYNC112", "--disable=", "--autofix=ASYNC"]
Expand Down
2 changes: 1 addition & 1 deletion flake8_async/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@


# CalVer: YY.month.patch, e.g. first release of July 2022 == "22.7.1"
__version__ = "25.5.1"
__version__ = "25.5.2"


# taken from https://github.com/Zac-HD/shed
Expand Down
12 changes: 1 addition & 11 deletions flake8_async/visitors/visitor102_120.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,6 @@ def __init__(self, node: ast.Call, funcname: str):
self.funcname = funcname
self.variable_name: str | None = None
self.shielded: bool = False
self.has_timeout: bool = True

# scope.shielded is assigned to in visit_Assign

if self.funcname == "CancelScope":
self.has_timeout = False
for kw in node.keywords:
# note: sets to True even if timeout is explicitly set to inf
if kw.arg == "deadline":
self.has_timeout = True

# trio 0.27 adds shield parameter to all scope helpers
if self.funcname in cancel_scope_names:
Expand Down Expand Up @@ -79,7 +69,7 @@ def async_call_checker(
self, node: ast.Await | ast.AsyncFor | ast.AsyncWith
) -> None:
if self._critical_scope is not None and not any(
cm.has_timeout and cm.shielded for cm in self._trio_context_managers
cm.shielded for cm in self._trio_context_managers
):
# non-critical exception handlers have the statement name set to "except"
if self._critical_scope.name == "except":
Expand Down
3 changes: 2 additions & 1 deletion tests/eval_files/async102.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,9 @@ async def foo():
try:
pass
finally:
# it's now fine to have a shield and no timeout
with trio.CancelScope(shield=True):
await foo() # error: 12, Statement("try/finally", lineno-4)
await foo()
try:
pass
finally:
Expand Down
10 changes: 10 additions & 0 deletions tests/eval_files/async120.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,13 @@ async def foobar():
await foo()

raise


# shielded but no timeout no longer triggers async120
# https://github.com/python-trio/flake8-async/issues/272
async def foo_shield_no_timeout():
try:
...
finally:
with trio.CancelScope(shield=True):
await foo()