@@ -126,6 +126,14 @@ except that those prefixed by the ``async`` keyword use the ``__aenter__`` /
126
126
Only the ``with `` statement is modified; ``async with async ctx(): `` is a
127
127
syntax error.
128
128
129
+ The :class: `ast.withitem ` node gains a new ``is_async `` integer attribute,
130
+ following the existing ``is_async `` attribute on :class: `ast.comprehension `.
131
+ For ``async with `` statement items, this attribute is always ``1 ``. For items
132
+ in a regular ``with `` statement, the attribute is ``1 `` when the ``async ``
133
+ keyword is present and ``0 `` otherwise. This allows the AST to precisely
134
+ represent which context managers should use the async protocol while
135
+ maintaining backwards compatibility with existing AST processing tools.
136
+
129
137
130
138
Backwards Compatibility
131
139
=======================
@@ -165,7 +173,7 @@ manager in an async context manager. For example:
165
173
@contextmanager
166
174
async def as_acm (sync_cm ):
167
175
with sync_cm as result:
168
- await sleep(0 ) # make async for structured-concurrency
176
+ await sleep(0 )
169
177
yield result
170
178
171
179
async with (
@@ -174,12 +182,14 @@ manager in an async context manager. For example:
174
182
):
175
183
...
176
184
177
- This is our recommended workaround for most code.
185
+ This is our recommended workaround for almost all code.
178
186
179
- However, there are some cases where allowing the scheduler to cancel the task
180
- (with ``sleep(0) ``) is undesirable; conversely breaking the correspondence
181
- between a syntactic ``await `` / ``async for `` / ``async with `` risks deadlocks
182
- that cannot be detected by static-analysis tools such as ``flake8-async ``.
187
+ However, there are some cases where calling back into the async runtime (i.e.
188
+ executing ``await sleep(0) ``) to allow cancellation is undesirable. On the
189
+ other hand, *omitting * ``await sleep(0) `` would break the transitive property
190
+ that a syntactic ``await `` / ``async for `` / ``async with `` always calls back
191
+ into the async runtime (or raises an exception). While few codebases enforce
192
+ this property, we have found it indispensible in preventing deadlocks.
183
193
184
194
185
195
Workaround: using ``AsyncExitStack ``
0 commit comments