Unravelling the `async with` statement

I already covered unravelling the with statement, and async with is not much different. Much like with, the language reference for async with gives an example of the statement already destructured. Based on that and the fact that async with is just with with asynchronous versions of __enter__ and __exit__ (__aenter__ and __aexit__, respectively), I'm just going to jump straight to the unravelled version and keep this post short.

async with a as b:
    c
Example use of async with

becomes:

_enter = type(a).__aenter__
_exit = type(a).__aexit__
b = await _enter(a)

try:
    c
except:
    if not await _exit(a, *sys.exc_info()):
        raise
else:
    await _exit(a, None, None, None)
Example aync with unravelled

It's with unravelled but changed by:

  1. __enter__ to __aenter__.
  2. __exit__ to __aexit__.
  3. All calls to those methods being preceded with await.