Skip to content

Commit b842265

Browse files
authored
Revert the changes to Visitor91x in "async100 now ignores trio.open_n… (#326)
* Revert the changes to Visitor91x in "async100 now ignores trio.open_nursery and anyio.create_task_group (#317)" This partially reverts commit 7a45176.
1 parent 565a81d commit b842265

12 files changed

+22
-66
lines changed

docs/changelog.rst

+6-3
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,19 @@ Changelog
44

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

7+
24.11.3
8+
=======
9+
- Revert :ref:`ASYNC100 <async100>` ignoring :func:`trio.open_nursery` and :func:`anyio.create_task_group` due to it not viewing `start_soon()` as introducing a :ref:`cancel point <cancel_point>`.
10+
711
24.11.2
812
=======
913
- Fix crash in ``Visitor91x`` on ``async with a().b():``.
1014

1115
24.11.1
1216
=======
1317
- :ref:`ASYNC100 <async100>` now ignores :func:`trio.open_nursery` and :func:`anyio.create_task_group`
14-
as cancellation sources, because they are :ref:`schedule points <schedule_points>` but not
15-
:ref:`cancellation points <cancel_points>`.
18+
as cancellation sources, because they are :ref:`schedule points <schedule_point>` but not
19+
:ref:`cancellation points <cancel_point>`.
1620
- :ref:`ASYNC101 <async101>` and :ref:`ASYNC119 <async119>` are now silenced for decorators in :ref:`transform-async-generator-decorators`.
1721

1822
24.10.2
@@ -34,7 +38,6 @@ Changelog
3438
24.9.3
3539
======
3640
- :ref:`ASYNC102 <async102>` and :ref:`ASYNC120 <async120>`:
37-
3841
- handles nested cancel scopes
3942
- detects internal cancel scopes of nurseries as a way to shield&deadline
4043
- no longer treats :func:`trio.open_nursery` or :func:`anyio.create_task_group` as cancellation sources

docs/glossary.rst

+1-3
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ functions defined by Trio will either checkpoint or raise an exception when
9999
iteration, and when exhausting the iterator, and ``async with`` will checkpoint
100100
on at least one of enter/exit.
101101

102-
The one exception is :func:`trio.open_nursery` and :func:`anyio.create_task_group` which are :ref:`schedule_points` but not :ref:`cancel_points`.
102+
The one exception is :func:`trio.open_nursery` and :func:`anyio.create_task_group` which are :ref:`schedule points <schedule_point>` but not :ref:`cancel points <cancel_point>`.
103103

