@@ -126,6 +126,14 @@ except that those prefixed by the ``async`` keyword use the ``__aenter__`` /
126126Only the ``with `` statement is modified; ``async with async ctx(): `` is a
127127syntax error.
128128
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+
129137
130138Backwards Compatibility
131139=======================
@@ -165,7 +173,7 @@ manager in an async context manager. For example:
165173 @contextmanager
166174 async def as_acm (sync_cm ):
167175 with sync_cm as result:
168- await sleep(0 ) # make async for structured-concurrency
176+ await sleep(0 )
169177 yield result
170178
171179 async with (
@@ -174,12 +182,14 @@ manager in an async context manager. For example:
174182 ):
175183 ...
176184
177- This is our recommended workaround for most code.
185+ This is our recommended workaround for almost all code.
178186
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.
183193
184194
185195Workaround: using ``AsyncExitStack ``
0 commit comments