diff --git a/docs/changelog.rst b/docs/changelog.rst
index 95b0875..9f8cc5e 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -4,8 +4,9 @@ Changelog
`CalVer, YY.month.patch `_
-FUTURE
+25.5.2
======
+- :ref:`ASYNC102 ` and :ref:`ASYNC120 ` no longer requires cancel scopes to have a timeout. `(issue #272) `_
- Add :ref:`ASYNC400 ` except-star-invalid-attribute.
25.5.1
@@ -19,7 +20,7 @@ FUTURE
25.4.3
======
- :ref:`ASYNC100 ` can now autofix ``with`` statements with multiple items.
-- Fixed a bug where multiple ``with`` items would not interact, leading to ASYNC100 and ASYNC9xx false alarms. https://github.com/python-trio/flake8-async/issues/156
+- Fixed a bug where multiple ``with`` items would not interact, leading to ASYNC100 and ASYNC9xx false alarms. `(issue #367) `_
25.4.2
======
@@ -159,7 +160,7 @@ FUTURE
24.3.5
======
-- ASYNC102 (no await inside finally or critical except) no longer raises warnings for calls to ``aclose()`` on objects in trio/anyio code. See https://github.com/python-trio/flake8-async/issues/156
+- ASYNC102 (no await inside finally or critical except) no longer raises warnings for calls to ``aclose()`` on objects in trio/anyio code. See `(issue #156) `_
24.3.4
======
diff --git a/docs/usage.rst b/docs/usage.rst
index 407ffba..a3101c5 100644
--- a/docs/usage.rst
+++ b/docs/usage.rst
@@ -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"]
diff --git a/flake8_async/__init__.py b/flake8_async/__init__.py
index ff25126..15583f6 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__ = "25.5.1"
+__version__ = "25.5.2"
# taken from https://github.com/Zac-HD/shed
diff --git a/flake8_async/visitors/visitor102_120.py b/flake8_async/visitors/visitor102_120.py
index 97c665e..ac70b3a 100644
--- a/flake8_async/visitors/visitor102_120.py
+++ b/flake8_async/visitors/visitor102_120.py
@@ -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:
@@ -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":
diff --git a/tests/eval_files/async102.py b/tests/eval_files/async102.py
index a52333b..3d3f6d6 100644
--- a/tests/eval_files/async102.py
+++ b/tests/eval_files/async102.py
@@ -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:
diff --git a/tests/eval_files/async120.py b/tests/eval_files/async120.py
index f969f45..67039ec 100644
--- a/tests/eval_files/async120.py
+++ b/tests/eval_files/async120.py
@@ -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()