104104
asyncio does not place any guarantees on if or when asyncio functions will
105105
checkpoint. This means that enabling and adhering to :ref:`ASYNC91x <ASYNC910>`
@@ -117,7 +117,6 @@ To insert a checkpoint with no other side effects, you can use
117117
<asyncio.sleep>`
118118

119119
.. _schedule_point:
120-
.. _schedule_points:
121120

122121
Schedule Point
123122
--------------
@@ -137,7 +136,6 @@ asyncio does not have any direct equivalents due to their cancellation model bei
137136

138137

139138
.. _cancel_point:
140-
.. _cancel_points:
141139

142140
Cancel Point
143141
------------

docs/rules.rst

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ _`ASYNC100` : cancel-scope-no-checkpoint
1313
A :ref:`timeout_context` does not contain any :ref:`checkpoints <checkpoint>`.
1414
This makes it pointless, as the timeout can only be triggered by a checkpoint.
1515
This check also treats ``yield`` as a checkpoint, since checkpoints can happen in the caller we yield to.
16-
:func:`trio.open_nursery` and :func:`anyio.create_task_group` are excluded, as they are :ref:`schedule_points` but not :ref:`cancel_points`.
1716
See :ref:`ASYNC912 <async912>` which will in addition guarantee checkpoints on every code path.
1817

1918
_`ASYNC101` : yield-in-cancel-scope

flake8_async/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939

4040
# CalVer: YY.month.patch, e.g. first release of July 2022 == "22.7.1"
41-
__version__ = "24.11.2"
41+
__version__ = "24.11.3"
4242

4343

4444
# taken from https://github.com/Zac-HD/shed

flake8_async/visitors/visitor91x.py

+4-25
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
flatten_preserving_comments,
2626
fnmatch_qualified_name_cst,
2727
func_has_decorator,
28-
identifier_to_string,
2928
iter_guaranteed_once_cst,
3029
with_has_call,
3130
)
@@ -492,33 +491,12 @@ def _is_exception_suppressing_context_manager(self, node: cst.With) -> bool:
492491
is not None
493492
)
494493

495-
def _checkpoint_with(self, node: cst.With):
496-
"""Conditionally checkpoints entry/exit of With.
497-
498-
If the with only contains calls to open_nursery/create_task_group, it's a schedule
499-
point but not a cancellation point, so we treat it as a checkpoint for async91x
500-
but not for async100.
501-
"""
502-
if getattr(node, "asynchronous", None):
503-
for item in node.items:
504-
if not (
505-
isinstance(item.item, cst.Call)
506-
and identifier_to_string(item.item.func)
507-
in (
508-
"trio.open_nursery",
509-
"anyio.create_task_group",
510-
)
511-
):
512-
self.checkpoint()
513-
break
514-
else:
515-
self.uncheckpointed_statements = set()
516-
517494
# Async context managers can reasonably checkpoint on either or both of entry and
518495
# exit. Given that we can't tell which, we assume "both" to avoid raising a
519496
# missing-checkpoint warning when there might in fact be one (i.e. a false alarm).
520497
def visit_With_body(self, node: cst.With):
521-
self._checkpoint_with(node)
498+
if getattr(node, "asynchronous", None):
499+
self.checkpoint()
522500

523501
# if this might suppress exceptions, we cannot treat anything inside it as
524502
# checkpointing.
@@ -577,7 +555,8 @@ def leave_With(self, original_node: cst.With, updated_node: cst.With):
577555
self.restore_state(original_node)
578556
self.uncheckpointed_statements.update(prev_checkpoints)
579557

580-
self._checkpoint_with(original_node)
558+
if getattr(original_node, "asynchronous", None):
559+
self.checkpoint()
581560
return updated_node
582561

583562
# error if no checkpoint since earlier yield or function entry

tests/autofix_files/async100.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ async def fn(timeout):
133133

134134

135135
async def nursery_no_cancel_point():
136-
# error: 9, "trio", "CancelScope"
137-
async with anyio.create_task_group():
138-
...
136+
with trio.CancelScope(): # should error, but reverted PR
137+
async with anyio.create_task_group():
138+
...
139139

140140

141141
async def dont_crash_on_non_name_or_attr_call():

tests/autofix_files/async100.py.diff

-13
Original file line numberDiff line numberDiff line change
@@ -130,16 +130,3 @@
130130

131131
with contextlib.suppress(Exception):
132132
with open("blah") as file:
133-
@@ x,9 x,9 @@
134-
135-
136-
async def nursery_no_cancel_point():
137-
- with trio.CancelScope(): # error: 9, "trio", "CancelScope"
138-
- async with anyio.create_task_group():
139-
- ...
140-
+ # error: 9, "trio", "CancelScope"
141-
+ async with anyio.create_task_group():
142-
+ ...
143-
144-
145-
async def dont_crash_on_non_name_or_attr_call():

tests/autofix_files/async100_trio.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55

66

77
async def nursery_no_cancel_point():
8-
# error: 9, "trio", "CancelScope"
9-
async with trio.open_nursery():
10-
...
8+
with trio.CancelScope(): # should error, but reverted PR
9+
async with trio.open_nursery():
10+
...
-12
Original file line numberDiff line numberDiff line change
@@ -1,12 +0,0 @@
1-
---
2-
+++
3-
@@ x,6 x,6 @@
4-
5-
6-
async def nursery_no_cancel_point():
7-
- with trio.CancelScope(): # error: 9, "trio", "CancelScope"
8-
- async with trio.open_nursery():
9-
- ...
10-
+ # error: 9, "trio", "CancelScope"
11-
+ async with trio.open_nursery():
12-
+ ...

tests/eval_files/async100.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ async def fn(timeout):
133133

134134

135135
async def nursery_no_cancel_point():
136-
with trio.CancelScope(): # error: 9, "trio", "CancelScope"
136+
with trio.CancelScope(): # should error, but reverted PR
137137
async with anyio.create_task_group():
138138
...
139139

tests/eval_files/async100_trio.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55

66

77
async def nursery_no_cancel_point():
8-
with trio.CancelScope(): # error: 9, "trio", "CancelScope"
8+
with trio.CancelScope(): # should error, but reverted PR
99
async with trio.open_nursery():
1010
...

tests/test_flake8_async.py

+2
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ def format_difflib_line(s: str) -> str:
8383

8484

8585
def diff_strings(first: str, second: str, /) -> str:
86+
if first == second:
87+
return ""
8688
return (
8789
"".join(
8890
map(

0 commit comments

Comments
 (0)