3

The PEP 492 mentions that:

async with EXPR as VAR:
    BLOCK

is semantically equivalent to:

mgr = (EXPR)
aexit = type(mgr).__aexit__
aenter = type(mgr).__aenter__

VAR = await aenter(mgr)
try:
    BLOCK
except:
    if not await aexit(mgr, *sys.exc_info()):
        raise
else:
    await aexit(mgr, None, None, None)

However, VAR = await aenter(mgr) is not in the try block so I am wondering if __aenter__() is allowed to fail.

For example, in this this aiohttp snippet (taken from Getting Started):

import aiohttp
import asyncio

async def main():

    async with aiohttp.ClientSession() as session:
        async with session.get('http://python.org') as response:

            print("Status:", response.status)
            print("Content-type:", response.headers['content-type'])

            html = await response.text()
            print("Body:", html[:15], "...")

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

session.get('http://python.org') could fail and __aexit__() would not be called to close the context.

1
  • 1
    and __aexit__() would not be called to close the context. - what context are you referring to? The session will be closed because the exception happened in the body of the outer async with. If you mean response, there is nothing to close because session.get(...) never finished running, it raised an exception instead. Commented Jan 25, 2021 at 18:55

1 Answer 1

7

If __aenter__ fails, __aexit__ is indeed not run. Any required cleanup is __aenter__'s responsibility in this case.

__aenter__ has more information about how far it got and what did or did not get successfully initialized, so having __aenter__ handle this is more convenient than expecting __aexit__ to handle cleaning up arbitrary partially-entered context manager states.

(This is exactly the same for normal, non-async context managers.)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.